@sinm/kai 1.10.7 → 1.10.9

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 (129) hide show
  1. package/dist-cli/kai-cli.js +1221 -529
  2. package/dist-electron/renderer/assets/{_baseUniq--zw5vxJ8.js → _baseUniq-BwtMDG1-.js} +1 -1
  3. package/dist-electron/renderer/assets/_baseUniq-BwtMDG1-.js.gz +0 -0
  4. package/dist-electron/renderer/assets/{arc-B-ZTE5px.js → arc-D5Y8sObu.js} +1 -1
  5. package/dist-electron/renderer/assets/arc-D5Y8sObu.js.gz +0 -0
  6. package/dist-electron/renderer/assets/{architectureDiagram-Q4EWVU46-CsjJkYpt.js → architectureDiagram-Q4EWVU46-Dk0KuAk6.js} +5 -5
  7. package/dist-electron/renderer/assets/architectureDiagram-Q4EWVU46-Dk0KuAk6.js.gz +0 -0
  8. package/dist-electron/renderer/assets/{blockDiagram-DXYQGD6D-C4KXhIaX.js → blockDiagram-DXYQGD6D-RROzjSS4.js} +6 -6
  9. package/dist-electron/renderer/assets/blockDiagram-DXYQGD6D-RROzjSS4.js.gz +0 -0
  10. package/dist-electron/renderer/assets/{c4Diagram-AHTNJAMY-B4vdoFNw.js → c4Diagram-AHTNJAMY-COr4yxZO.js} +2 -2
  11. package/dist-electron/renderer/assets/c4Diagram-AHTNJAMY-COr4yxZO.js.gz +0 -0
  12. package/dist-electron/renderer/assets/{channel-CojzKabn.js → channel-D7c0puHw.js} +1 -1
  13. package/dist-electron/renderer/assets/{chunk-4BX2VUAB-CCDurM9j.js → chunk-4BX2VUAB-zon6ESDT.js} +1 -1
  14. package/dist-electron/renderer/assets/{chunk-4TB4RGXK-D70CTFFr.js → chunk-4TB4RGXK-t5PuOocg.js} +5 -5
  15. package/dist-electron/renderer/assets/chunk-4TB4RGXK-t5PuOocg.js.gz +0 -0
  16. package/dist-electron/renderer/assets/{chunk-55IACEB6-B0va-3Kz.js → chunk-55IACEB6-BKk3Kjuh.js} +1 -1
  17. package/dist-electron/renderer/assets/{chunk-EDXVE4YY-1YMWXLsT.js → chunk-EDXVE4YY-D07Bk7Ts.js} +1 -1
  18. package/dist-electron/renderer/assets/chunk-EDXVE4YY-D07Bk7Ts.js.gz +0 -0
  19. package/dist-electron/renderer/assets/{chunk-FMBD7UC4-C93n6mrE.js → chunk-FMBD7UC4-ridqi0-s.js} +1 -1
  20. package/dist-electron/renderer/assets/{chunk-OYMX7WX6-B4Lz8_M8.js → chunk-OYMX7WX6-BJStQEVA.js} +3 -3
  21. package/dist-electron/renderer/assets/chunk-OYMX7WX6-BJStQEVA.js.gz +0 -0
  22. package/dist-electron/renderer/assets/{chunk-QZHKN3VN-Bln2eCdd.js → chunk-QZHKN3VN-4ZDs5jRy.js} +1 -1
  23. package/dist-electron/renderer/assets/{chunk-YZCP3GAM-DLyJ3i6-.js → chunk-YZCP3GAM-WMu5UJ_J.js} +1 -1
  24. package/dist-electron/renderer/assets/chunk-YZCP3GAM-WMu5UJ_J.js.gz +0 -0
  25. package/dist-electron/renderer/assets/{classDiagram-6PBFFD2Q-BCpu5WpC.js → classDiagram-6PBFFD2Q-WQ6mAQ8p.js} +6 -6
  26. package/dist-electron/renderer/assets/{classDiagram-v2-HSJHXN6E-BCpu5WpC.js → classDiagram-v2-HSJHXN6E-WQ6mAQ8p.js} +6 -6
  27. package/dist-electron/renderer/assets/{clone-DHbm8xhR.js → clone-wHUtBPLK.js} +1 -1
  28. package/dist-electron/renderer/assets/{cose-bilkent-S5V4N54A-j4mwYnJK.js → cose-bilkent-S5V4N54A-C7-3WlAT.js} +1 -1
  29. package/dist-electron/renderer/assets/cose-bilkent-S5V4N54A-C7-3WlAT.js.gz +0 -0
  30. package/dist-electron/renderer/assets/{dagre-KV5264BT-Cs4c7zmN.js → dagre-KV5264BT-CgU6PfJs.js} +6 -6
  31. package/dist-electron/renderer/assets/dagre-KV5264BT-CgU6PfJs.js.gz +0 -0
  32. package/dist-electron/renderer/assets/{diagram-5BDNPKRD-DH3zvht0.js → diagram-5BDNPKRD-NYjY1WSI.js} +6 -6
  33. package/dist-electron/renderer/assets/diagram-5BDNPKRD-NYjY1WSI.js.gz +0 -0
  34. package/dist-electron/renderer/assets/{diagram-G4DWMVQ6-CGDXBGv7.js → diagram-G4DWMVQ6-BWToylUw.js} +6 -6
  35. package/dist-electron/renderer/assets/diagram-G4DWMVQ6-BWToylUw.js.gz +0 -0
  36. package/dist-electron/renderer/assets/{diagram-MMDJMWI5-C8Ns1x5S.js → diagram-MMDJMWI5-CYOS--AG.js} +5 -5
  37. package/dist-electron/renderer/assets/diagram-MMDJMWI5-CYOS--AG.js.gz +0 -0
  38. package/dist-electron/renderer/assets/{diagram-TYMM5635-Hr47desu.js → diagram-TYMM5635-DbR10Nbc.js} +5 -5
  39. package/dist-electron/renderer/assets/diagram-TYMM5635-DbR10Nbc.js.gz +0 -0
  40. package/dist-electron/renderer/assets/{erDiagram-SMLLAGMA-CxhPNMff.js → erDiagram-SMLLAGMA-0fqlEFM9.js} +4 -4
  41. package/dist-electron/renderer/assets/erDiagram-SMLLAGMA-0fqlEFM9.js.gz +0 -0
  42. package/dist-electron/renderer/assets/{flowDiagram-DWJPFMVM-BER6WVZg.js → flowDiagram-DWJPFMVM-DbCFy4Q1.js} +6 -6
  43. package/dist-electron/renderer/assets/flowDiagram-DWJPFMVM-DbCFy4Q1.js.gz +0 -0
  44. package/dist-electron/renderer/assets/{ganttDiagram-T4ZO3ILL-DiKH9xVX.js → ganttDiagram-T4ZO3ILL-99E_sjoR.js} +1 -1
  45. package/dist-electron/renderer/assets/ganttDiagram-T4ZO3ILL-99E_sjoR.js.gz +0 -0
  46. package/dist-electron/renderer/assets/{gitGraphDiagram-UUTBAWPF--hHnNRwU.js → gitGraphDiagram-UUTBAWPF-BYQMGCe1.js} +6 -6
  47. package/dist-electron/renderer/assets/gitGraphDiagram-UUTBAWPF-BYQMGCe1.js.gz +0 -0
  48. package/dist-electron/renderer/assets/{graph-CG-i4KXk.js → graph-I1gBTVcf.js} +2 -2
  49. package/dist-electron/renderer/assets/graph-I1gBTVcf.js.gz +0 -0
  50. package/dist-electron/renderer/assets/{index-HszXKoTI.js → index-Bq9gK3yW.js} +488 -424
  51. package/dist-electron/renderer/assets/index-Bq9gK3yW.js.gz +0 -0
  52. package/dist-electron/renderer/assets/{index-DGMKs4_S.css → index-DwIqVvJQ.css} +249 -232
  53. package/dist-electron/renderer/assets/index-DwIqVvJQ.css.gz +0 -0
  54. package/dist-electron/renderer/assets/{infoDiagram-42DDH7IO-Glh-kNi7.js → infoDiagram-42DDH7IO-KLNN6MTr.js} +4 -4
  55. package/dist-electron/renderer/assets/{ishikawaDiagram-UXIWVN3A-GATvn0p-.js → ishikawaDiagram-UXIWVN3A-CIpUwlD6.js} +1 -1
  56. package/dist-electron/renderer/assets/ishikawaDiagram-UXIWVN3A-CIpUwlD6.js.gz +0 -0
  57. package/dist-electron/renderer/assets/{journeyDiagram-VCZTEJTY-Dh3hGd03.js → journeyDiagram-VCZTEJTY-Cf5eOwIT.js} +4 -4
  58. package/dist-electron/renderer/assets/journeyDiagram-VCZTEJTY-Cf5eOwIT.js.gz +0 -0
  59. package/dist-electron/renderer/assets/{kanban-definition-6JOO6SKY-B4CKbVuY.js → kanban-definition-6JOO6SKY-D-AiOtub.js} +2 -2
  60. package/dist-electron/renderer/assets/kanban-definition-6JOO6SKY-D-AiOtub.js.gz +0 -0
  61. package/dist-electron/renderer/assets/{layout-ByVBxABe.js → layout-oRQlDrmR.js} +4 -4
  62. package/dist-electron/renderer/assets/layout-oRQlDrmR.js.gz +0 -0
  63. package/dist-electron/renderer/assets/{min-wqhv2XVH.js → min-CJbOmPi5.js} +2 -2
  64. package/dist-electron/renderer/assets/min-CJbOmPi5.js.gz +0 -0
  65. package/dist-electron/renderer/assets/{mindmap-definition-QFDTVHPH-D4mNlXr2.js → mindmap-definition-QFDTVHPH-DKKEXzR5.js} +3 -3
  66. package/dist-electron/renderer/assets/mindmap-definition-QFDTVHPH-DKKEXzR5.js.gz +0 -0
  67. package/dist-electron/renderer/assets/{pieDiagram-DEJITSTG-7WTMb8Jf.js → pieDiagram-DEJITSTG-BE5F3KPb.js} +6 -6
  68. package/dist-electron/renderer/assets/pieDiagram-DEJITSTG-BE5F3KPb.js.gz +0 -0
  69. package/dist-electron/renderer/assets/{quadrantDiagram-34T5L4WZ-8hdoptuE.js → quadrantDiagram-34T5L4WZ-D0gMai7D.js} +1 -1
  70. package/dist-electron/renderer/assets/{quadrantDiagram-34T5L4WZ-8hdoptuE.js.gz → quadrantDiagram-34T5L4WZ-D0gMai7D.js.gz} +0 -0
  71. package/dist-electron/renderer/assets/{requirementDiagram-MS252O5E-B_xMPn-V.js → requirementDiagram-MS252O5E-C3xERMVY.js} +3 -3
  72. package/dist-electron/renderer/assets/requirementDiagram-MS252O5E-C3xERMVY.js.gz +0 -0
  73. package/dist-electron/renderer/assets/{sankeyDiagram-XADWPNL6-DzNk6tS4.js → sankeyDiagram-XADWPNL6-DWRyCRF7.js} +1 -1
  74. package/dist-electron/renderer/assets/sankeyDiagram-XADWPNL6-DWRyCRF7.js.gz +0 -0
  75. package/dist-electron/renderer/assets/{sequenceDiagram-FGHM5R23-C42xau12.js → sequenceDiagram-FGHM5R23-CXOjG4Pk.js} +3 -3
  76. package/dist-electron/renderer/assets/sequenceDiagram-FGHM5R23-CXOjG4Pk.js.gz +0 -0
  77. package/dist-electron/renderer/assets/{stateDiagram-FHFEXIEX-DKyS2aaF.js → stateDiagram-FHFEXIEX-BFGMsjAA.js} +8 -8
  78. package/dist-electron/renderer/assets/stateDiagram-FHFEXIEX-BFGMsjAA.js.gz +0 -0
  79. package/dist-electron/renderer/assets/{stateDiagram-v2-QKLJ7IA2-D1ccqVYN.js → stateDiagram-v2-QKLJ7IA2-TQ4k_Ake.js} +4 -4
  80. package/dist-electron/renderer/assets/{timeline-definition-GMOUNBTQ-BHW2iOvC.js → timeline-definition-GMOUNBTQ-we4olq0q.js} +2 -2
  81. package/dist-electron/renderer/assets/timeline-definition-GMOUNBTQ-we4olq0q.js.gz +0 -0
  82. package/dist-electron/renderer/assets/{vennDiagram-DHZGUBPP-C_Wft8GY.js → vennDiagram-DHZGUBPP-ByyCWjrf.js} +1 -1
  83. package/dist-electron/renderer/assets/vennDiagram-DHZGUBPP-ByyCWjrf.js.gz +0 -0
  84. package/dist-electron/renderer/assets/{wardley-RL74JXVD-G7z3b9xY.js → wardley-RL74JXVD-DjV5krT-.js} +3 -3
  85. package/dist-electron/renderer/assets/wardley-RL74JXVD-DjV5krT-.js.gz +0 -0
  86. package/dist-electron/renderer/assets/{wardleyDiagram-NUSXRM2D-DpOEFojT.js → wardleyDiagram-NUSXRM2D-CnkU2yG8.js} +5 -5
  87. package/dist-electron/renderer/assets/wardleyDiagram-NUSXRM2D-CnkU2yG8.js.gz +0 -0
  88. package/dist-electron/renderer/assets/{xychartDiagram-5P7HB3ND-CPfWWH77.js → xychartDiagram-5P7HB3ND-CcyVXC1b.js} +1 -1
  89. package/dist-electron/renderer/assets/xychartDiagram-5P7HB3ND-CcyVXC1b.js.gz +0 -0
  90. package/dist-electron/renderer/index.html +2 -2
  91. package/package.json +2 -2
  92. package/dist-electron/renderer/assets/_baseUniq--zw5vxJ8.js.gz +0 -0
  93. package/dist-electron/renderer/assets/arc-B-ZTE5px.js.gz +0 -0
  94. package/dist-electron/renderer/assets/architectureDiagram-Q4EWVU46-CsjJkYpt.js.gz +0 -0
  95. package/dist-electron/renderer/assets/blockDiagram-DXYQGD6D-C4KXhIaX.js.gz +0 -0
  96. package/dist-electron/renderer/assets/c4Diagram-AHTNJAMY-B4vdoFNw.js.gz +0 -0
  97. package/dist-electron/renderer/assets/chunk-4TB4RGXK-D70CTFFr.js.gz +0 -0
  98. package/dist-electron/renderer/assets/chunk-EDXVE4YY-1YMWXLsT.js.gz +0 -0
  99. package/dist-electron/renderer/assets/chunk-OYMX7WX6-B4Lz8_M8.js.gz +0 -0
  100. package/dist-electron/renderer/assets/chunk-YZCP3GAM-DLyJ3i6-.js.gz +0 -0
  101. package/dist-electron/renderer/assets/cose-bilkent-S5V4N54A-j4mwYnJK.js.gz +0 -0
  102. package/dist-electron/renderer/assets/dagre-KV5264BT-Cs4c7zmN.js.gz +0 -0
  103. package/dist-electron/renderer/assets/diagram-5BDNPKRD-DH3zvht0.js.gz +0 -0
  104. package/dist-electron/renderer/assets/diagram-G4DWMVQ6-CGDXBGv7.js.gz +0 -0
  105. package/dist-electron/renderer/assets/diagram-MMDJMWI5-C8Ns1x5S.js.gz +0 -0
  106. package/dist-electron/renderer/assets/diagram-TYMM5635-Hr47desu.js.gz +0 -0
  107. package/dist-electron/renderer/assets/erDiagram-SMLLAGMA-CxhPNMff.js.gz +0 -0
  108. package/dist-electron/renderer/assets/flowDiagram-DWJPFMVM-BER6WVZg.js.gz +0 -0
  109. package/dist-electron/renderer/assets/ganttDiagram-T4ZO3ILL-DiKH9xVX.js.gz +0 -0
  110. package/dist-electron/renderer/assets/gitGraphDiagram-UUTBAWPF--hHnNRwU.js.gz +0 -0
  111. package/dist-electron/renderer/assets/graph-CG-i4KXk.js.gz +0 -0
  112. package/dist-electron/renderer/assets/index-DGMKs4_S.css.gz +0 -0
  113. package/dist-electron/renderer/assets/index-HszXKoTI.js.gz +0 -0
  114. package/dist-electron/renderer/assets/ishikawaDiagram-UXIWVN3A-GATvn0p-.js.gz +0 -0
  115. package/dist-electron/renderer/assets/journeyDiagram-VCZTEJTY-Dh3hGd03.js.gz +0 -0
  116. package/dist-electron/renderer/assets/kanban-definition-6JOO6SKY-B4CKbVuY.js.gz +0 -0
  117. package/dist-electron/renderer/assets/layout-ByVBxABe.js.gz +0 -0
  118. package/dist-electron/renderer/assets/min-wqhv2XVH.js.gz +0 -0
  119. package/dist-electron/renderer/assets/mindmap-definition-QFDTVHPH-D4mNlXr2.js.gz +0 -0
  120. package/dist-electron/renderer/assets/pieDiagram-DEJITSTG-7WTMb8Jf.js.gz +0 -0
  121. package/dist-electron/renderer/assets/requirementDiagram-MS252O5E-B_xMPn-V.js.gz +0 -0
  122. package/dist-electron/renderer/assets/sankeyDiagram-XADWPNL6-DzNk6tS4.js.gz +0 -0
  123. package/dist-electron/renderer/assets/sequenceDiagram-FGHM5R23-C42xau12.js.gz +0 -0
  124. package/dist-electron/renderer/assets/stateDiagram-FHFEXIEX-DKyS2aaF.js.gz +0 -0
  125. package/dist-electron/renderer/assets/timeline-definition-GMOUNBTQ-BHW2iOvC.js.gz +0 -0
  126. package/dist-electron/renderer/assets/vennDiagram-DHZGUBPP-C_Wft8GY.js.gz +0 -0
  127. package/dist-electron/renderer/assets/wardley-RL74JXVD-G7z3b9xY.js.gz +0 -0
  128. package/dist-electron/renderer/assets/wardleyDiagram-NUSXRM2D-DpOEFojT.js.gz +0 -0
  129. package/dist-electron/renderer/assets/xychartDiagram-5P7HB3ND-CPfWWH77.js.gz +0 -0
@@ -4716,7 +4716,7 @@ var require_lodash = __commonJS({
4716
4716
  function valuesIn(object4) {
4717
4717
  return object4 == null ? [] : baseValues(object4, keysIn(object4));
4718
4718
  }
4719
- function clamp(number4, lower, upper) {
4719
+ function clamp2(number4, lower, upper) {
4720
4720
  if (upper === undefined2) {
4721
4721
  upper = lower;
4722
4722
  lower = undefined2;
@@ -5398,7 +5398,7 @@ var require_lodash = __commonJS({
5398
5398
  lodash.camelCase = camelCase2;
5399
5399
  lodash.capitalize = capitalize;
5400
5400
  lodash.ceil = ceil;
5401
- lodash.clamp = clamp;
5401
+ lodash.clamp = clamp2;
5402
5402
  lodash.clone = clone3;
5403
5403
  lodash.cloneDeep = cloneDeep2;
5404
5404
  lodash.cloneDeepWith = cloneDeepWith;
@@ -31653,13 +31653,13 @@ var require_core = __commonJS({
31653
31653
  }, warn() {
31654
31654
  }, error() {
31655
31655
  } };
31656
- function getLogger(logger51) {
31657
- if (logger51 === false)
31656
+ function getLogger(logger53) {
31657
+ if (logger53 === false)
31658
31658
  return noLogs;
31659
- if (logger51 === void 0)
31659
+ if (logger53 === void 0)
31660
31660
  return console;
31661
- if (logger51.log && logger51.warn && logger51.error)
31662
- return logger51;
31661
+ if (logger53.log && logger53.warn && logger53.error)
31662
+ return logger53;
31663
31663
  throw new Error("logger must implement log, warn and error methods");
31664
31664
  }
31665
31665
  var KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i;
@@ -40347,7 +40347,7 @@ var init_logging = __esm({
40347
40347
  // src/shared/utils/logger.ts
40348
40348
  function createLogger(prefix) {
40349
40349
  const scope = legacyScope(prefix);
40350
- const logger51 = createStructuredLogger({
40350
+ const logger53 = createStructuredLogger({
40351
40351
  scope,
40352
40352
  sinks,
40353
40353
  minLevel: currentLevel <= LOG_LEVELS.noise ? "debug" : "info"
@@ -40355,37 +40355,37 @@ function createLogger(prefix) {
40355
40355
  return {
40356
40356
  noise: (...args2) => {
40357
40357
  if (currentLevel <= LOG_LEVELS.noise) {
40358
- writeLegacy(logger51, "debug", "legacy.noise", args2);
40358
+ writeLegacy(logger53, "debug", "legacy.noise", args2);
40359
40359
  }
40360
40360
  },
40361
40361
  debug: (...args2) => {
40362
40362
  if (currentLevel <= LOG_LEVELS.debug) {
40363
- writeLegacy(logger51, "debug", "legacy.debug", args2);
40363
+ writeLegacy(logger53, "debug", "legacy.debug", args2);
40364
40364
  }
40365
40365
  },
40366
40366
  info: (...args2) => {
40367
- writeLegacy(logger51, "info", "legacy.info", args2);
40367
+ writeLegacy(logger53, "info", "legacy.info", args2);
40368
40368
  },
40369
40369
  warn: (...args2) => {
40370
- writeLegacy(logger51, "warn", "legacy.warn", args2);
40370
+ writeLegacy(logger53, "warn", "legacy.warn", args2);
40371
40371
  },
40372
40372
  error: (...args2) => {
40373
- writeLegacy(logger51, "error", "legacy.error", args2);
40373
+ writeLegacy(logger53, "error", "legacy.error", args2);
40374
40374
  }
40375
40375
  };
40376
40376
  }
40377
- function writeLegacy(logger51, level, event, args2) {
40377
+ function writeLegacy(logger53, level, event, args2) {
40378
40378
  const { message, data: data2, error: error48 } = normalizeLegacyArgs(args2);
40379
40379
  const payload = {
40380
40380
  ...message ? { message } : {},
40381
40381
  ...data2.length > 0 ? { args: data2 } : {},
40382
40382
  ...error48 ? { error: error48 } : {}
40383
40383
  };
40384
- if (level === "debug") logger51.debug(event, payload);
40385
- else if (level === "info") logger51.info(event, payload);
40386
- else if (level === "warn") logger51.warn(event, payload);
40387
- else if (level === "error") logger51.error(event, payload);
40388
- else logger51.fatal(event, payload);
40384
+ if (level === "debug") logger53.debug(event, payload);
40385
+ else if (level === "info") logger53.info(event, payload);
40386
+ else if (level === "warn") logger53.warn(event, payload);
40387
+ else if (level === "error") logger53.error(event, payload);
40388
+ else logger53.fatal(event, payload);
40389
40389
  }
40390
40390
  function normalizeLegacyArgs(args2) {
40391
40391
  const [first2, ...rest] = args2;
@@ -56843,7 +56843,7 @@ var require_logger = __commonJS({
56843
56843
  };
56844
56844
  __export3(exports2, {
56845
56845
  Logger: () => Logger,
56846
- logger: () => logger51
56846
+ logger: () => logger53
56847
56847
  });
56848
56848
  var import_debug = __toModule(require_src());
56849
56849
  var import_util8 = __toModule(require("util"));
@@ -56868,7 +56868,7 @@ var require_logger = __commonJS({
56868
56868
  return (0, import_debug.default)(`${this.config.context}:${name21}`);
56869
56869
  }
56870
56870
  };
56871
- var logger51 = new Logger();
56871
+ var logger53 = new Logger();
56872
56872
  }
56873
56873
  });
56874
56874
 
@@ -58920,7 +58920,7 @@ var require_data_types9 = __commonJS({
58920
58920
  var Validator2 = require_validator_extras().validator;
58921
58921
  var momentTz = require_moment_timezone2();
58922
58922
  var moment = require_moment();
58923
- var { logger: logger51 } = require_logger();
58923
+ var { logger: logger53 } = require_logger();
58924
58924
  var warnings = {};
58925
58925
  var { classToInvokable } = require_class_to_invokable();
58926
58926
  var { joinSQLFragments } = require_join_sql_fragments();
@@ -58949,7 +58949,7 @@ var require_data_types9 = __commonJS({
58949
58949
  static warn(link, text7) {
58950
58950
  if (!warnings[text7]) {
58951
58951
  warnings[text7] = true;
58952
- logger51.warn(`${text7}
58952
+ logger53.warn(`${text7}
58953
58953
  >> Check: ${link}`);
58954
58954
  }
58955
58955
  }
@@ -59589,7 +59589,7 @@ var require_sql_string = __commonJS({
59589
59589
  "use strict";
59590
59590
  var moment = require_moment();
59591
59591
  var dataTypes = require_data_types9();
59592
- var { logger: logger51 } = require_logger();
59592
+ var { logger: logger53 } = require_logger();
59593
59593
  function arrayToList(array3, timeZone, dialect, format2) {
59594
59594
  return array3.reduce((sql, val2, i) => {
59595
59595
  if (i !== 0) {
@@ -59639,7 +59639,7 @@ var require_sql_string = __commonJS({
59639
59639
  return arrayToList(val2, timeZone, dialect, format2);
59640
59640
  }
59641
59641
  if (!val2.replace) {
59642
- throw new Error(`Invalid value ${logger51.inspect(val2)}`);
59642
+ throw new Error(`Invalid value ${logger53.inspect(val2)}`);
59643
59643
  }
59644
59644
  if (["postgres", "sqlite", "mssql", "snowflake", "db2"].includes(dialect)) {
59645
59645
  val2 = val2.replace(/'/g, "''");
@@ -63487,8 +63487,8 @@ var require_hooks = __commonJS({
63487
63487
  "node_modules/sequelize/lib/hooks.js"(exports2) {
63488
63488
  "use strict";
63489
63489
  var _5 = require_lodash();
63490
- var { logger: logger51 } = require_logger();
63491
- var debug = logger51.debugContext("hooks");
63490
+ var { logger: logger53 } = require_logger();
63491
+ var debug = logger53.debugContext("hooks");
63492
63492
  var hookTypes = {
63493
63493
  beforeValidate: { params: 2 },
63494
63494
  afterValidate: { params: 2 },
@@ -63798,7 +63798,7 @@ var require_model = __commonJS({
63798
63798
  var _5 = require_lodash();
63799
63799
  var Dottie = require_dottie();
63800
63800
  var Utils2 = require_utils2();
63801
- var { logger: logger51 } = require_logger();
63801
+ var { logger: logger53 } = require_logger();
63802
63802
  var BelongsTo2 = require_belongs_to();
63803
63803
  var BelongsToMany2 = require_belongs_to_many();
63804
63804
  var InstanceValidator = require_instance_validator();
@@ -63862,7 +63862,7 @@ var require_model = __commonJS({
63862
63862
  }
63863
63863
  }
63864
63864
  if (overwrittenAttributes.length > 0) {
63865
- logger51.warn(`Model ${JSON.stringify(this.constructor.name)} is declaring public class fields for attribute(s): ${overwrittenAttributes.map((attr2) => JSON.stringify(attr2)).join(", ")}.
63865
+ logger53.warn(`Model ${JSON.stringify(this.constructor.name)} is declaring public class fields for attribute(s): ${overwrittenAttributes.map((attr2) => JSON.stringify(attr2)).join(", ")}.
63866
63866
  These class fields are shadowing Sequelize's attribute getters & setters.
63867
63867
  See https://sequelize.org/main/manual/model-basics.html#caveat-with-public-class-fields`);
63868
63868
  }
@@ -64935,7 +64935,7 @@ See https://sequelize.org/main/manual/model-basics.html#caveat-with-public-class
64935
64935
  const unrecognizedOptions = Object.keys(options2).filter((k2) => !validQueryKeywords.has(k2));
64936
64936
  const unexpectedModelAttributes = _5.intersection(unrecognizedOptions, validColumnNames);
64937
64937
  if (!options2.where && unexpectedModelAttributes.length > 0) {
64938
- logger51.warn(`Model attributes (${unexpectedModelAttributes.join(", ")}) passed into finder method options of model ${this.name}, but the options.where object is empty. Did you forget to use options.where?`);
64938
+ logger53.warn(`Model attributes (${unexpectedModelAttributes.join(", ")}) passed into finder method options of model ${this.name}, but the options.where object is empty. Did you forget to use options.where?`);
64939
64939
  }
64940
64940
  }
64941
64941
  static _injectDependentVirtualAttributes(attributes2) {
@@ -65168,7 +65168,7 @@ See https://sequelize.org/main/manual/model-basics.html#caveat-with-public-class
65168
65168
  const defaults3 = Object.keys(options2.defaults);
65169
65169
  const unknownDefaults = defaults3.filter((name21) => !this.rawAttributes[name21]);
65170
65170
  if (unknownDefaults.length) {
65171
- logger51.warn(`Unknown attributes (${unknownDefaults}) passed to defaults option of findOrCreate`);
65171
+ logger53.warn(`Unknown attributes (${unknownDefaults}) passed to defaults option of findOrCreate`);
65172
65172
  }
65173
65173
  }
65174
65174
  if (options2.transaction === void 0 && this.sequelize.constructor._cls) {
@@ -70311,9 +70311,9 @@ var require_connection_manager = __commonJS({
70311
70311
  var _5 = require_lodash();
70312
70312
  var semver = require_semver2();
70313
70313
  var errors2 = require_errors2();
70314
- var { logger: logger51 } = require_logger();
70314
+ var { logger: logger53 } = require_logger();
70315
70315
  var deprecations = require_deprecations();
70316
- var debug = logger51.debugContext("pool");
70316
+ var debug = logger53.debugContext("pool");
70317
70317
  var ConnectionManager = class {
70318
70318
  constructor(dialect, sequelize) {
70319
70319
  const config3 = _5.cloneDeep(sequelize.config);
@@ -70598,10 +70598,10 @@ var require_connection_manager2 = __commonJS({
70598
70598
  var semver = require_semver2();
70599
70599
  var AbstractConnectionManager = require_connection_manager();
70600
70600
  var SequelizeErrors = require_errors2();
70601
- var { logger: logger51 } = require_logger();
70601
+ var { logger: logger53 } = require_logger();
70602
70602
  var DataTypes2 = require_data_types9().mariadb;
70603
70603
  var momentTz = require_moment_timezone2();
70604
- var debug = logger51.debugContext("connection:mariadb");
70604
+ var debug = logger53.debugContext("connection:mariadb");
70605
70605
  var parserStore = require_parserStore()("mariadb");
70606
70606
  var ConnectionManager = class _ConnectionManager extends AbstractConnectionManager {
70607
70607
  constructor(dialect, sequelize) {
@@ -71273,12 +71273,12 @@ var require_query2 = __commonJS({
71273
71273
  var sequelizeErrors = require_errors2();
71274
71274
  var _5 = require_lodash();
71275
71275
  var DataTypes2 = require_data_types9();
71276
- var { logger: logger51 } = require_logger();
71276
+ var { logger: logger53 } = require_logger();
71277
71277
  var ER_DUP_ENTRY = 1062;
71278
71278
  var ER_DEADLOCK = 1213;
71279
71279
  var ER_ROW_IS_REFERENCED = 1451;
71280
71280
  var ER_NO_REFERENCED_ROW = 1452;
71281
- var debug = logger51.debugContext("sql:mariadb");
71281
+ var debug = logger53.debugContext("sql:mariadb");
71282
71282
  var Query = class extends AbstractQuery {
71283
71283
  constructor(connection, sequelize, options2) {
71284
71284
  super(connection, sequelize, __spreadValues({ showWarnings: false }, options2));
@@ -74499,12 +74499,12 @@ var require_connection_manager3 = __commonJS({
74499
74499
  "use strict";
74500
74500
  var AbstractConnectionManager = require_connection_manager();
74501
74501
  var AsyncQueue = require_async_queue().default;
74502
- var { logger: logger51 } = require_logger();
74502
+ var { logger: logger53 } = require_logger();
74503
74503
  var sequelizeErrors = require_errors2();
74504
74504
  var DataTypes2 = require_data_types9().mssql;
74505
74505
  var parserStore = require_parserStore()("mssql");
74506
- var debug = logger51.debugContext("connection:mssql");
74507
- var debugTedious = logger51.debugContext("connection:mssql:tedious");
74506
+ var debug = logger53.debugContext("connection:mssql");
74507
+ var debugTedious = logger53.debugContext("connection:mssql:tedious");
74508
74508
  var ConnectionManager = class extends AbstractConnectionManager {
74509
74509
  constructor(dialect, sequelize) {
74510
74510
  sequelize.config.port = sequelize.config.port || 1433;
@@ -74647,8 +74647,8 @@ var require_query3 = __commonJS({
74647
74647
  var sequelizeErrors = require_errors2();
74648
74648
  var parserStore = require_parserStore()("mssql");
74649
74649
  var _5 = require_lodash();
74650
- var { logger: logger51 } = require_logger();
74651
- var debug = logger51.debugContext("sql:mssql");
74650
+ var { logger: logger53 } = require_logger();
74651
+ var debug = logger53.debugContext("sql:mssql");
74652
74652
  var minSafeIntegerAsBigInt = BigInt(Number.MIN_SAFE_INTEGER);
74653
74653
  var maxSafeIntegerAsBigInt = BigInt(Number.MAX_SAFE_INTEGER);
74654
74654
  function getScale(aNum) {
@@ -75972,10 +75972,10 @@ var require_connection_manager4 = __commonJS({
75972
75972
  };
75973
75973
  var AbstractConnectionManager = require_connection_manager();
75974
75974
  var SequelizeErrors = require_errors2();
75975
- var { logger: logger51 } = require_logger();
75975
+ var { logger: logger53 } = require_logger();
75976
75976
  var DataTypes2 = require_data_types9().mysql;
75977
75977
  var momentTz = require_moment_timezone2();
75978
- var debug = logger51.debugContext("connection:mysql");
75978
+ var debug = logger53.debugContext("connection:mysql");
75979
75979
  var parserStore = require_parserStore()("mysql");
75980
75980
  var { promisify: promisify2 } = require("util");
75981
75981
  var ConnectionManager = class _ConnectionManager extends AbstractConnectionManager {
@@ -76098,12 +76098,12 @@ var require_query4 = __commonJS({
76098
76098
  var AbstractQuery = require_query();
76099
76099
  var sequelizeErrors = require_errors2();
76100
76100
  var _5 = require_lodash();
76101
- var { logger: logger51 } = require_logger();
76101
+ var { logger: logger53 } = require_logger();
76102
76102
  var ER_DUP_ENTRY = 1062;
76103
76103
  var ER_DEADLOCK = 1213;
76104
76104
  var ER_ROW_IS_REFERENCED = 1451;
76105
76105
  var ER_NO_REFERENCED_ROW = 1452;
76106
- var debug = logger51.debugContext("sql:mysql");
76106
+ var debug = logger53.debugContext("sql:mysql");
76107
76107
  var Query = class extends AbstractQuery {
76108
76108
  constructor(connection, sequelize, options2) {
76109
76109
  super(connection, sequelize, __spreadValues({ showWarnings: false }, options2));
@@ -76417,9 +76417,9 @@ var require_connection_manager5 = __commonJS({
76417
76417
  var AbstractConnectionManager = require_connection_manager();
76418
76418
  var SequelizeErrors = require_errors2();
76419
76419
  var parserStore = require_parserStore()("oracle");
76420
- var { logger: logger51 } = require_logger();
76420
+ var { logger: logger53 } = require_logger();
76421
76421
  var semver = require_semver2();
76422
- var debug = logger51.debugContext("connection:oracle");
76422
+ var debug = logger53.debugContext("connection:oracle");
76423
76423
  var DataTypes2 = require_data_types9().oracle;
76424
76424
  var { promisify: promisify2 } = require("util");
76425
76425
  var OracleConnectionManager = class extends AbstractConnectionManager {
@@ -76574,8 +76574,8 @@ var require_query5 = __commonJS({
76574
76574
  var parserStore = require_parserStore()("oracle");
76575
76575
  var _5 = require_lodash();
76576
76576
  var Utils2 = require_utils2();
76577
- var { logger: logger51 } = require_logger();
76578
- var debug = logger51.debugContext("sql:oracle");
76577
+ var { logger: logger53 } = require_logger();
76578
+ var debug = logger53.debugContext("sql:oracle");
76579
76579
  var OracleQuery = class extends AbstractQuery {
76580
76580
  constructor(connection, sequelize, options2) {
76581
76581
  super(connection, sequelize, options2);
@@ -78156,8 +78156,8 @@ var require_connection_manager6 = __commonJS({
78156
78156
  "use strict";
78157
78157
  var _5 = require_lodash();
78158
78158
  var AbstractConnectionManager = require_connection_manager();
78159
- var { logger: logger51 } = require_logger();
78160
- var debug = logger51.debugContext("connection:pg");
78159
+ var { logger: logger53 } = require_logger();
78160
+ var debug = logger53.debugContext("connection:pg");
78161
78161
  var sequelizeErrors = require_errors2();
78162
78162
  var semver = require_semver2();
78163
78163
  var dataTypes = require_data_types9();
@@ -78407,8 +78407,8 @@ var require_query6 = __commonJS({
78407
78407
  var QueryTypes2 = require_query_types();
78408
78408
  var sequelizeErrors = require_errors2();
78409
78409
  var _5 = require_lodash();
78410
- var { logger: logger51 } = require_logger();
78411
- var debug = logger51.debugContext("sql:pg");
78410
+ var { logger: logger53 } = require_logger();
78411
+ var debug = logger53.debugContext("sql:pg");
78412
78412
  var Query = class extends AbstractQuery {
78413
78413
  static formatBindParameters(sql, values, dialect) {
78414
78414
  const stringReplaceFunc = (value) => typeof value === "string" ? value.replace(/\0/g, "\\0") : value;
@@ -79668,8 +79668,8 @@ var require_connection_manager7 = __commonJS({
79668
79668
  var fs7 = require("fs");
79669
79669
  var path19 = require("path");
79670
79670
  var AbstractConnectionManager = require_connection_manager();
79671
- var { logger: logger51 } = require_logger();
79672
- var debug = logger51.debugContext("connection:sqlite");
79671
+ var { logger: logger53 } = require_logger();
79672
+ var debug = logger53.debugContext("connection:sqlite");
79673
79673
  var dataTypes = require_data_types9().sqlite;
79674
79674
  var sequelizeErrors = require_errors2();
79675
79675
  var parserStore = require_parserStore()("sqlite");
@@ -79754,8 +79754,8 @@ var require_query7 = __commonJS({
79754
79754
  var QueryTypes2 = require_query_types();
79755
79755
  var sequelizeErrors = require_errors2();
79756
79756
  var parserStore = require_parserStore()("sqlite");
79757
- var { logger: logger51 } = require_logger();
79758
- var debug = logger51.debugContext("sql:sqlite");
79757
+ var { logger: logger53 } = require_logger();
79758
+ var debug = logger53.debugContext("sql:sqlite");
79759
79759
  function stringifyIfBigint(value) {
79760
79760
  if (typeof value === "bigint") {
79761
79761
  return value.toString();
@@ -80728,9 +80728,9 @@ var require_connection_manager8 = __commonJS({
80728
80728
  "use strict";
80729
80729
  var AbstractConnectionManager = require_connection_manager();
80730
80730
  var sequelizeErrors = require_errors2();
80731
- var { logger: logger51 } = require_logger();
80731
+ var { logger: logger53 } = require_logger();
80732
80732
  var DataTypes2 = require_data_types9().db2;
80733
- var debug = logger51.debugContext("connection:db2");
80733
+ var debug = logger53.debugContext("connection:db2");
80734
80734
  var parserStore = require_parserStore()("db2");
80735
80735
  var ConnectionManager = class extends AbstractConnectionManager {
80736
80736
  constructor(dialect, sequelize) {
@@ -80823,9 +80823,9 @@ var require_query8 = __commonJS({
80823
80823
  var sequelizeErrors = require_errors2();
80824
80824
  var parserStore = require_parserStore()("db2");
80825
80825
  var _5 = require_lodash();
80826
- var { logger: logger51 } = require_logger();
80826
+ var { logger: logger53 } = require_logger();
80827
80827
  var moment = require_moment();
80828
- var debug = logger51.debugContext("sql:db2");
80828
+ var debug = logger53.debugContext("sql:db2");
80829
80829
  var Query = class extends AbstractQuery {
80830
80830
  getInsertIdField() {
80831
80831
  return "id";
@@ -82187,9 +82187,9 @@ var require_connection_manager9 = __commonJS({
82187
82187
  };
82188
82188
  var AbstractConnectionManager = require_connection_manager();
82189
82189
  var SequelizeErrors = require_errors2();
82190
- var { logger: logger51 } = require_logger();
82190
+ var { logger: logger53 } = require_logger();
82191
82191
  var DataTypes2 = require_data_types9().snowflake;
82192
- var debug = logger51.debugContext("connection:snowflake");
82192
+ var debug = logger53.debugContext("connection:snowflake");
82193
82193
  var parserStore = require_parserStore()("snowflake");
82194
82194
  var ConnectionManager = class extends AbstractConnectionManager {
82195
82195
  constructor(dialect, sequelize) {
@@ -82304,12 +82304,12 @@ var require_query9 = __commonJS({
82304
82304
  var AbstractQuery = require_query();
82305
82305
  var sequelizeErrors = require_errors2();
82306
82306
  var _5 = require_lodash();
82307
- var { logger: logger51 } = require_logger();
82307
+ var { logger: logger53 } = require_logger();
82308
82308
  var ER_DUP_ENTRY = 1062;
82309
82309
  var ER_DEADLOCK = 1213;
82310
82310
  var ER_ROW_IS_REFERENCED = 1451;
82311
82311
  var ER_NO_REFERENCED_ROW = 1452;
82312
- var debug = logger51.debugContext("sql:snowflake");
82312
+ var debug = logger53.debugContext("sql:snowflake");
82313
82313
  var Query = class extends AbstractQuery {
82314
82314
  static formatBindParameters(sql, values, dialect) {
82315
82315
  const bindParam = [];
@@ -104967,8 +104967,8 @@ var require_index_cjs = __commonJS({
104967
104967
  EventType["Disconnected"] = "disconnected_event";
104968
104968
  })(exports2.EventType || (exports2.EventType = {}));
104969
104969
  var WeComApiClient = class {
104970
- constructor(logger51, timeout = 1e4) {
104971
- this.logger = logger51;
104970
+ constructor(logger53, timeout = 1e4) {
104971
+ this.logger = logger53;
104972
104972
  this.httpClient = axios.create({
104973
104973
  timeout,
104974
104974
  headers: {
@@ -105016,7 +105016,7 @@ var require_index_cjs = __commonJS({
105016
105016
  }
105017
105017
  var DEFAULT_WS_URL = "wss://openws.work.weixin.qq.com";
105018
105018
  var WsConnectionManager2 = class {
105019
- constructor(logger51, heartbeatInterval = 3e4, reconnectBaseDelay = 1e3, maxReconnectAttempts = 10, wsUrl, wsOptions, maxReplyQueueSize, maxAuthFailureAttempts) {
105019
+ constructor(logger53, heartbeatInterval = 3e4, reconnectBaseDelay = 1e3, maxReconnectAttempts = 10, wsUrl, wsOptions, maxReplyQueueSize, maxAuthFailureAttempts) {
105020
105020
  this.ws = null;
105021
105021
  this.heartbeatTimer = null;
105022
105022
  this.reconnectAttempts = 0;
@@ -105043,7 +105043,7 @@ var require_index_cjs = __commonJS({
105043
105043
  this.onReconnecting = null;
105044
105044
  this.onError = null;
105045
105045
  this.onServerDisconnect = null;
105046
- this.logger = logger51;
105046
+ this.logger = logger53;
105047
105047
  this.heartbeatInterval = heartbeatInterval;
105048
105048
  this.reconnectBaseDelay = reconnectBaseDelay;
105049
105049
  this.maxReconnectAttempts = maxReconnectAttempts;
@@ -105101,7 +105101,7 @@ var require_index_cjs = __commonJS({
105101
105101
  });
105102
105102
  this.ws.on("message", (data2) => {
105103
105103
  try {
105104
- const raw = data2.toString();
105104
+ const raw = data2.toString().replace(/[\x00-\x08\x0B-\x0D\x0E-\x1F]/g, "");
105105
105105
  const frame = JSON.parse(raw);
105106
105106
  this.handleFrame(frame);
105107
105107
  } catch (error48) {
@@ -105477,8 +105477,8 @@ var require_index_cjs = __commonJS({
105477
105477
  }
105478
105478
  };
105479
105479
  var MessageHandler = class {
105480
- constructor(logger51) {
105481
- this.logger = logger51;
105480
+ constructor(logger53) {
105481
+ this.logger = logger53;
105482
105482
  }
105483
105483
  /**
105484
105484
  * 处理收到的 WebSocket 帧,解析并触发对应的消息/事件
@@ -110994,6 +110994,7 @@ var init_SkillListingInjector = __esm({
110994
110994
  "- skill \u53EF\u80FD\u5305\u542B\u5F53\u524D\u63D0\u793A\u8BCD\u5176\u4ED6\u4F4D\u7F6E\u6CA1\u6709\u7684\u5F3A\u5236\u5DE5\u4F5C\u6D41\u3001\u7EA6\u675F\u3001\u5DE5\u5177\u89C4\u5219\u6216\u8F93\u51FA\u8981\u6C42\u3002",
110995
110995
  "- \u5982\u679C\u591A\u4E2A skills \u540C\u65F6\u5339\u914D\uFF0C\u5148\u52A0\u8F7D\u6700\u5177\u4F53\u7684\u90A3\u4E2A\uFF1B\u5982\u679C\u6CA1\u6709 skill \u5339\u914D\uFF0C\u5219\u6B63\u5E38\u7EE7\u7EED\u3002",
110996
110996
  "- \u5F53 skill \u5F15\u7528\u4E86\u76F8\u5BF9\u8DEF\u5F84\uFF08\u4F8B\u5982 scripts/\u3001references/\uFF09\u65F6\uFF0C\u57FA\u4E8E\u8BE5 skill \u7684\u76EE\u5F55\u89E3\u6790\u8FD9\u4E9B\u8DEF\u5F84\u3002",
110997
+ "- \u7528\u6237\u8F93\u5165\u4EE5 `/skill-name ` \u5F00\u5934\u65F6\uFF0C\u8868\u793A\u624B\u52A8\u52A0\u8F7D\u4E00\u4E2A skill\uFF1Bskill \u5185\u5BB9\u4F1A\u88AB\u6CE8\u5165\u5230 user message \u4E2D\uFF0C\u4F60\u76F4\u63A5\u9075\u5FAA\u5176\u6307\u4EE4\u5373\u53EF\u3002",
110997
110998
  "",
110998
110999
  "<available_skills>",
110999
111000
  ...lines,
@@ -115125,11 +115126,11 @@ var init_global_utils = __esm({
115125
115126
 
115126
115127
  // node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js
115127
115128
  function logProxy(funcName, namespace, args2) {
115128
- const logger51 = getGlobal("diag");
115129
- if (!logger51) {
115129
+ const logger53 = getGlobal("diag");
115130
+ if (!logger53) {
115130
115131
  return;
115131
115132
  }
115132
- return logger51[funcName](namespace, ...args2);
115133
+ return logger53[funcName](namespace, ...args2);
115133
115134
  }
115134
115135
  var DiagComponentLogger;
115135
115136
  var init_ComponentLogger = __esm({
@@ -115175,17 +115176,17 @@ var init_types6 = __esm({
115175
115176
  });
115176
115177
 
115177
115178
  // node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js
115178
- function createLogLevelDiagLogger(maxLevel, logger51) {
115179
+ function createLogLevelDiagLogger(maxLevel, logger53) {
115179
115180
  if (maxLevel < DiagLogLevel.NONE) {
115180
115181
  maxLevel = DiagLogLevel.NONE;
115181
115182
  } else if (maxLevel > DiagLogLevel.ALL) {
115182
115183
  maxLevel = DiagLogLevel.ALL;
115183
115184
  }
115184
- logger51 = logger51 || {};
115185
+ logger53 = logger53 || {};
115185
115186
  function _filterFunc(funcName, theLevel) {
115186
- const theFunc = logger51[funcName];
115187
+ const theFunc = logger53[funcName];
115187
115188
  if (typeof theFunc === "function" && maxLevel >= theLevel) {
115188
- return theFunc.bind(logger51);
115189
+ return theFunc.bind(logger53);
115189
115190
  }
115190
115191
  return function() {
115191
115192
  };
@@ -115228,16 +115229,16 @@ var init_diag = __esm({
115228
115229
  constructor() {
115229
115230
  function _logProxy(funcName) {
115230
115231
  return function(...args2) {
115231
- const logger51 = getGlobal("diag");
115232
- if (!logger51)
115232
+ const logger53 = getGlobal("diag");
115233
+ if (!logger53)
115233
115234
  return;
115234
- return logger51[funcName](...args2);
115235
+ return logger53[funcName](...args2);
115235
115236
  };
115236
115237
  }
115237
115238
  const self2 = this;
115238
- const setLogger = (logger51, optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }) => {
115239
+ const setLogger = (logger53, optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }) => {
115239
115240
  var _a31, _b18, _c;
115240
- if (logger51 === self2) {
115241
+ if (logger53 === self2) {
115241
115242
  const err2 = new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");
115242
115243
  self2.error((_a31 = err2.stack) !== null && _a31 !== void 0 ? _a31 : err2.message);
115243
115244
  return false;
@@ -115248,7 +115249,7 @@ var init_diag = __esm({
115248
115249
  };
115249
115250
  }
115250
115251
  const oldLogger = getGlobal("diag");
115251
- const newLogger = createLogLevelDiagLogger((_b18 = optionsOrLogLevel.logLevel) !== null && _b18 !== void 0 ? _b18 : DiagLogLevel.INFO, logger51);
115252
+ const newLogger = createLogLevelDiagLogger((_b18 = optionsOrLogLevel.logLevel) !== null && _b18 !== void 0 ? _b18 : DiagLogLevel.INFO, logger53);
115252
115253
  if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
115253
115254
  const stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : "<failed to generate stacktrace>";
115254
115255
  oldLogger.warn(`Current logger will be overwritten from ${stack}`);
@@ -124192,12 +124193,12 @@ var init_dist6 = __esm({
124192
124193
  if (options2.warnings.length === 0) {
124193
124194
  return;
124194
124195
  }
124195
- const logger51 = globalThis.AI_SDK_LOG_WARNINGS;
124196
- if (logger51 === false) {
124196
+ const logger53 = globalThis.AI_SDK_LOG_WARNINGS;
124197
+ if (logger53 === false) {
124197
124198
  return;
124198
124199
  }
124199
- if (typeof logger51 === "function") {
124200
- logger51(options2);
124200
+ if (typeof logger53 === "function") {
124201
+ logger53(options2);
124201
124202
  return;
124202
124203
  }
124203
124204
  if (!hasLoggedBefore) {
@@ -131171,30 +131172,30 @@ var init_line = __esm({
131171
131172
  // node_modules/openai/internal/utils/log.mjs
131172
131173
  function noop3() {
131173
131174
  }
131174
- function makeLogFn(fnLevel, logger51, logLevel) {
131175
- if (!logger51 || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
131175
+ function makeLogFn(fnLevel, logger53, logLevel) {
131176
+ if (!logger53 || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
131176
131177
  return noop3;
131177
131178
  } else {
131178
- return logger51[fnLevel].bind(logger51);
131179
+ return logger53[fnLevel].bind(logger53);
131179
131180
  }
131180
131181
  }
131181
131182
  function loggerFor(client) {
131182
- const logger51 = client.logger;
131183
+ const logger53 = client.logger;
131183
131184
  const logLevel = client.logLevel ?? "off";
131184
- if (!logger51) {
131185
+ if (!logger53) {
131185
131186
  return noopLogger2;
131186
131187
  }
131187
- const cachedLogger = cachedLoggers.get(logger51);
131188
+ const cachedLogger = cachedLoggers.get(logger53);
131188
131189
  if (cachedLogger && cachedLogger[0] === logLevel) {
131189
131190
  return cachedLogger[1];
131190
131191
  }
131191
131192
  const levelLogger = {
131192
- error: makeLogFn("error", logger51, logLevel),
131193
- warn: makeLogFn("warn", logger51, logLevel),
131194
- info: makeLogFn("info", logger51, logLevel),
131195
- debug: makeLogFn("debug", logger51, logLevel)
131193
+ error: makeLogFn("error", logger53, logLevel),
131194
+ warn: makeLogFn("warn", logger53, logLevel),
131195
+ info: makeLogFn("info", logger53, logLevel),
131196
+ debug: makeLogFn("debug", logger53, logLevel)
131196
131197
  };
131197
- cachedLoggers.set(logger51, [logLevel, levelLogger]);
131198
+ cachedLoggers.set(logger53, [logLevel, levelLogger]);
131198
131199
  return levelLogger;
131199
131200
  }
131200
131201
  var levelNumbers, parseLogLevel, noopLogger2, cachedLoggers, formatRequestDetails;
@@ -131321,7 +131322,7 @@ var init_streaming = __esm({
131321
131322
  }
131322
131323
  static fromSSEResponse(response, controller, client, synthesizeEventData) {
131323
131324
  let consumed = false;
131324
- const logger51 = client ? loggerFor(client) : console;
131325
+ const logger53 = client ? loggerFor(client) : console;
131325
131326
  async function* iterator() {
131326
131327
  if (consumed) {
131327
131328
  throw new OpenAIError("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
@@ -131341,8 +131342,8 @@ var init_streaming = __esm({
131341
131342
  try {
131342
131343
  data2 = JSON.parse(sse.data);
131343
131344
  } catch (e) {
131344
- logger51.error(`Could not parse message into JSON:`, sse.data);
131345
- logger51.error(`From chunk:`, sse.raw);
131345
+ logger53.error(`Could not parse message into JSON:`, sse.data);
131346
+ logger53.error(`From chunk:`, sse.raw);
131346
131347
  throw e;
131347
131348
  }
131348
131349
  if (data2 && data2.error) {
@@ -142484,13 +142485,24 @@ var init_environmentMessages = __esm({
142484
142485
  });
142485
142486
 
142486
142487
  // src/core/agent/runtime/runtimeOnlyMessages.ts
142487
- function isRuntimeOnlyMessage(message) {
142488
- if (message.role === "system") return true;
142488
+ function isSkillListingReminder(message) {
142489
142489
  if (message.role !== "user" || typeof message.content !== "string") return false;
142490
142490
  return message.content.startsWith("<system-reminder>") && message.content.includes("<available_skills>");
142491
142491
  }
142492
- function stripRuntimeOnlyMessages(messages) {
142493
- return messages.filter((message) => !isRuntimeOnlyMessage(message));
142492
+ function isRuntimeInjectedMessage(message) {
142493
+ if (message.role === "system") return true;
142494
+ if (message.role !== "user") return false;
142495
+ if (message.metadata?.source === "runtime-skill") return true;
142496
+ return isSkillListingReminder(message);
142497
+ }
142498
+ function stripSystemMessages(messages) {
142499
+ return messages.filter((message) => message.role !== "system");
142500
+ }
142501
+ function stripPromptInjectedMessages(messages) {
142502
+ return messages.filter((message) => message.role !== "system" && !isSkillListingReminder(message));
142503
+ }
142504
+ function stripInheritedRuntimeMessages(messages) {
142505
+ return messages.filter((message) => !isRuntimeInjectedMessage(message));
142494
142506
  }
142495
142507
  var init_runtimeOnlyMessages = __esm({
142496
142508
  "src/core/agent/runtime/runtimeOnlyMessages.ts"() {
@@ -142571,7 +142583,34 @@ async function runCompactionWithRetries(input, sanitizedWorker, beforeTokens) {
142571
142583
  });
142572
142584
  return lastResult;
142573
142585
  }
142574
- throw attemptResult.error;
142586
+ compactionLogger.warn("compaction.first_attempt_failed_using_pruning_fallback", {
142587
+ sessionId: input.worker.sessionId,
142588
+ workerId: input.worker.id,
142589
+ agentId: input.worker.agentId,
142590
+ attempt: attempt + 1,
142591
+ error: attemptResult.error
142592
+ });
142593
+ const fallbackResult = await runSingleAttempt({
142594
+ input,
142595
+ worker: currentWorker,
142596
+ targetTokenLimit,
142597
+ messageTargetTokenLimit: targetResolution.messageTargetTokenLimit,
142598
+ beforeTokens,
142599
+ keepRecentCount: step.keepRecentCount ?? 3,
142600
+ forceDeterministic: true
142601
+ });
142602
+ if (!fallbackResult.ok) throw fallbackResult.error;
142603
+ return {
142604
+ worker: fallbackResult.compactedWorker,
142605
+ changed: fallbackResult.changed,
142606
+ targetTokenLimit,
142607
+ messageTargetTokenLimit: targetResolution.messageTargetTokenLimit,
142608
+ ...targetResolution.overheadTokens !== void 0 ? { overheadTokens: targetResolution.overheadTokens } : {},
142609
+ ...targetResolution.overheadExceedsTarget !== void 0 ? { overheadExceedsTarget: targetResolution.overheadExceedsTarget } : {},
142610
+ ...beforeTokens !== void 0 ? { beforeTokens } : {},
142611
+ ...fallbackResult.afterTokens !== void 0 ? { afterTokens: fallbackResult.afterTokens } : {},
142612
+ attempts: attempt + 1
142613
+ };
142575
142614
  }
142576
142615
  currentWorker = attemptResult.compactedWorker;
142577
142616
  lastResult = {
@@ -142618,7 +142657,7 @@ async function runSingleCompaction(input, sanitizedWorker, targetTokenLimit, bef
142618
142657
  };
142619
142658
  }
142620
142659
  async function runSingleAttempt(params) {
142621
- const { input, worker, targetTokenLimit, messageTargetTokenLimit, beforeTokens, keepRecentCount } = params;
142660
+ const { input, worker, targetTokenLimit, messageTargetTokenLimit, beforeTokens, keepRecentCount, forceDeterministic } = params;
142622
142661
  const compactor = input.compactor;
142623
142662
  const startedAt = Date.now();
142624
142663
  const baseEventFields = {
@@ -142639,7 +142678,8 @@ async function runSingleAttempt(params) {
142639
142678
  request: input.request,
142640
142679
  targetTokenLimit: messageTargetTokenLimit,
142641
142680
  reason: input.reason,
142642
- ...keepRecentCount !== void 0 ? { keepRecentCount } : {}
142681
+ ...keepRecentCount !== void 0 ? { keepRecentCount } : {},
142682
+ ...forceDeterministic ? { forceDeterministic } : {}
142643
142683
  });
142644
142684
  const compactedWorker = sanitizeWorker(result.worker);
142645
142685
  const afterTokens = await estimateCompactionTokensSafely(input.tokenEstimator, compactedWorker.messages);
@@ -142671,7 +142711,7 @@ async function resolveCompactionMessageTargetTokenLimit(input, preparedTargetTok
142671
142711
  input.tokenEstimator,
142672
142712
  input.systemMessages,
142673
142713
  [
142674
- ...stripRuntimeOnlyMessages(input.request.inputMessages),
142714
+ ...stripSystemMessages(input.request.inputMessages),
142675
142715
  ...input.request.transientInputMessages ?? []
142676
142716
  ]
142677
142717
  );
@@ -142734,7 +142774,7 @@ function emitCompactionEvent(observer, event) {
142734
142774
  error: error48
142735
142775
  });
142736
142776
  }
142737
- const logger51 = compactionLogger.child({
142777
+ const logger53 = compactionLogger.child({
142738
142778
  sessionId: event.sessionId,
142739
142779
  workerId: event.workerId,
142740
142780
  agentId: event.agentId
@@ -142747,11 +142787,11 @@ function emitCompactionEvent(observer, event) {
142747
142787
  ...event.durableBeforeTokens !== void 0 ? { durableBeforeTokens: event.durableBeforeTokens } : {}
142748
142788
  };
142749
142789
  if (event.phase === "started") {
142750
- logger51.info("compaction.started", payload);
142790
+ logger53.info("compaction.started", payload);
142751
142791
  return;
142752
142792
  }
142753
142793
  if (event.phase === "completed") {
142754
- logger51.info("compaction.completed", {
142794
+ logger53.info("compaction.completed", {
142755
142795
  ...payload,
142756
142796
  afterMessageCount: event.afterMessageCount,
142757
142797
  ...event.durableAfterTokens !== void 0 ? { durableAfterTokens: event.durableAfterTokens } : {},
@@ -142759,7 +142799,7 @@ function emitCompactionEvent(observer, event) {
142759
142799
  });
142760
142800
  return;
142761
142801
  }
142762
- logger51.error("compaction.failed", {
142802
+ logger53.error("compaction.failed", {
142763
142803
  ...payload,
142764
142804
  durationMs: event.durationMs,
142765
142805
  error: event.error
@@ -142768,7 +142808,7 @@ function emitCompactionEvent(observer, event) {
142768
142808
  function sanitizeWorker(worker) {
142769
142809
  return {
142770
142810
  ...worker,
142771
- messages: stripRuntimeOnlyMessages(worker.messages)
142811
+ messages: stripSystemMessages(worker.messages)
142772
142812
  };
142773
142813
  }
142774
142814
  var import_node_util, DEFAULT_RETRY_STEPS, compactionLogger;
@@ -142910,8 +142950,8 @@ var init_WorkerRuntime = __esm({
142910
142950
  compactionLogger2 = createStructuredLogger({ scope: "worker-runtime.compaction" });
142911
142951
  DefaultWorkerContextManager = class {
142912
142952
  async prepare(input) {
142913
- const workerMessages = stripRuntimeOnlyMessages(input.worker.messages);
142914
- const inputMessages = stripRuntimeOnlyMessages(input.request.inputMessages);
142953
+ const workerMessages = stripSystemMessages(input.worker.messages);
142954
+ const inputMessages = stripPromptInjectedMessages(input.request.inputMessages);
142915
142955
  const transientInputMessages = input.request.transientInputMessages ?? [];
142916
142956
  const transientStart = workerMessages.length + inputMessages.length;
142917
142957
  return {
@@ -143125,7 +143165,7 @@ var init_WorkerRuntime = __esm({
143125
143165
  async repairStepBoundaryBudget(prepared, replayInput, loopResult) {
143126
143166
  const checkpointWorker = this.sanitizeWorker({
143127
143167
  ...prepared.worker,
143128
- messages: stripRuntimeOnlyMessages(toDurableMessages(prepared, loopResult.messages))
143168
+ messages: stripSystemMessages(toDurableMessages(prepared, loopResult.messages))
143129
143169
  });
143130
143170
  const triggerTokens = await this.estimateTelemetryTokens(
143131
143171
  this.toBudgetMessages(replayInput, loopResult.messages)
@@ -143338,7 +143378,7 @@ var init_WorkerRuntime = __esm({
143338
143378
  * runtime-only 与 transient 消息不会进入 durable transcript。
143339
143379
  */
143340
143380
  async saveLoopResult(prepared, loopResult, result) {
143341
- const messages = stripRuntimeOnlyMessages(toDurableMessages(prepared, loopResult.messages));
143381
+ const messages = stripSystemMessages(toDurableMessages(prepared, loopResult.messages));
143342
143382
  const saveError = await this.saveWorker({
143343
143383
  ...prepared.worker,
143344
143384
  messages
@@ -143354,7 +143394,7 @@ var init_WorkerRuntime = __esm({
143354
143394
  agent: input.agent,
143355
143395
  tools: input.tools,
143356
143396
  system,
143357
- messages: stripRuntimeOnlyMessages(messages),
143397
+ messages,
143358
143398
  modelSettings: input.modelSettings,
143359
143399
  fallbackModelSettings: input.fallbackModelSettings,
143360
143400
  retry: input.retry,
@@ -143430,14 +143470,14 @@ var init_WorkerRuntime = __esm({
143430
143470
  return {
143431
143471
  ...prepared,
143432
143472
  worker: this.sanitizeWorker(prepared.worker),
143433
- messages: stripRuntimeOnlyMessages(prepared.messages)
143473
+ messages: stripSystemMessages(prepared.messages)
143434
143474
  };
143435
143475
  }
143436
143476
  /** 清理 worker 的 durable messages,移除只应存在于运行时的内部消息。 */
143437
143477
  sanitizeWorker(worker) {
143438
143478
  return {
143439
143479
  ...worker,
143440
- messages: stripRuntimeOnlyMessages(worker.messages)
143480
+ messages: stripSystemMessages(worker.messages)
143441
143481
  };
143442
143482
  }
143443
143483
  /** 用新的 worker 替换 prepared 里的 worker,保持其它 prepare 元数据不变。 */
@@ -143978,27 +144018,47 @@ function truncateMessagesFromEnd(messages, targetTokens) {
143978
144018
  let currentTokens = 0;
143979
144019
  for (let i = messages.length - 1; i >= 0; i--) {
143980
144020
  const msg = messages[i];
143981
- const msgTokens = estimateTokens(formatMessageContent(msg));
143982
- if (currentTokens + msgTokens <= targetTokens || result.length === 0) {
143983
- result.unshift(`[${getLabelForMessage(msg)}]: ${formatMessageContent(msg)}`);
144021
+ const formatted = `[${getLabelForMessage(msg)}]: ${formatMessageContent(msg)}`;
144022
+ const msgTokens = estimateTokens(formatted);
144023
+ if (currentTokens + msgTokens <= targetTokens) {
144024
+ result.unshift(formatted);
143984
144025
  currentTokens += msgTokens;
143985
- } else {
143986
- break;
144026
+ continue;
143987
144027
  }
144028
+ if (result.length === 0) {
144029
+ result.unshift(truncateTextToTokenBudget(formatted, targetTokens));
144030
+ }
144031
+ break;
143988
144032
  }
143989
144033
  if (result.length < messages.length) {
143990
144034
  result.unshift(`[... ${messages.length - result.length} earlier messages truncated ...]`);
143991
144035
  }
143992
144036
  return result.join("\n\n");
143993
144037
  }
143994
- function buildFallbackSummary(messages, totalTokens, tips) {
143995
- const targetTokens = Math.floor(totalTokens * COMPRESSION_CONFIG.SUMMARY_COMPRESSION_RATIO);
143996
- const truncatedContent = truncateMessagesFromEnd(messages, targetTokens);
144038
+ function truncateTextToTokenBudget(text7, targetTokens) {
144039
+ if (targetTokens <= 0) return "";
144040
+ if (estimateTokens(text7) <= targetTokens) return text7;
144041
+ const suffix = "\n[... truncated to fit summary budget ...]";
144042
+ if (estimateTokens(suffix) >= targetTokens) return "";
144043
+ let low = 0;
144044
+ let high = text7.length;
144045
+ while (low < high) {
144046
+ const mid = Math.ceil((low + high) / 2);
144047
+ if (estimateTokens(`${text7.slice(0, mid).trimEnd()}${suffix}`) <= targetTokens) {
144048
+ low = mid;
144049
+ } else {
144050
+ high = mid - 1;
144051
+ }
144052
+ }
144053
+ return `${text7.slice(0, Math.max(0, low)).trimEnd()}${suffix}`;
144054
+ }
144055
+ function buildFallbackSummaryContent(messages, totalTokens, tips, evidenceBudget) {
144056
+ const truncatedContent = truncateMessagesFromEnd(messages, evidenceBudget);
143997
144057
  const tipsSection = tips ? `### User Preferences / Corrections
143998
144058
  ${tips}
143999
144059
 
144000
144060
  ` : "";
144001
- const summaryContent = `<<<PREVIOUS_CONVERSATION_SUMMARY>>>
144061
+ return `<<<PREVIOUS_CONVERSATION_SUMMARY>>>
144002
144062
  (Original: ${messages.length} messages, ~${totalTokens} tokens, truncated from newest)
144003
144063
 
144004
144064
  ### Current State
@@ -144008,12 +144068,47 @@ ${tipsSection}### Evidence
144008
144068
  ${truncatedContent}
144009
144069
 
144010
144070
  <<<END_SUMMARY>>>`;
144071
+ }
144072
+ function enforceHardTokenLimit(content3, targetTokens) {
144073
+ if (!targetTokens || targetTokens <= 0 || estimateTokens(content3) <= targetTokens) return content3;
144074
+ const marker21 = "### Evidence\n";
144075
+ const markerIndex = content3.indexOf(marker21);
144076
+ if (markerIndex === -1) {
144077
+ return truncateTextToTokenBudget(content3, targetTokens);
144078
+ }
144079
+ const evidenceStart = markerIndex + marker21.length;
144080
+ const endMarker = "\n\n<<<END_SUMMARY>>>";
144081
+ const endIndex = content3.lastIndexOf(endMarker);
144082
+ if (endIndex <= evidenceStart) {
144083
+ return truncateTextToTokenBudget(content3, targetTokens);
144084
+ }
144085
+ const prefix = content3.slice(0, evidenceStart);
144086
+ const suffix = content3.slice(endIndex);
144087
+ const overheadTokens = estimateTokens(prefix + suffix);
144088
+ const evidenceBudget = Math.max(1, targetTokens - overheadTokens - 8);
144089
+ const trimmedEvidence = truncateTextToTokenBudget(content3.slice(evidenceStart, endIndex), evidenceBudget);
144090
+ const trimmed = `${prefix}${trimmedEvidence}${suffix}`;
144091
+ if (estimateTokens(trimmed) <= targetTokens) return trimmed;
144092
+ return truncateTextToTokenBudget(content3, targetTokens);
144093
+ }
144094
+ function resolveFallbackEvidenceBudget(messages, totalTokens, tips, maxSummaryTokens) {
144095
+ if (!maxSummaryTokens || !Number.isFinite(maxSummaryTokens) || maxSummaryTokens <= 0) {
144096
+ return Math.floor(totalTokens * COMPRESSION_CONFIG.SUMMARY_COMPRESSION_RATIO);
144097
+ }
144098
+ const emptyContent = buildFallbackSummaryContent(messages, totalTokens, tips, 0);
144099
+ const overheadTokens = estimateTokens(emptyContent);
144100
+ return Math.max(1, Math.floor(maxSummaryTokens) - overheadTokens - 8);
144101
+ }
144102
+ function buildFallbackSummary(messages, totalTokens, tips, maxSummaryTokens) {
144103
+ const hardLimit = maxSummaryTokens && Number.isFinite(maxSummaryTokens) && maxSummaryTokens > 0 ? Math.floor(maxSummaryTokens) : void 0;
144104
+ const evidenceBudget = resolveFallbackEvidenceBudget(messages, totalTokens, tips, hardLimit);
144105
+ const draftContent = buildFallbackSummaryContent(messages, totalTokens, tips, evidenceBudget);
144106
+ const summaryContent = hardLimit ? enforceHardTokenLimit(draftContent, hardLimit) : draftContent;
144011
144107
  const summaryMessage = {
144012
144108
  role: "user",
144013
144109
  content: summaryContent,
144014
144110
  metadata: {
144015
144111
  isSummary: true,
144016
- summarizedMessageIds: messages.map((_5, i) => `msg-${i}`),
144017
144112
  summarizedCount: messages.length,
144018
144113
  summaryTokens: estimateTokens(summaryContent),
144019
144114
  generatedAt: Date.now()
@@ -144024,7 +144119,127 @@ ${truncatedContent}
144024
144119
  );
144025
144120
  return summaryMessage;
144026
144121
  }
144027
- function buildSummaryPrompt(messages, totalTokens, tips) {
144122
+ function resolveSummarizerInputBudget(options2) {
144123
+ const configured = options2?.modelInputTokens;
144124
+ if (configured && Number.isFinite(configured) && configured > 0) {
144125
+ return Math.floor(configured * SUMMARY_INPUT_BUDGET_RATIO);
144126
+ }
144127
+ return Math.floor(DEFAULT_SUMMARIZER_INPUT_TOKENS * SUMMARY_INPUT_BUDGET_RATIO);
144128
+ }
144129
+ function resolveChunkBudget(inputBudget, options2) {
144130
+ const configured = options2?.maxChunkTokens;
144131
+ if (configured && Number.isFinite(configured) && configured > 0) {
144132
+ return Math.floor(configured);
144133
+ }
144134
+ return Math.max(1, Math.floor(inputBudget * SUMMARY_CHUNK_BUDGET_RATIO));
144135
+ }
144136
+ function resolveChunkConcurrency(options2) {
144137
+ const configured = options2?.chunkConcurrency;
144138
+ if (!configured || !Number.isFinite(configured)) return CHUNK_SUMMARY_CONCURRENCY;
144139
+ return Math.max(1, Math.floor(configured));
144140
+ }
144141
+ function clamp(value, min, max) {
144142
+ return Math.max(min, Math.min(max, value));
144143
+ }
144144
+ function calculateSummaryBudget(sourceTokens, mode = "summary", options2) {
144145
+ const explicitTarget = options2?.targetSummaryTokens;
144146
+ const ratio = mode === "chunk" ? CHUNK_SUMMARY_TARGET_RATIO : SUMMARY_TARGET_RATIO;
144147
+ const min = mode === "chunk" ? CHUNK_SUMMARY_TARGET_MIN_TOKENS : SUMMARY_TARGET_MIN_TOKENS;
144148
+ const max = mode === "chunk" ? CHUNK_SUMMARY_TARGET_MAX_TOKENS : SUMMARY_TARGET_MAX_TOKENS;
144149
+ const rawTarget = explicitTarget && Number.isFinite(explicitTarget) && explicitTarget > 0 ? Math.floor(explicitTarget) : clamp(Math.floor(sourceTokens * ratio), min, max);
144150
+ const targetTokens = clamp(rawTarget, min, max);
144151
+ return {
144152
+ mode,
144153
+ targetTokens,
144154
+ tightenThresholdTokens: Math.ceil(targetTokens * SUMMARY_TIGHTEN_THRESHOLD_RATIO)
144155
+ };
144156
+ }
144157
+ function isContextOverflowError2(error48) {
144158
+ const text7 = String(
144159
+ error48 instanceof Error ? `${error48.name} ${error48.message}` : error48
144160
+ ).toLowerCase();
144161
+ return [
144162
+ "context length",
144163
+ "context_length_exceeded",
144164
+ "maximum context",
144165
+ "too many tokens",
144166
+ "input too long",
144167
+ "token limit"
144168
+ ].some((marker21) => text7.includes(marker21));
144169
+ }
144170
+ function summarizeErrorForLog(error48) {
144171
+ const isOverflow = isContextOverflowError2(error48);
144172
+ if (error48 instanceof Error) {
144173
+ return `kind=${isOverflow ? "context_overflow" : "error"} name=${error48.name}`;
144174
+ }
144175
+ return `kind=${isOverflow ? "context_overflow" : typeof error48}`;
144176
+ }
144177
+ async function mapLimit(items, limit2, fn3) {
144178
+ const results = new Array(items.length);
144179
+ let next2 = 0;
144180
+ async function worker() {
144181
+ while (next2 < items.length) {
144182
+ const index3 = next2++;
144183
+ results[index3] = await fn3(items[index3], index3);
144184
+ }
144185
+ }
144186
+ await Promise.all(
144187
+ Array.from({ length: Math.min(limit2, items.length) }, () => worker())
144188
+ );
144189
+ return results;
144190
+ }
144191
+ function planMessageChunks(messages, maxChunkTokens) {
144192
+ if (messages.length === 0) return [];
144193
+ const chunks = [];
144194
+ let current = [];
144195
+ let currentTokens = 0;
144196
+ const pushCurrent = () => {
144197
+ if (!current.length) return;
144198
+ chunks.push({
144199
+ index: chunks.length,
144200
+ messages: current,
144201
+ tokenEstimate: currentTokens
144202
+ });
144203
+ current = [];
144204
+ currentTokens = 0;
144205
+ };
144206
+ for (const msg of messages) {
144207
+ const msgTokens = estimateTokens(formatMessageContent(msg));
144208
+ const startsNewTurn = msg.role === "user" && current.length > 0;
144209
+ if (startsNewTurn && currentTokens + msgTokens > maxChunkTokens) {
144210
+ pushCurrent();
144211
+ }
144212
+ current.push(msg);
144213
+ currentTokens += msgTokens;
144214
+ }
144215
+ pushCurrent();
144216
+ return chunks;
144217
+ }
144218
+ function unwrapSummaryContent(content3) {
144219
+ const text7 = String(content3 ?? "").trim();
144220
+ if (!text7) return "";
144221
+ return text7.replace(/^<<<PREVIOUS_CONVERSATION_SUMMARY>>>\s*/u, "").replace(/\s*<<<END_SUMMARY>>>$/u, "").trim().replace(/^\(Original:[^\n]*\)\s*/u, "").trim();
144222
+ }
144223
+ function getSummaryHeader(content3) {
144224
+ const text7 = String(content3 ?? "").trim();
144225
+ const withoutStart = text7.replace(/^<<<PREVIOUS_CONVERSATION_SUMMARY>>>\s*/u, "").trim();
144226
+ const firstLine = withoutStart.split("\n", 1)[0]?.trim();
144227
+ return firstLine && /^\(Original:/u.test(firstLine) ? firstLine : void 0;
144228
+ }
144229
+ function buildTargetLengthInstruction(budget) {
144230
+ return `Target length: <= ${budget.targetTokens} tokens.`;
144231
+ }
144232
+ function buildCutPriorityItems() {
144233
+ return [
144234
+ "1. Drop routine progress, pleasantries, and successful checks with no new findings.",
144235
+ "2. Drop repeated exploration and failed attempts that no longer affect decisions or next actions.",
144236
+ "3. Compress tool outputs to path/symbol + conclusion + key error only.",
144237
+ "4. Merge similar decisions and constraints instead of repeating them.",
144238
+ "5. Keep only current open tasks; omit completed tasks unless needed as evidence.",
144239
+ "6. Preserve exact wording only for active user constraints, corrections, paths, commands, errors, config values, and symbols."
144240
+ ];
144241
+ }
144242
+ function buildSummaryPrompt(messages, totalTokens, tips, budget) {
144028
144243
  const conversationLog = buildConversationLog(messages);
144029
144244
  const tipsSection = tips ? ["### User Instructions for This Summary", tips, ""] : [];
144030
144245
  return [
@@ -144034,6 +144249,11 @@ function buildSummaryPrompt(messages, totalTokens, tips) {
144034
144249
  "",
144035
144250
  SUMMARY_SECTION_TEMPLATE,
144036
144251
  "",
144252
+ "Budget rules:",
144253
+ buildTargetLengthInstruction(budget),
144254
+ "If the summary would exceed the target, cut in this order:",
144255
+ ...buildCutPriorityItems(),
144256
+ "",
144037
144257
  "Before finalizing, verify the summary answers:",
144038
144258
  "- What is the current goal?",
144039
144259
  "- What decisions and constraints must be preserved?",
@@ -144049,6 +144269,44 @@ function buildSummaryPrompt(messages, totalTokens, tips) {
144049
144269
  conversationLog
144050
144270
  ].join("\n");
144051
144271
  }
144272
+ function buildChunkTips(chunk, totalChunks, tips) {
144273
+ const chunkTip = [
144274
+ `This is chunk ${chunk.index + 1}/${totalChunks} of a longer conversation.`,
144275
+ "Summarize only this chunk. Do not assume missing context from other chunks.",
144276
+ "Preserve decisions, constraints, current state, open tasks, and evidence found in this chunk."
144277
+ ].join("\n");
144278
+ return tips ? `${chunkTip}
144279
+
144280
+ ${tips}` : chunkTip;
144281
+ }
144282
+ function buildMergeTips(tips) {
144283
+ const mergeTip = [
144284
+ "Merge these chunk summaries into one continuation handoff summary.",
144285
+ "Remove duplicates, resolve conflicts in favor of later chunks, and preserve concrete decisions, constraints, open tasks, and evidence."
144286
+ ].join("\n");
144287
+ return tips ? `${mergeTip}
144288
+
144289
+ ${tips}` : mergeTip;
144290
+ }
144291
+ function buildTightenPrompt(summary, budget, tips) {
144292
+ const tipsSection = tips ? ["### User Instructions for This Rewrite", tips, ""] : [];
144293
+ return [
144294
+ `Rewrite the existing handoff summary to fit <= ${budget.targetTokens} tokens.`,
144295
+ "Do not add facts. Do not infer missing details. Only delete, merge, and tighten wording.",
144296
+ "Keep continuity-critical information: current goal, decisions, constraints, current state, open tasks, user corrections, and evidence.",
144297
+ "Use the same section order where content exists:",
144298
+ "",
144299
+ SUMMARY_SECTION_TEMPLATE,
144300
+ "",
144301
+ "Cut in this order:",
144302
+ ...buildCutPriorityItems(),
144303
+ "",
144304
+ ...tipsSection,
144305
+ "Existing summary:",
144306
+ "",
144307
+ unwrapSummaryContent(summary.content)
144308
+ ].join("\n");
144309
+ }
144052
144310
  function extractSummaryText(rawOutput) {
144053
144311
  let cleaned = rawOutput.replace(/<analysis>[\s\S]*?<\/analysis>/g, "").trim();
144054
144312
  const summaryMatch = cleaned.match(/<summary>([\s\S]*?)<\/summary>/);
@@ -144057,76 +144315,257 @@ function extractSummaryText(rawOutput) {
144057
144315
  }
144058
144316
  return cleaned;
144059
144317
  }
144060
- async function summarizeMessages(messages, languageModel, originalTokens, tips) {
144318
+ async function summarizeSinglePass(messages, languageModel, totalTokens, tips, budget) {
144319
+ const prompt = buildSummaryPrompt(messages, totalTokens, tips, budget);
144320
+ const result = await generateText({
144321
+ model: languageModel,
144322
+ messages: [
144323
+ {
144324
+ role: "system",
144325
+ content: SUMMARIZER_SYSTEM_PROMPT
144326
+ },
144327
+ {
144328
+ role: "user",
144329
+ content: prompt
144330
+ }
144331
+ ],
144332
+ temperature: 0,
144333
+ providerOptions: {
144334
+ google: {
144335
+ thinkingConfig: {
144336
+ thinkingLevel: "low"
144337
+ }
144338
+ }
144339
+ }
144340
+ });
144341
+ const text7 = result.text.trim();
144342
+ if (!text7) {
144343
+ throw new Error("ERROR_EMPTY_SUMMARY");
144344
+ }
144345
+ const summaryBody = extractSummaryText(text7);
144346
+ if (!summaryBody) {
144347
+ throw new Error("ERROR_EMPTY_SUMMARY_AFTER_EXTRACTION");
144348
+ }
144349
+ const summaryContent = `<<<PREVIOUS_CONVERSATION_SUMMARY>>>
144350
+ (Original: ${messages.length} messages, ~${totalTokens} tokens)
144351
+
144352
+ ${summaryBody}
144353
+
144354
+ <<<END_SUMMARY>>>`;
144355
+ const summaryMessage = {
144356
+ role: "user",
144357
+ content: summaryContent,
144358
+ metadata: {
144359
+ isSummary: true,
144360
+ summarizedCount: messages.length,
144361
+ summaryTokens: estimateTokens(summaryContent),
144362
+ generatedAt: Date.now()
144363
+ }
144364
+ };
144365
+ logger22.info(
144366
+ `LLM summarized mode=${budget.mode} messages=${messages.length} sourceTokens=${totalTokens} targetTokens=${budget.targetTokens} summaryTokens=${estimateTokens(summaryContent)}`
144367
+ );
144368
+ return summaryMessage;
144369
+ }
144370
+ async function tightenSummary(summary, languageModel, budget, tips) {
144371
+ const result = await generateText({
144372
+ model: languageModel,
144373
+ messages: [
144374
+ {
144375
+ role: "system",
144376
+ content: SUMMARIZER_SYSTEM_PROMPT
144377
+ },
144378
+ {
144379
+ role: "user",
144380
+ content: buildTightenPrompt(summary, budget, tips)
144381
+ }
144382
+ ],
144383
+ temperature: 0,
144384
+ providerOptions: {
144385
+ google: {
144386
+ thinkingConfig: {
144387
+ thinkingLevel: "low"
144388
+ }
144389
+ }
144390
+ }
144391
+ });
144392
+ const summaryBody = extractSummaryText(result.text.trim());
144393
+ if (!summaryBody) {
144394
+ throw new Error("ERROR_EMPTY_TIGHTENED_SUMMARY");
144395
+ }
144396
+ const header = getSummaryHeader(summary.content) ?? "(Original: previous summary, tightened)";
144397
+ const summaryContent = `<<<PREVIOUS_CONVERSATION_SUMMARY>>>
144398
+ ${header}
144399
+
144400
+ ${summaryBody}
144401
+
144402
+ <<<END_SUMMARY>>>`;
144403
+ const metadata = summary.metadata;
144404
+ return {
144405
+ role: "user",
144406
+ content: summaryContent,
144407
+ metadata: {
144408
+ ...metadata,
144409
+ isSummary: true,
144410
+ summaryTokens: estimateTokens(summaryContent),
144411
+ generatedAt: Date.now()
144412
+ }
144413
+ };
144414
+ }
144415
+ async function enforceSummaryBudget(summary, languageModel, budget, tips) {
144416
+ const summaryTokens = estimateTokens(String(summary.content ?? ""));
144417
+ if (summaryTokens <= budget.tightenThresholdTokens || !languageModel) {
144418
+ logger22.debug(
144419
+ `Summary budget ok mode=${budget.mode} targetTokens=${budget.targetTokens} thresholdTokens=${budget.tightenThresholdTokens} summaryTokens=${summaryTokens}`
144420
+ );
144421
+ return summary;
144422
+ }
144423
+ logger22.info(
144424
+ `Summary exceeds budget; tightening mode=${budget.mode} targetTokens=${budget.targetTokens} thresholdTokens=${budget.tightenThresholdTokens} summaryTokens=${summaryTokens}`
144425
+ );
144426
+ try {
144427
+ const tightened = await tightenSummary(summary, languageModel, budget, tips);
144428
+ const tightenedTokens = estimateTokens(String(tightened.content ?? ""));
144429
+ logger22.info(
144430
+ `Summary tightened mode=${budget.mode} beforeTokens=${summaryTokens} afterTokens=${tightenedTokens} targetTokens=${budget.targetTokens}`
144431
+ );
144432
+ if (tightenedTokens > budget.tightenThresholdTokens) {
144433
+ logger22.warn(
144434
+ `Summary still exceeds budget after tightening; using deterministic fallback mode=${budget.mode} targetTokens=${budget.targetTokens} tightenedTokens=${tightenedTokens}`
144435
+ );
144436
+ return buildFallbackSummary([summary], summaryTokens, tips, budget.targetTokens);
144437
+ }
144438
+ return tightened;
144439
+ } catch (error48) {
144440
+ logger22.warn(`Summary tighten failed; using deterministic fallback: ${summarizeErrorForLog(error48)}`);
144441
+ return buildFallbackSummary([summary], summaryTokens, tips, budget.targetTokens);
144442
+ }
144443
+ }
144444
+ function buildMergedSummaryMessage(chunkSummaries, totalMessages, totalTokens) {
144445
+ const body = chunkSummaries.map((summary) => unwrapSummaryContent(summary.message.content)).filter(Boolean).join("\n\n");
144446
+ const summaryContent = `<<<PREVIOUS_CONVERSATION_SUMMARY>>>
144447
+ (Original: ${totalMessages} messages, ~${totalTokens} tokens, chunked into ${chunkSummaries.length} summaries)
144448
+
144449
+ ${body}
144450
+
144451
+ <<<END_SUMMARY>>>`;
144452
+ const summaryMessage = {
144453
+ role: "user",
144454
+ content: summaryContent,
144455
+ metadata: {
144456
+ isSummary: true,
144457
+ summarizedCount: totalMessages,
144458
+ summaryTokens: estimateTokens(summaryContent),
144459
+ generatedAt: Date.now()
144460
+ }
144461
+ };
144462
+ return summaryMessage;
144463
+ }
144464
+ async function summarizeChunked(messages, languageModel, totalTokens, inputBudget, tips, options2) {
144465
+ const maxChunkTokens = resolveChunkBudget(inputBudget, options2);
144466
+ const concurrency = resolveChunkConcurrency(options2);
144467
+ const chunks = planMessageChunks(messages, maxChunkTokens);
144468
+ logger22.info(
144469
+ `LLM summarization mode=chunked chunks=${chunks.length} concurrency=${concurrency} sourceTokens=${totalTokens} maxChunkTokens=${maxChunkTokens}`
144470
+ );
144471
+ const chunkSummaries = await mapLimit(chunks, concurrency, async (chunk) => {
144472
+ let message;
144473
+ const chunkBudget = calculateSummaryBudget(chunk.tokenEstimate, "chunk", options2);
144474
+ const chunkTips = buildChunkTips(chunk, chunks.length, tips);
144475
+ if (chunk.tokenEstimate > maxChunkTokens) {
144476
+ logger22.warn(
144477
+ `Chunk exceeds budget; using truncation fallback for chunk index=${chunk.index} sourceTokens=${chunk.tokenEstimate} maxChunkTokens=${maxChunkTokens}`
144478
+ );
144479
+ message = buildFallbackSummary(chunk.messages, chunk.tokenEstimate, chunkTips, chunkBudget.targetTokens);
144480
+ } else {
144481
+ const summary = await summarizeSinglePass(
144482
+ chunk.messages,
144483
+ languageModel,
144484
+ chunk.tokenEstimate,
144485
+ chunkTips,
144486
+ chunkBudget
144487
+ );
144488
+ message = await enforceSummaryBudget(summary, languageModel, chunkBudget, chunkTips);
144489
+ }
144490
+ const summaryTokens = estimateTokens(String(message.content ?? ""));
144491
+ logger22.debug(
144492
+ `Chunk summarized index=${chunk.index} messages=${chunk.messages.length} sourceTokens=${chunk.tokenEstimate} targetTokens=${chunkBudget.targetTokens} summaryTokens=${summaryTokens}`
144493
+ );
144494
+ return {
144495
+ chunkIndex: chunk.index,
144496
+ sourceMessageCount: chunk.messages.length,
144497
+ sourceTokens: chunk.tokenEstimate,
144498
+ message,
144499
+ summaryTokens
144500
+ };
144501
+ });
144502
+ const merged = buildMergedSummaryMessage(chunkSummaries, messages.length, totalTokens);
144503
+ const mergedTokens = estimateTokens(String(merged.content ?? ""));
144504
+ const mergeBudget = calculateSummaryBudget(totalTokens, "merge", options2);
144505
+ if (mergedTokens <= inputBudget && mergedTokens <= mergeBudget.tightenThresholdTokens) {
144506
+ logger22.info(
144507
+ `LLM summarized mode=chunked-concat chunks=${chunks.length} sourceTokens=${totalTokens} targetTokens=${mergeBudget.targetTokens} summaryTokens=${mergedTokens}`
144508
+ );
144509
+ return merged;
144510
+ }
144511
+ logger22.info(
144512
+ `Chunk summaries exceed merge budget chunks=${chunks.length} summaryTokens=${mergedTokens} inputBudget=${inputBudget} targetTokens=${mergeBudget.targetTokens}; running merge summary`
144513
+ );
144514
+ const mergeSummary = await summarizeSinglePass(
144515
+ chunkSummaries.map((summary) => summary.message),
144516
+ languageModel,
144517
+ mergedTokens,
144518
+ buildMergeTips(tips),
144519
+ mergeBudget
144520
+ );
144521
+ return enforceSummaryBudget(mergeSummary, languageModel, mergeBudget, tips);
144522
+ }
144523
+ async function summarizeMessages(messages, options2 = {}) {
144061
144524
  if (messages.length === 0) {
144062
144525
  return {
144063
144526
  role: "user",
144064
144527
  content: "[Previous conversation summary - no messages to summarize]"
144065
144528
  };
144066
144529
  }
144530
+ const { languageModel, originalTokens, tips } = options2;
144067
144531
  const totalTokens = originalTokens ?? messages.reduce((sum, msg) => {
144068
144532
  return sum + estimateTokens(formatMessageContent(msg));
144069
144533
  }, 0);
144070
144534
  if (!languageModel) {
144071
144535
  return buildFallbackSummary(messages, totalTokens, tips);
144072
144536
  }
144073
- try {
144074
- const result = await generateText({
144075
- model: languageModel,
144076
- messages: [
144077
- {
144078
- role: "system",
144079
- content: SUMMARIZER_SYSTEM_PROMPT
144080
- },
144081
- {
144082
- role: "user",
144083
- content: buildSummaryPrompt(messages, totalTokens, tips)
144084
- }
144085
- ],
144086
- temperature: 0,
144087
- providerOptions: {
144088
- google: {
144089
- thinkingConfig: {
144090
- thinkingLevel: "low"
144091
- }
144092
- }
144093
- }
144094
- });
144095
- const text7 = result.text.trim();
144096
- if (!text7) {
144097
- throw new Error("ERROR_EMPTY_SUMMARY");
144098
- }
144099
- const summaryBody = extractSummaryText(text7);
144100
- if (!summaryBody) {
144101
- throw new Error("ERROR_EMPTY_SUMMARY_AFTER_EXTRACTION");
144102
- }
144103
- const summaryContent = `<<<PREVIOUS_CONVERSATION_SUMMARY>>>
144104
- (Original: ${messages.length} messages, ~${totalTokens} tokens)
144105
-
144106
- ${summaryBody}
144107
-
144108
- <<<END_SUMMARY>>>`;
144109
- const summaryMessage = {
144110
- role: "user",
144111
- content: summaryContent,
144112
- metadata: {
144113
- isSummary: true,
144114
- summarizedMessageIds: messages.map((_5, i) => `msg-${i}`),
144115
- summarizedCount: messages.length,
144116
- summaryTokens: estimateTokens(summaryContent),
144117
- generatedAt: Date.now()
144118
- }
144119
- };
144537
+ const inputBudget = resolveSummarizerInputBudget(options2);
144538
+ const summaryBudget = calculateSummaryBudget(totalTokens, "summary", options2);
144539
+ const promptTokens = estimateTokens(buildSummaryPrompt(messages, totalTokens, tips, summaryBudget));
144540
+ if (promptTokens > inputBudget) {
144120
144541
  logger22.info(
144121
- `LLM summarized ${messages.length} messages (${totalTokens} tokens) into ~${estimateTokens(summaryContent)} tokens`
144542
+ `LLM summarization input exceeds budget promptTokens=${promptTokens} inputBudget=${inputBudget}; using chunked mode`
144122
144543
  );
144123
- return summaryMessage;
144544
+ try {
144545
+ return await summarizeChunked(messages, languageModel, totalTokens, inputBudget, tips, options2);
144546
+ } catch (error48) {
144547
+ logger22.warn(`Chunked summarization failed, fallback to truncation: ${summarizeErrorForLog(error48)}`);
144548
+ return buildFallbackSummary(messages, totalTokens, tips);
144549
+ }
144550
+ }
144551
+ try {
144552
+ const summary = await summarizeSinglePass(messages, languageModel, totalTokens, tips, summaryBudget);
144553
+ return enforceSummaryBudget(summary, languageModel, summaryBudget, tips);
144124
144554
  } catch (error48) {
144125
- logger22.warn("LLM summarization failed, fallback to truncation:", error48);
144555
+ if (isContextOverflowError2(error48)) {
144556
+ logger22.warn(`LLM summarization hit context overflow, retrying with chunked mode: ${summarizeErrorForLog(error48)}`);
144557
+ try {
144558
+ return await summarizeChunked(messages, languageModel, totalTokens, inputBudget, tips, options2);
144559
+ } catch (chunkError) {
144560
+ logger22.warn(`Chunked summarization failed after context overflow, fallback to truncation: ${summarizeErrorForLog(chunkError)}`);
144561
+ return buildFallbackSummary(messages, totalTokens, tips);
144562
+ }
144563
+ }
144564
+ logger22.warn(`LLM summarization failed, fallback to truncation: ${summarizeErrorForLog(error48)}`);
144126
144565
  return buildFallbackSummary(messages, totalTokens, tips);
144127
144566
  }
144128
144567
  }
144129
- var logger22, TRUNCATION_SUFFIX, SUMMARIZER_MAX_TOOL_RESULT_CHARS, SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_WRITE, SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_DEFAULT, WRITE_TOOL_NAMES, SUMMARY_SECTION_TEMPLATE, SUMMARIZER_SYSTEM_PROMPT;
144568
+ var logger22, DEFAULT_SUMMARIZER_INPUT_TOKENS, SUMMARY_INPUT_BUDGET_RATIO, SUMMARY_CHUNK_BUDGET_RATIO, CHUNK_SUMMARY_CONCURRENCY, SUMMARY_TARGET_RATIO, SUMMARY_TARGET_MIN_TOKENS, SUMMARY_TARGET_MAX_TOKENS, CHUNK_SUMMARY_TARGET_RATIO, CHUNK_SUMMARY_TARGET_MIN_TOKENS, CHUNK_SUMMARY_TARGET_MAX_TOKENS, SUMMARY_TIGHTEN_THRESHOLD_RATIO, TRUNCATION_SUFFIX, SUMMARIZER_MAX_TOOL_RESULT_CHARS, SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_WRITE, SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_DEFAULT, WRITE_TOOL_NAMES, SUMMARY_SECTION_TEMPLATE, SUMMARIZER_SYSTEM_PROMPT;
144130
144569
  var init_message_summarizer = __esm({
144131
144570
  "src/core/context-compaction/engine/message-summarizer.ts"() {
144132
144571
  "use strict";
@@ -144135,6 +144574,17 @@ var init_message_summarizer = __esm({
144135
144574
  init_token_estimator();
144136
144575
  init_constants2();
144137
144576
  logger22 = createLogger("Summarizer");
144577
+ DEFAULT_SUMMARIZER_INPUT_TOKENS = 12e4;
144578
+ SUMMARY_INPUT_BUDGET_RATIO = 0.75;
144579
+ SUMMARY_CHUNK_BUDGET_RATIO = 0.6;
144580
+ CHUNK_SUMMARY_CONCURRENCY = 1;
144581
+ SUMMARY_TARGET_RATIO = 0.15;
144582
+ SUMMARY_TARGET_MIN_TOKENS = 800;
144583
+ SUMMARY_TARGET_MAX_TOKENS = 6e3;
144584
+ CHUNK_SUMMARY_TARGET_RATIO = 0.18;
144585
+ CHUNK_SUMMARY_TARGET_MIN_TOKENS = 400;
144586
+ CHUNK_SUMMARY_TARGET_MAX_TOKENS = 1800;
144587
+ SUMMARY_TIGHTEN_THRESHOLD_RATIO = 1.2;
144138
144588
  TRUNCATION_SUFFIX = "...";
144139
144589
  SUMMARIZER_MAX_TOOL_RESULT_CHARS = 2e3;
144140
144590
  SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_WRITE = 1500;
@@ -144183,6 +144633,23 @@ var init_message_summarizer = __esm({
144183
144633
  }
144184
144634
  });
144185
144635
 
144636
+ // src/core/context-compaction/engine/human-user-message.ts
144637
+ function isHumanUserMessage(message) {
144638
+ if (message.role !== "user") return false;
144639
+ const metadata = message.metadata;
144640
+ if (metadata?.isSummary) return false;
144641
+ if (typeof message.content === "string") {
144642
+ const text7 = message.content.trimStart();
144643
+ if (text7.startsWith("<system-reminder>")) return false;
144644
+ }
144645
+ return metadata?.source === void 0 || metadata.source === "human";
144646
+ }
144647
+ var init_human_user_message = __esm({
144648
+ "src/core/context-compaction/engine/human-user-message.ts"() {
144649
+ "use strict";
144650
+ }
144651
+ });
144652
+
144186
144653
  // src/core/context-compaction/engine/anchor-utils.ts
144187
144654
  function getTextContent(message) {
144188
144655
  if (typeof message.content === "string") {
@@ -144207,12 +144674,13 @@ function isAnchorMessage(message) {
144207
144674
  return false;
144208
144675
  }
144209
144676
  if (!text7) return false;
144210
- if (message.role === "user") return true;
144677
+ if (isHumanUserMessage(message)) return true;
144211
144678
  return false;
144212
144679
  }
144213
144680
  var init_anchor_utils = __esm({
144214
144681
  "src/core/context-compaction/engine/anchor-utils.ts"() {
144215
144682
  "use strict";
144683
+ init_human_user_message();
144216
144684
  }
144217
144685
  });
144218
144686
 
@@ -144238,18 +144706,18 @@ var init_SummarizationStrategy = __esm({
144238
144706
  setLanguageModel(model) {
144239
144707
  this.languageModel = model;
144240
144708
  }
144241
- async summary(messages, tips) {
144709
+ async summarizeWindow(messages, context2) {
144242
144710
  try {
144243
144711
  const originalTokens = messages.reduce(
144244
144712
  (sum, msg) => sum + estimateTokens(formatMessageContent(msg)),
144245
144713
  0
144246
144714
  );
144247
- const summary = await summarizeMessages(
144248
- messages,
144249
- this.languageModel,
144715
+ const summary = await summarizeMessages(messages, {
144716
+ languageModel: this.languageModel,
144250
144717
  originalTokens,
144251
- tips
144252
- );
144718
+ tips: context2.summaryTips,
144719
+ modelInputTokens: context2.modelInputTokens
144720
+ });
144253
144721
  const summaryTokens = estimateMessagesTokens([summary]);
144254
144722
  return { messages: [summary], savedTokens: originalTokens - summaryTokens };
144255
144723
  } catch (error48) {
@@ -144270,18 +144738,19 @@ var init_SummarizationStrategy = __esm({
144270
144738
  const isSummary = (msg) => import_lodash2.default.get(msg, "metadata.isSummary");
144271
144739
  for (const [index3, msg] of oldWindow.entries()) {
144272
144740
  if (isAnchorMessage(msg) && isSummary(oldWindow[index3 + 1])) {
144273
- compacted.push(msg);
144274
144741
  if (toSummary.length) {
144275
- const { messages: messages2, savedTokens: tokens } = await this.summary(toSummary, context2.summaryTips);
144742
+ const { messages: messages2, savedTokens: tokens } = await this.summarizeWindow(toSummary, context2);
144276
144743
  compacted.push(...messages2);
144277
144744
  savedTokens += tokens;
144278
144745
  toSummary = [];
144279
144746
  }
144747
+ compacted.push(msg);
144748
+ continue;
144280
144749
  }
144281
144750
  toSummary.push(msg);
144282
144751
  }
144283
144752
  if (toSummary.length) {
144284
- const { messages: messages2, savedTokens: tokens } = await this.summary(toSummary, context2.summaryTips);
144753
+ const { messages: messages2, savedTokens: tokens } = await this.summarizeWindow(toSummary, context2);
144285
144754
  compacted.push(...messages2);
144286
144755
  savedTokens += tokens;
144287
144756
  toSummary = [];
@@ -144312,16 +144781,27 @@ var init_SummarizationStrategy = __esm({
144312
144781
  });
144313
144782
 
144314
144783
  // src/core/context-compaction/engine/strategies/PruningStrategy.ts
144315
- var PruningStrategy;
144784
+ function findLastHumanUserMessageIndex(messages) {
144785
+ for (let i = messages.length - 1; i >= 0; i--) {
144786
+ const message = messages[i];
144787
+ if (message && isHumanUserMessage(message)) return i;
144788
+ }
144789
+ return -1;
144790
+ }
144791
+ var logger24, PruningStrategy;
144316
144792
  var init_PruningStrategy = __esm({
144317
144793
  "src/core/context-compaction/engine/strategies/PruningStrategy.ts"() {
144318
144794
  "use strict";
144319
144795
  init_token_estimator();
144320
144796
  init_anchor_utils();
144321
144797
  init_recent_window();
144798
+ init_logger();
144799
+ init_human_user_message();
144800
+ logger24 = createLogger("pruning-strategy");
144322
144801
  PruningStrategy = class {
144323
144802
  name = "Pruning";
144324
144803
  priority = 40;
144804
+ deterministic = true;
144325
144805
  async compress(context2, messages) {
144326
144806
  if (messages.length === 0) {
144327
144807
  return { messages: [], savedTokens: 0 };
@@ -144336,6 +144816,10 @@ var init_PruningStrategy = __esm({
144336
144816
  for (let i = recentStart; i < messages.length; i++) {
144337
144817
  keepFlags[i] = true;
144338
144818
  }
144819
+ const lastHumanUserIndex = findLastHumanUserMessageIndex(messages);
144820
+ if (lastHumanUserIndex >= 0) {
144821
+ keepFlags[lastHumanUserIndex] = true;
144822
+ }
144339
144823
  let keptTokens = 0;
144340
144824
  for (let i = 0; i < messages.length; i++) {
144341
144825
  if (keepFlags[i]) keptTokens += msgTokens[i];
@@ -144360,6 +144844,9 @@ var init_PruningStrategy = __esm({
144360
144844
  }
144361
144845
  const result = messages.filter((_5, index3) => keepFlags[index3]);
144362
144846
  const afterTokens = estimateMessagesTokens(result);
144847
+ logger24.warn(
144848
+ `Deterministic pruning applied: beforeMessages=${messages.length}, afterMessages=${result.length}, beforeTokens=${beforeTokens}, afterTokens=${afterTokens}, targetTokens=${context2.targetTokens}, recentStart=${recentStart}, lastHumanUserKept=${lastHumanUserIndex >= 0 && keepFlags[lastHumanUserIndex]}`
144849
+ );
144363
144850
  return {
144364
144851
  messages: result,
144365
144852
  savedTokens: Math.max(0, beforeTokens - afterTokens),
@@ -144388,7 +144875,7 @@ function isToolCallPart(part) {
144388
144875
  function isToolResultPart2(part) {
144389
144876
  return typeof part === "object" && part !== null && part.type === "tool-result" && typeof part.toolCallId === "string" && typeof part.toolName === "string";
144390
144877
  }
144391
- var logger24, MessageCompactor;
144878
+ var logger25, MessageCompactor;
144392
144879
  var init_MessageCompactor = __esm({
144393
144880
  "src/core/context-compaction/engine/MessageCompactor.ts"() {
144394
144881
  "use strict";
@@ -144396,7 +144883,8 @@ var init_MessageCompactor = __esm({
144396
144883
  init_constants2();
144397
144884
  init_logger();
144398
144885
  init_strategies();
144399
- logger24 = createLogger("MessageCompactor");
144886
+ init_human_user_message();
144887
+ logger25 = createLogger("MessageCompactor");
144400
144888
  MessageCompactor = class {
144401
144889
  constructor(agentId, getContextWindow, languageModel, config3) {
144402
144890
  this.agentId = agentId;
@@ -144452,11 +144940,11 @@ var init_MessageCompactor = __esm({
144452
144940
  const contextWindow = this.getContextWindow(model);
144453
144941
  const targetTokens = this.calculateTargetTokens(systemMessages, contextWindow);
144454
144942
  let currentTokens = estimateMessagesTokens(nonSystemMessages);
144455
- logger24.debug(
144943
+ logger25.debug(
144456
144944
  `model=${model}, contextWindow=${contextWindow}, currentTokens=${currentTokens}, targetTokens=${targetTokens}`
144457
144945
  );
144458
144946
  if (!this.config.force && currentTokens <= targetTokens) {
144459
- logger24.debug("No compression needed");
144947
+ logger25.debug("No compression needed");
144460
144948
  const sanitizedNonSystemMessages = this.sanitizeToolCallPairs(nonSystemMessages);
144461
144949
  return systemMessages.concat(sanitizedNonSystemMessages);
144462
144950
  }
@@ -144464,6 +144952,7 @@ var init_MessageCompactor = __esm({
144464
144952
  const context2 = {
144465
144953
  agentId: this.agentId,
144466
144954
  targetTokens,
144955
+ modelInputTokens: contextWindow,
144467
144956
  ...this.config.summaryTips ? { summaryTips: this.config.summaryTips } : {},
144468
144957
  keepRecentStartIndex: recentWindow.startIndex,
144469
144958
  keepRecentCount: recentWindow.count
@@ -144477,7 +144966,7 @@ var init_MessageCompactor = __esm({
144477
144966
  keepRecentStartIndex: recentWindow2.startIndex,
144478
144967
  keepRecentCount: recentWindow2.count
144479
144968
  };
144480
- logger24.noise(`Running: ${strategy.name}`);
144969
+ logger25.noise(`Running: ${strategy.name}`);
144481
144970
  const result = await strategy.compress(updatedContext, currentMessages);
144482
144971
  currentMessages = result.messages;
144483
144972
  totalSavedTokens += result.savedTokens;
@@ -144486,23 +144975,44 @@ var init_MessageCompactor = __esm({
144486
144975
  const diff = Math.abs(actualTokens - result.currentTokens);
144487
144976
  const tolerance = actualTokens * 0.05;
144488
144977
  if (diff > tolerance) {
144489
- logger24.warn(
144978
+ logger25.warn(
144490
144979
  `Token mismatch in ${strategy.name}: reported=${result.currentTokens}, actual=${actualTokens}, diff=${diff}`
144491
144980
  );
144492
144981
  }
144493
144982
  }
144494
144983
  currentTokens = actualTokens;
144495
144984
  currentMessages = this.sanitizeToolCallPairs(currentMessages);
144496
- logger24.debug(
144985
+ logger25.debug(
144497
144986
  `After ${strategy.name}: tokens=${currentTokens}, saved=${result.savedTokens}`
144498
144987
  );
144499
144988
  if (strategy.name === "Summarization" && currentTokens <= targetTokens) {
144500
- logger24.debug("Target met after semantic compaction, skipping pruning");
144989
+ logger25.debug("Target met after semantic compaction, skipping pruning");
144501
144990
  break;
144502
144991
  }
144503
144992
  }
144993
+ if (currentTokens > targetTokens) {
144994
+ const fallback = this.strategies.find((strategy) => strategy.deterministic);
144995
+ if (fallback) {
144996
+ logger25.warn(
144997
+ `Compaction target not met after strategy pipeline; running deterministic fallback: tokens=${currentTokens}, targetTokens=${targetTokens}, strategy=${fallback.name}`
144998
+ );
144999
+ const recentWindow2 = this.getRecentWindow(currentMessages);
145000
+ const fallbackContext = {
145001
+ ...context2,
145002
+ keepRecentStartIndex: recentWindow2.startIndex,
145003
+ keepRecentCount: recentWindow2.count
145004
+ };
145005
+ const result = await fallback.compress(fallbackContext, currentMessages);
145006
+ currentMessages = this.sanitizeToolCallPairs(result.messages);
145007
+ totalSavedTokens += result.savedTokens;
145008
+ currentTokens = estimateMessagesTokens(currentMessages);
145009
+ logger25.warn(
145010
+ `After deterministic fallback ${fallback.name}: tokens=${currentTokens}, targetTokens=${targetTokens}`
145011
+ );
145012
+ }
145013
+ }
144504
145014
  currentMessages = this.sanitizeToolCallPairs(currentMessages);
144505
- logger24.info(`Complete: totalSaved=${totalSavedTokens}`);
145015
+ logger25.info(`Complete: totalSaved=${totalSavedTokens}`);
144506
145016
  return systemMessages.concat(currentMessages);
144507
145017
  }
144508
145018
  /**
@@ -144524,13 +145034,13 @@ var init_MessageCompactor = __esm({
144524
145034
  if (minimumRecentCount === 0) return { startIndex: messages.length, count: 0 };
144525
145035
  let startIndex = Math.max(0, messages.length - minimumRecentCount);
144526
145036
  const userInsideWindow = messages.findIndex(
144527
- (msg, index3) => index3 >= startIndex && msg.role === "user"
145037
+ (msg, index3) => index3 >= startIndex && isHumanUserMessage(msg)
144528
145038
  );
144529
145039
  if (userInsideWindow >= 0) {
144530
145040
  startIndex = userInsideWindow;
144531
145041
  } else {
144532
145042
  for (let i = startIndex; i >= 0; i--) {
144533
- if (messages[i]?.role === "user") {
145043
+ if (messages[i] && isHumanUserMessage(messages[i])) {
144534
145044
  startIndex = i;
144535
145045
  break;
144536
145046
  }
@@ -144626,7 +145136,7 @@ var init_MessageCompactor = __esm({
144626
145136
  });
144627
145137
  const afterCount = result.length;
144628
145138
  if (beforeCount !== afterCount || unparseableInputIds.size > 0) {
144629
- logger24.debug(
145139
+ logger25.debug(
144630
145140
  `Sanitized: removed ${beforeCount - afterCount} messages, unparseable inputs=${unparseableInputIds.size} (${toolCallIds.size} tool-calls, ${toolResultIds.size} tool-results, ${validIds.size} valid pairs)`
144631
145141
  );
144632
145142
  }
@@ -144724,7 +145234,7 @@ function normalizeFile(file2) {
144724
145234
  }
144725
145235
  return { version: FILE_VERSION, entries };
144726
145236
  }
144727
- var import_fs16, import_path75, FILE_VERSION, DEFAULT_INPUT_RATIO, EWMA_ALPHA, MIN_RATIO, MAX_RATIO, MAX_SAMPLE_COUNT, MIN_OBSERVABLE_TOKENS, logger25, FileTokenCalibrationStore, defaultStore;
145237
+ var import_fs16, import_path75, FILE_VERSION, DEFAULT_INPUT_RATIO, EWMA_ALPHA, MIN_RATIO, MAX_RATIO, MAX_SAMPLE_COUNT, MIN_OBSERVABLE_TOKENS, logger26, FileTokenCalibrationStore, defaultStore;
144728
145238
  var init_token_calibration = __esm({
144729
145239
  "src/core/agent/runtime/token-calibration.ts"() {
144730
145240
  "use strict";
@@ -144740,7 +145250,7 @@ var init_token_calibration = __esm({
144740
145250
  MAX_RATIO = 2;
144741
145251
  MAX_SAMPLE_COUNT = 1e3;
144742
145252
  MIN_OBSERVABLE_TOKENS = 1;
144743
- logger25 = createStructuredLogger({ scope: "token-calibration" });
145253
+ logger26 = createStructuredLogger({ scope: "token-calibration" });
144744
145254
  FileTokenCalibrationStore = class {
144745
145255
  constructor(filePath = getDefaultCalibrationFilePath()) {
144746
145256
  this.filePath = filePath;
@@ -144787,7 +145297,7 @@ var init_token_calibration = __esm({
144787
145297
  this.cache = normalizeFile(parsed);
144788
145298
  return this.cache;
144789
145299
  } catch (error48) {
144790
- logger25.warn("load_failed", { filePath: this.filePath, error: error48 });
145300
+ logger26.warn("load_failed", { filePath: this.filePath, error: error48 });
144791
145301
  this.cache = createEmptyFile();
144792
145302
  return this.cache;
144793
145303
  }
@@ -144801,7 +145311,7 @@ var init_token_calibration = __esm({
144801
145311
  `, "utf-8");
144802
145312
  (0, import_fs16.renameSync)(tempPath, this.filePath);
144803
145313
  } catch (error48) {
144804
- logger25.warn("persist_failed", { filePath: this.filePath, error: error48 });
145314
+ logger26.warn("persist_failed", { filePath: this.filePath, error: error48 });
144805
145315
  }
144806
145316
  }
144807
145317
  };
@@ -144819,14 +145329,17 @@ function createWorkerTokenBudget(input) {
144819
145329
  targetRatioAfterCompaction: TARGET_RATIO_AFTER_COMPACTION
144820
145330
  };
144821
145331
  }
144822
- var import_node_util2, DEFAULT_CONTEXT_WINDOW2, PROACTIVE_THRESHOLD_RATIO, TARGET_RATIO_AFTER_COMPACTION, DefaultWorkerTokenEstimator, MessageWorkerCompactor;
145332
+ var import_node_util2, logger27, DEFAULT_CONTEXT_WINDOW2, PROACTIVE_THRESHOLD_RATIO, TARGET_RATIO_AFTER_COMPACTION, DefaultWorkerTokenEstimator, MessageWorkerCompactor;
144823
145333
  var init_context_compaction = __esm({
144824
145334
  "src/core/context-compaction/runtime/context-compaction.ts"() {
144825
145335
  "use strict";
144826
145336
  import_node_util2 = require("node:util");
144827
145337
  init_MessageCompactor();
145338
+ init_strategies();
144828
145339
  init_token_estimator();
144829
145340
  init_token_calibration();
145341
+ init_logger();
145342
+ logger27 = createLogger("message-worker-compactor");
144830
145343
  DEFAULT_CONTEXT_WINDOW2 = 128e3;
144831
145344
  PROACTIVE_THRESHOLD_RATIO = 0.85;
144832
145345
  TARGET_RATIO_AFTER_COMPACTION = 0.4;
@@ -144878,6 +145391,9 @@ var init_context_compaction = __esm({
144878
145391
  modelCapability;
144879
145392
  compactorConfig;
144880
145393
  async compact(input) {
145394
+ if (input.forceDeterministic) {
145395
+ return this.compactDeterministically(input);
145396
+ }
144881
145397
  const compactor = new MessageCompactor(
144882
145398
  this.agentId,
144883
145399
  (model) => this.getContextWindow(model),
@@ -144903,6 +145419,34 @@ var init_context_compaction = __esm({
144903
145419
  changed: !(0, import_node_util2.isDeepStrictEqual)(input.worker.messages, messages)
144904
145420
  };
144905
145421
  }
145422
+ async compactDeterministically(input) {
145423
+ const keepRecentCount = input.keepRecentCount ?? this.compactorConfig?.keepRecentCount ?? 3;
145424
+ const sourceMessages = [
145425
+ ...input.worker.messages,
145426
+ ...input.request.inputMessages,
145427
+ ...input.request.transientInputMessages ?? []
145428
+ ];
145429
+ const messages = await new PruningStrategy().compress(
145430
+ {
145431
+ agentId: this.agentId,
145432
+ targetTokens: input.targetTokenLimit,
145433
+ keepRecentCount,
145434
+ keepRecentStartIndex: Math.max(0, sourceMessages.length - keepRecentCount)
145435
+ },
145436
+ sourceMessages
145437
+ );
145438
+ logger27.warn(
145439
+ `Deterministic compaction fallback used: workerMessages=${input.worker.messages.length}, inputMessages=${input.request.inputMessages.length}, transientInputMessages=${input.request.transientInputMessages?.length ?? 0}, resultMessages=${messages.messages.length}, targetTokenLimit=${input.targetTokenLimit}, keepRecentCount=${keepRecentCount}`
145440
+ );
145441
+ return {
145442
+ worker: {
145443
+ ...input.worker,
145444
+ messages: messages.messages,
145445
+ contextVersion: (input.worker.contextVersion ?? 0) + 1
145446
+ },
145447
+ changed: !(0, import_node_util2.isDeepStrictEqual)(input.worker.messages, messages.messages)
145448
+ };
145449
+ }
144906
145450
  createSummaryLanguageModel() {
144907
145451
  return this.languageModelFactory.createLanguageModel(
144908
145452
  {
@@ -145260,7 +145804,7 @@ function createAgentWorkerRuntimeRunner(deps, options2 = {}) {
145260
145804
  },
145261
145805
  request: {
145262
145806
  system,
145263
- inputMessages: stripRuntimeOnlyMessages(input.inputMessages),
145807
+ inputMessages: stripPromptInjectedMessages(input.inputMessages),
145264
145808
  mentionedAgentIds: input.mentionedAgentIds,
145265
145809
  invocation: input.invocation ?? toWorkerInvocation(input.scope)
145266
145810
  },
@@ -145704,11 +146248,12 @@ function createBroadcastTool(calls) {
145704
146248
  description: "Broadcast a question to multiple agents in parallel and collect their responses. All target agents receive the same question at the same time and respond independently. Use this when you want diverse viewpoints, parallel expert input, or a quick team discussion.",
145705
146249
  inputSchema: zod_default.object({
145706
146250
  question: zod_default.string().describe("Question or topic to broadcast"),
145707
- targetAgentIds: zod_default.array(zod_default.string()).min(1).describe("Target agent IDs (at least one)")
146251
+ targetAgentIds: zod_default.array(zod_default.string()).min(1).describe("Target agent IDs (at least one)"),
146252
+ inherits: zod_default.boolean().default(false).describe("Whether to inherit the current conversation context")
145708
146253
  }),
145709
- execute: async ({ question, targetAgentIds }, { abortSignal }) => {
146254
+ execute: async ({ question, targetAgentIds, inherits }, { abortSignal }) => {
145710
146255
  if (abortSignal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
145711
- return calls.broadcast({ question, targetAgentIds });
146256
+ return calls.broadcast({ question, targetAgentIds, inherits });
145712
146257
  }
145713
146258
  });
145714
146259
  }
@@ -146208,7 +146753,7 @@ var init_TaskBroadcastRunner = __esm({
146208
146753
  if (!agentConfig) throw new Error(`Agent ${agentId} has no config`);
146209
146754
  const runtime = this.deps.getRuntime?.() ?? createExecutionRuntime();
146210
146755
  const contextMessages = filterBroadcastAggregateMessages(
146211
- this.deps.removeSystem(input.contextMessages)
146756
+ this.deps.sanitizeInheritedContext(input.contextMessages)
146212
146757
  );
146213
146758
  const messages = [
146214
146759
  ...contextMessages,
@@ -146497,7 +147042,7 @@ var init_TaskOrchestrator = __esm({
146497
147042
  const agentConfig = await agent.getConfig();
146498
147043
  if (!agentConfig) throw new Error(`Agent ${agentId} has no config`);
146499
147044
  const messages = inherits ? this.deps.getInheritedMessages() || [] : [];
146500
- let input = [...this.deps.removeSystem(messages)];
147045
+ let input = [...this.deps.sanitizeInheritedContext(messages)];
146501
147046
  input.push({
146502
147047
  role: "user",
146503
147048
  content: [`\u4F60\u662F @${agent.name}\u3002${agent.description || ""}`, "", `# Task`, task].join("\n")
@@ -146510,7 +147055,7 @@ var init_TaskOrchestrator = __esm({
146510
147055
  groupId: this.deps.session.groupId,
146511
147056
  runId: this.deps.runId,
146512
147057
  source: this.deps.executionSource ?? "desktop",
146513
- messages: this.deps.removeSystem(input)
147058
+ messages: this.deps.sanitizeInheritedContext(input)
146514
147059
  },
146515
147060
  runtime
146516
147061
  );
@@ -146698,8 +147243,9 @@ var init_TaskOrchestrator = __esm({
146698
147243
  };
146699
147244
  },
146700
147245
  broadcast: async (options2) => {
147246
+ const inherits = options2.inherits ?? false;
146701
147247
  return this.executeBroadcast(options2.question, options2.targetAgentIds, abortSignal, {
146702
- contextMessages: this.deps.getInheritedMessages()
147248
+ contextMessages: inherits ? this.deps.getInheritedMessages() : []
146703
147249
  });
146704
147250
  },
146705
147251
  listTasks: async () => {
@@ -146743,7 +147289,7 @@ var init_TaskOrchestrator = __esm({
146743
147289
  context: this.deps.context,
146744
147290
  agentDeps: this.agentDeps,
146745
147291
  getSkills: this.deps.getSkills,
146746
- removeSystem: this.deps.removeSystem,
147292
+ sanitizeInheritedContext: this.deps.sanitizeInheritedContext,
146747
147293
  createWorkerRuntimeRunner: (input) => this.createWorkerRuntimeRunner(input),
146748
147294
  onStream: this.deps.onStream,
146749
147295
  onNestedStream: this.deps.onNestedStream,
@@ -157260,7 +157806,7 @@ var init_SwarmExecutor = __esm({
157260
157806
  onUsage: (usage) => {
157261
157807
  this.taskUsage = this.mergeUsage(this.taskUsage, usage);
157262
157808
  },
157263
- removeSystem: (msgs) => stripRuntimeOnlyMessages(msgs),
157809
+ sanitizeInheritedContext: (msgs) => stripInheritedRuntimeMessages(msgs),
157264
157810
  getRuntime: () => this.activeRuntime,
157265
157811
  executionSource: resolveExecutionSource(this.metadata),
157266
157812
  runId: this.metadata?.runId,
@@ -157359,7 +157905,7 @@ var init_SwarmExecutor = __esm({
157359
157905
  return this.stripDurablePrefix(input.currentMessages, input.durableMessages);
157360
157906
  }
157361
157907
  normalizeDurableContext(messages) {
157362
- return stripRuntimeOnlyMessages(messages);
157908
+ return stripSystemMessages(messages);
157363
157909
  }
157364
157910
  getBroadcastSafeInheritedMessages(messages) {
157365
157911
  return filterBroadcastAggregateMessages(this.normalizeDurableContext(messages));
@@ -158705,7 +159251,7 @@ var init_ConversationManager = __esm({
158705
159251
  // ---------------------------------------------------------------------------
158706
159252
  async reply(message, abortSignal, metadata) {
158707
159253
  const messages = await this.getLLMMessages();
158708
- messages.push(message);
159254
+ messages.push(...Array.isArray(message) ? message : [message]);
158709
159255
  log13.debug("---->", messages.length, message);
158710
159256
  const replier = await this.chat.reply(messages, abortSignal, metadata ?? this.metadata);
158711
159257
  replier.onStream((block) => {
@@ -160082,13 +160628,13 @@ var init_MessageProcessor = __esm({
160082
160628
  * 群 Session 路径:sessionId → groupSessionContextStore.findById → Session manager pool
160083
160629
  * 单聊路径:sessionId(= sessionId)→ 解析 owner agent → 构建 ChatContext
160084
160630
  */
160085
- async processMessage(sessionId, message, metadata, retryCount = 0, aiMessageIdOverride) {
160631
+ async processMessage(sessionId, message, metadata, retryCount = 0, aiMessageIdOverride, targetAgentId) {
160086
160632
  const { groupSessionContextStore, messageRepository: messageRepository2 } = resolveMessageDeps();
160087
160633
  const groupSession = await groupSessionContextStore.findById(sessionId);
160088
160634
  const isGroupSession = !!groupSession;
160089
160635
  let agentId = null;
160090
160636
  if (isGroupSession) {
160091
- agentId = groupSession.speakerId ?? null;
160637
+ agentId = targetAgentId ?? groupSession.speakerId ?? null;
160092
160638
  } else {
160093
160639
  agentId = await this.resolveDirectAgentId(sessionId);
160094
160640
  }
@@ -160140,7 +160686,8 @@ var init_MessageProcessor = __esm({
160140
160686
  }),
160141
160687
  pendingDbWrites: this.pendingDbWrites
160142
160688
  }),
160143
- isGroupSession
160689
+ isGroupSession,
160690
+ targetAgentId
160144
160691
  };
160145
160692
  this.messageQueue?.registerRunId(ctx.runId, sessionId);
160146
160693
  this.messageQueue?.registerActiveRunSnapshot(sessionId, {
@@ -160199,6 +160746,9 @@ var init_MessageProcessor = __esm({
160199
160746
  this.callbacks.unregisterAbortController(sessionId);
160200
160747
  return { success: false };
160201
160748
  }
160749
+ if (metadata?.mentions?.length === 1 && !metadata.broadcast && ctx.targetAgentId) {
160750
+ await resolveMessageDeps().sessionRepository.update(sessionId, { speakerId: ctx.targetAgentId });
160751
+ }
160202
160752
  chat = mgr;
160203
160753
  } else {
160204
160754
  const singleChatContext = {
@@ -160268,7 +160818,11 @@ var init_MessageProcessor = __esm({
160268
160818
  });
160269
160819
  }, PROGRESS_INTERVAL_MS);
160270
160820
  log16.noise(`calling chat.reply, sessionId=${sessionId}`);
160271
- const { usage, model, fallback, finalAgentId } = await chat.reply(message, abortController.signal, metadata);
160821
+ const { usage, model, fallback, finalAgentId } = await chat.reply(
160822
+ message,
160823
+ abortController.signal,
160824
+ metadata
160825
+ );
160272
160826
  if (finalAgentId) {
160273
160827
  ctx.agentId = finalAgentId;
160274
160828
  }
@@ -160682,10 +161236,12 @@ var init_MessageQueue = __esm({
160682
161236
  const prev2 = this.queueMap.get(sessionId) || [];
160683
161237
  this.queueMap.set(sessionId, [...prev2, {
160684
161238
  message,
161239
+ llmMessages: queueContext?.llmMessages,
160685
161240
  metadata,
160686
161241
  dbMessageId: queueContext?.dbMessageId ?? "",
160687
161242
  originalContent: queueContext?.originalContent ?? "",
160688
- hasAttachments: queueContext?.hasAttachments ?? false
161243
+ hasAttachments: queueContext?.hasAttachments ?? false,
161244
+ targetAgentId: queueContext?.targetAgentId
160689
161245
  }]);
160690
161246
  log18.noise(`push: sessionId=${sessionId}, queueLength=${prev2.length + 1}`);
160691
161247
  this.emitQueueUpdated(sessionId);
@@ -160766,6 +161322,29 @@ var init_MessageQueue = __esm({
160766
161322
  });
160767
161323
  this.processingPromises.add(promise2);
160768
161324
  }
161325
+ scheduleRetry(sessionId, items, retryCount, retryDelay) {
161326
+ this.queueMap.set(sessionId, [...items, ...this.queueMap.get(sessionId) || []]);
161327
+ const nextRetryCount = retryCount + 1;
161328
+ const timerId = setTimeout(() => {
161329
+ if (this.isDestroyed) return;
161330
+ this.timers.delete(sessionId);
161331
+ this.processingSet.delete(sessionId);
161332
+ this.startConsume(sessionId, nextRetryCount);
161333
+ }, retryDelay);
161334
+ this.timers.set(sessionId, timerId);
161335
+ }
161336
+ async revokeMergedMessages(sessionId, items) {
161337
+ if (items.length <= 1) return;
161338
+ const mergedIds = items.slice(0, -1).map((item) => item.dbMessageId).filter((id) => Boolean(id));
161339
+ if (mergedIds.length === 0) return;
161340
+ await resolveMessageDeps().messageRepository.delete(mergedIds);
161341
+ eventBus.emit({
161342
+ type: "messages.revoked",
161343
+ sessionId,
161344
+ messageIds: mergedIds
161345
+ });
161346
+ log18.noise(`consume: cleaned up ${mergedIds.length} merged DB messages`);
161347
+ }
160769
161348
  async consume(sessionId, retryCount = 0) {
160770
161349
  if (this.isDestroyed) return;
160771
161350
  if (this.processingSet.has(sessionId)) {
@@ -160779,37 +161358,31 @@ var init_MessageQueue = __esm({
160779
161358
  }
160780
161359
  const items = queue.splice(0);
160781
161360
  const hasAttachments = items.some((item) => item.hasAttachments);
161361
+ const hasLLMMessageOverride = items.some((item) => item.llmMessages?.length);
160782
161362
  this.processingSet.add(sessionId);
160783
- log18.noise(`consume: start processing, sessionId=${sessionId}, merged=${items.length}, hasAttachments=${hasAttachments}`);
161363
+ log18.noise(`consume: start processing, sessionId=${sessionId}, merged=${items.length}, hasAttachments=${hasAttachments}, hasLLMMessageOverride=${hasLLMMessageOverride}`);
160784
161364
  this.emitQueueUpdated(sessionId);
160785
161365
  let shouldContinue = false;
160786
161366
  let willRetry = false;
160787
161367
  try {
160788
- if (hasAttachments) {
161368
+ if (hasAttachments || hasLLMMessageOverride) {
160789
161369
  const [current, ...rest] = items;
160790
161370
  if (rest.length > 0) {
160791
161371
  this.queueMap.set(sessionId, [...rest, ...this.queueMap.get(sessionId) || []]);
160792
161372
  }
160793
161373
  const result = await this.processor.processMessage(
160794
161374
  sessionId,
160795
- current.message,
161375
+ current.llmMessages ?? current.message,
160796
161376
  current.metadata,
160797
161377
  retryCount,
160798
- current.aiMessageId
161378
+ current.aiMessageId,
161379
+ current.targetAgentId
160799
161380
  );
160800
161381
  if (result.aiMessageId) {
160801
161382
  current.aiMessageId = result.aiMessageId;
160802
161383
  }
160803
161384
  if (result.shouldRetry && result.retryDelay) {
160804
- this.queueMap.set(sessionId, [current, ...this.queueMap.get(sessionId) || []]);
160805
- const nextRetryCount = retryCount + 1;
160806
- const timerId = setTimeout(() => {
160807
- if (this.isDestroyed) return;
160808
- this.timers.delete(sessionId);
160809
- this.processingSet.delete(sessionId);
160810
- this.startConsume(sessionId, nextRetryCount);
160811
- }, result.retryDelay);
160812
- this.timers.set(sessionId, timerId);
161385
+ this.scheduleRetry(sessionId, [current], retryCount, result.retryDelay);
160813
161386
  willRetry = true;
160814
161387
  return;
160815
161388
  }
@@ -160840,36 +161413,20 @@ ${stripped}`;
160840
161413
  mergedMessage,
160841
161414
  lastMetadata,
160842
161415
  retryCount,
160843
- items[0]?.aiMessageId
161416
+ items[0]?.aiMessageId,
161417
+ items[items.length - 1]?.targetAgentId
160844
161418
  );
160845
161419
  if (result.aiMessageId && items[0]) {
160846
161420
  items[0].aiMessageId = result.aiMessageId;
160847
161421
  }
160848
161422
  if (result.shouldRetry && result.retryDelay) {
160849
- this.queueMap.set(sessionId, [...items, ...this.queueMap.get(sessionId) || []]);
160850
- const nextRetryCount = retryCount + 1;
160851
- const timerId = setTimeout(() => {
160852
- if (this.isDestroyed) return;
160853
- this.timers.delete(sessionId);
160854
- this.processingSet.delete(sessionId);
160855
- this.startConsume(sessionId, nextRetryCount);
160856
- }, result.retryDelay);
160857
- this.timers.set(sessionId, timerId);
161423
+ this.scheduleRetry(sessionId, items, retryCount, result.retryDelay);
160858
161424
  willRetry = true;
160859
161425
  return;
160860
161426
  }
160861
- log18.noise(`consume: completed, sessionId=${sessionId}`);
160862
- const mergedIds = items.slice(0, -1).map((item) => item.dbMessageId).filter((id) => Boolean(id));
160863
- if (mergedIds.length > 0) {
160864
- await resolveMessageDeps().messageRepository.delete(mergedIds);
160865
- eventBus.emit({
160866
- type: "messages.revoked",
160867
- sessionId,
160868
- messageIds: mergedIds
160869
- });
160870
- log18.noise(`consume: cleaned up ${mergedIds.length} merged DB messages`);
160871
- }
160872
161427
  shouldContinue = (this.queueMap.get(sessionId)?.length ?? 0) > 0;
161428
+ log18.noise(`consume: completed, sessionId=${sessionId}`);
161429
+ await this.revokeMergedMessages(sessionId, items);
160873
161430
  }
160874
161431
  } finally {
160875
161432
  if (!willRetry) {
@@ -160959,6 +161516,12 @@ var init_message2 = __esm({
160959
161516
  });
160960
161517
 
160961
161518
  // src/core/message/MessagePublisher.ts
161519
+ function appendCurrentTime(message) {
161520
+ const timeTag = `
161521
+ <current_time>${formatCurrentTime()}</current_time>`;
161522
+ const content3 = typeof message.content === "string" ? message.content + timeTag : Array.isArray(message.content) ? [...message.content, { type: "text", text: timeTag }] : message.content;
161523
+ return { ...message, content: content3 };
161524
+ }
160962
161525
  var log19, MessagePublisherImpl, messagePublisher;
160963
161526
  var init_MessagePublisher = __esm({
160964
161527
  "src/core/message/MessagePublisher.ts"() {
@@ -160989,22 +161552,25 @@ var init_MessagePublisher = __esm({
160989
161552
  });
160990
161553
  this.emitAccepted(message, options2.clientRequestId);
160991
161554
  if (options2.targetAgentId) {
160992
- const userContent = blocksToUserContent(blocks);
160993
- const timeTag = `
160994
- <current_time>${formatCurrentTime()}</current_time>`;
160995
- const messageContent = typeof userContent === "string" ? userContent + timeTag : [...userContent, { type: "text", text: timeTag }];
161555
+ const llmMessages = options2.llmMessagesOverride ? options2.llmMessagesOverride.map(
161556
+ (llmMessage, index3, all2) => index3 === all2.length - 1 ? appendCurrentTime(llmMessage) : llmMessage
161557
+ ) : void 0;
161558
+ const userContent = options2.userContentOverride ?? blocksToUserContent(blocks);
161559
+ const fallbackMessage = appendCurrentTime({
161560
+ role: "user",
161561
+ content: userContent,
161562
+ metadata: { source: "human" }
161563
+ });
160996
161564
  messageQueue.push(
160997
161565
  sessionId,
160998
- {
160999
- role: "user",
161000
- content: messageContent,
161001
- metadata: { source: "human" }
161002
- },
161566
+ llmMessages?.[llmMessages.length - 1] ?? fallbackMessage,
161003
161567
  options2.metadata,
161004
161568
  {
161005
161569
  dbMessageId: message.id,
161006
161570
  originalContent: options2.originalContent ?? "",
161007
- hasAttachments: blocks.some((b2) => b2.type === "attachments")
161571
+ hasAttachments: blocks.some((b2) => b2.type === "attachments"),
161572
+ llmMessages,
161573
+ targetAgentId: options2.targetAgentId
161008
161574
  }
161009
161575
  );
161010
161576
  }
@@ -161066,7 +161632,12 @@ var init_MessagePublisher = __esm({
161066
161632
  },
161067
161633
  void 0,
161068
161634
  // system message 无 metadata
161069
- { dbMessageId: message.id, originalContent: "", hasAttachments: false }
161635
+ {
161636
+ dbMessageId: message.id,
161637
+ originalContent: "",
161638
+ hasAttachments: false,
161639
+ targetAgentId: options2.targetAgentId
161640
+ }
161070
161641
  // 保持 QueueItem 不变量
161071
161642
  );
161072
161643
  }
@@ -170430,7 +171001,7 @@ var init_scheduled_task_state = __esm({
170430
171001
  });
170431
171002
 
170432
171003
  // src/adapters/scheduler/scheduler.ts
170433
- var logger26, DEFAULT_TICK_INTERVAL_MS, DEFAULT_SHUTDOWN_TIMEOUT_MS, Scheduler;
171004
+ var logger28, DEFAULT_TICK_INTERVAL_MS, DEFAULT_SHUTDOWN_TIMEOUT_MS, Scheduler;
170434
171005
  var init_scheduler = __esm({
170435
171006
  "src/adapters/scheduler/scheduler.ts"() {
170436
171007
  "use strict";
@@ -170439,7 +171010,7 @@ var init_scheduler = __esm({
170439
171010
  init_logger();
170440
171011
  init_cron_time();
170441
171012
  init_scheduled_task_state();
170442
- logger26 = createLogger("Scheduler");
171013
+ logger28 = createLogger("Scheduler");
170443
171014
  DEFAULT_TICK_INTERVAL_MS = 3e4;
170444
171015
  DEFAULT_SHUTDOWN_TIMEOUT_MS = 1e4;
170445
171016
  Scheduler = class {
@@ -170461,17 +171032,17 @@ var init_scheduler = __esm({
170461
171032
  }
170462
171033
  registerExecutor(executor) {
170463
171034
  this.executors.set(executor.type, executor);
170464
- logger26.debug("Registered executor:", executor.type);
171035
+ logger28.debug("Registered executor:", executor.type);
170465
171036
  }
170466
171037
  /** Register an existing executor type under an additional name */
170467
171038
  registerExecutorAlias(alias, executorType) {
170468
171039
  const executor = this.executors.get(executorType);
170469
171040
  if (!executor) {
170470
- logger26.error(`Cannot alias unknown executor: ${executorType}`);
171041
+ logger28.error(`Cannot alias unknown executor: ${executorType}`);
170471
171042
  return;
170472
171043
  }
170473
171044
  this.executors.set(alias, executor);
170474
- logger26.debug("Aliased executor:", executorType, "\u2192", alias);
171045
+ logger28.debug("Aliased executor:", executorType, "\u2192", alias);
170475
171046
  }
170476
171047
  async loadAll() {
170477
171048
  if (!this.ctx || this.destroyed) return;
@@ -170482,7 +171053,7 @@ var init_scheduler = __esm({
170482
171053
  if (task.enabled) await this.ensureInitializedNextRunAt(task, Date.now());
170483
171054
  }
170484
171055
  this.start();
170485
- logger26.debug("Loaded", tasks.filter((task) => task.enabled).length, "enabled tasks");
171056
+ logger28.debug("Loaded", tasks.filter((task) => task.enabled).length, "enabled tasks");
170486
171057
  }
170487
171058
  schedule(task) {
170488
171059
  if (this.destroyed) return;
@@ -170492,7 +171063,7 @@ var init_scheduler = __esm({
170492
171063
  return;
170493
171064
  }
170494
171065
  this.start();
170495
- logger26.debug("Scheduled:", task.id, task.cronExpression);
171066
+ logger28.debug("Scheduled:", task.id, task.cronExpression);
170496
171067
  }
170497
171068
  nextRunAt(task, now2 = Date.now()) {
170498
171069
  return resolveNextRunAt(task, now2);
@@ -170538,7 +171109,7 @@ var init_scheduler = __esm({
170538
171109
  const now2 = Date.now();
170539
171110
  const tasks = await cronFileStore.findAllTasks();
170540
171111
  const dueTasks = tasks.filter((task) => task.enabled && this.isDue(task, now2));
170541
- if (dueTasks.length > 0) logger26.info(`Tick ${reason}: ${dueTasks.length} due task(s)`);
171112
+ if (dueTasks.length > 0) logger28.info(`Tick ${reason}: ${dueTasks.length} due task(s)`);
170542
171113
  await Promise.all(dueTasks.map((task) => this.startDueTask(task, now2)));
170543
171114
  } while (this.tickPending && !this.destroyed);
170544
171115
  }
@@ -170579,7 +171150,7 @@ var init_scheduler = __esm({
170579
171150
  const isEphemeral = task.id.startsWith("temp-");
170580
171151
  const startedAt = Date.now();
170581
171152
  try {
170582
- logger26.info("Executing:", task.id, `type=${task.type} ephemeral=${isEphemeral}`);
171153
+ logger28.info("Executing:", task.id, `type=${task.type} ephemeral=${isEphemeral}`);
170583
171154
  const result = await executor.execute(task, this.ctx);
170584
171155
  const completedAt = Date.now();
170585
171156
  if (!isEphemeral) {
@@ -170592,11 +171163,11 @@ var init_scheduler = __esm({
170592
171163
  output: result.output,
170593
171164
  error: result.error
170594
171165
  });
170595
- logger26.info("Execution recorded:", task.id, `status=${result.success ? "success" : "failed"} duration=${completedAt - startedAt}ms`);
171166
+ logger28.info("Execution recorded:", task.id, `status=${result.success ? "success" : "failed"} duration=${completedAt - startedAt}ms`);
170596
171167
  }
170597
171168
  if (this.destroyed) return result;
170598
171169
  this.ctx.eventBridge.broadcast(IPC_TASK_EXECUTION_EVENT, { taskId: task.id, result });
170599
- logger26.info("Completed:", task.id, `success=${result.success} duration=${completedAt - startedAt}ms`);
171170
+ logger28.info("Completed:", task.id, `success=${result.success} duration=${completedAt - startedAt}ms`);
170600
171171
  return result;
170601
171172
  } catch (err2) {
170602
171173
  const completedAt = Date.now();
@@ -170612,7 +171183,7 @@ var init_scheduler = __esm({
170612
171183
  status: "failed",
170613
171184
  error: error48
170614
171185
  }).then((record2) => {
170615
- logger26.info("Execution recorded:", task.id, `status=failed duration=${completedAt - startedAt}ms executionId=${record2.id}`);
171186
+ logger28.info("Execution recorded:", task.id, `status=failed duration=${completedAt - startedAt}ms executionId=${record2.id}`);
170616
171187
  }).catch((e) => {
170617
171188
  this.ctx?.logger.error("Failed to write execution record:", e);
170618
171189
  });
@@ -170621,7 +171192,7 @@ var init_scheduler = __esm({
170621
171192
  }
170622
171193
  }
170623
171194
  unschedule(id) {
170624
- logger26.debug("Unscheduled:", id);
171195
+ logger28.debug("Unscheduled:", id);
170625
171196
  }
170626
171197
  isRunning(id) {
170627
171198
  return this.runningTasks.has(id);
@@ -170664,7 +171235,7 @@ var init_scheduler = __esm({
170664
171235
  const fresh = await cronFileStore.findTaskById(task.id);
170665
171236
  if (this.destroyed) return;
170666
171237
  if (!fresh) {
170667
- logger26.warn("Due task disappeared before execution:", task.id);
171238
+ logger28.warn("Due task disappeared before execution:", task.id);
170668
171239
  return;
170669
171240
  }
170670
171241
  if (!fresh.enabled) return;
@@ -173628,9 +174199,9 @@ function initScheduler(ctx) {
173628
174199
  const previous3 = instance;
173629
174200
  instance = null;
173630
174201
  if (previous3) {
173631
- logger27.warn("Reinitializing scheduler, shutting down previous instance first");
174202
+ logger29.warn("Reinitializing scheduler, shutting down previous instance first");
173632
174203
  await previous3.shutdown().catch((error48) => {
173633
- logger27.warn("Previous scheduler shutdown failed; continuing reinitialization", error48);
174204
+ logger29.warn("Previous scheduler shutdown failed; continuing reinitialization", error48);
173634
174205
  });
173635
174206
  }
173636
174207
  const next2 = new Scheduler();
@@ -173642,7 +174213,7 @@ function initScheduler(ctx) {
173642
174213
  return next2;
173643
174214
  } catch (error48) {
173644
174215
  await next2.shutdown().catch((shutdownError) => {
173645
- logger27.warn("Failed to shut down scheduler after initialization failure", shutdownError);
174216
+ logger29.warn("Failed to shut down scheduler after initialization failure", shutdownError);
173646
174217
  });
173647
174218
  throw error48;
173648
174219
  }
@@ -173662,7 +174233,7 @@ function requireScheduler() {
173662
174233
  if (!instance) throw new Error("Scheduler is not initialized");
173663
174234
  return instance;
173664
174235
  }
173665
- var logger27, instance, lifecycle;
174236
+ var logger29, instance, lifecycle;
173666
174237
  var init_scheduler2 = __esm({
173667
174238
  "src/adapters/scheduler/index.ts"() {
173668
174239
  "use strict";
@@ -173672,7 +174243,7 @@ var init_scheduler2 = __esm({
173672
174243
  init_GroupMemoryUpdateExecutor();
173673
174244
  init_GroupDailyExtractionExecutor();
173674
174245
  init_logger();
173675
- logger27 = createLogger("scheduler-init");
174246
+ logger29 = createLogger("scheduler-init");
173676
174247
  instance = null;
173677
174248
  lifecycle = Promise.resolve();
173678
174249
  }
@@ -178717,7 +179288,7 @@ async function migrateGroupsToThreads() {
178717
179288
  const dbPath = getDbPath();
178718
179289
  const needed = await isMigrationNeeded();
178719
179290
  if (!needed) {
178720
- logger42.debug("Migration already done, skipping.");
179291
+ logger44.debug("Migration already done, skipping.");
178721
179292
  return;
178722
179293
  }
178723
179294
  const journalModeRows = await sequelize.query(
@@ -178726,7 +179297,7 @@ async function migrateGroupsToThreads() {
178726
179297
  );
178727
179298
  const journalMode = journalModeRows[0]?.journal_mode;
178728
179299
  if (journalMode !== "wal") {
178729
- logger42.warn(`Journal mode is "${journalMode}", switching to WAL for safety`);
179300
+ logger44.warn(`Journal mode is "${journalMode}", switching to WAL for safety`);
178730
179301
  await sequelize.query("PRAGMA journal_mode = WAL");
178731
179302
  }
178732
179303
  const beforeRows = await sequelize.query(
@@ -178734,13 +179305,13 @@ async function migrateGroupsToThreads() {
178734
179305
  { type: QueryTypes.SELECT }
178735
179306
  );
178736
179307
  const beforeTotal = beforeRows[0]?.total ?? 0;
178737
- logger42.debug(`Messages before migration: ${beforeTotal}`);
179308
+ logger44.debug(`Messages before migration: ${beforeTotal}`);
178738
179309
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
178739
179310
  const backupPath = `${dbPath}.bak.${timestamp}`;
178740
- logger42.debug(`Backing up database to ${backupPath}`);
179311
+ logger44.debug(`Backing up database to ${backupPath}`);
178741
179312
  await (0, import_promises36.copyFile)(dbPath, backupPath);
178742
179313
  try {
178743
- logger42.debug("Rebuilding messages table (removing FK)");
179314
+ logger44.debug("Rebuilding messages table (removing FK)");
178744
179315
  await sequelize.transaction(async (t) => {
178745
179316
  await sequelize.query(
178746
179317
  `CREATE TABLE messages_new (
@@ -178821,14 +179392,14 @@ async function migrateGroupsToThreads() {
178821
179392
  { transaction: t }
178822
179393
  );
178823
179394
  });
178824
- logger42.debug("Messages table rebuilt without FK");
179395
+ logger44.debug("Messages table rebuilt without FK");
178825
179396
  const groupConversations = await sequelize.query(
178826
179397
  `SELECT id, title, target_id, created_at, updated_at
178827
179398
  FROM conversations
178828
179399
  WHERE type = 'group'`,
178829
179400
  { type: QueryTypes.SELECT }
178830
179401
  );
178831
- logger42.debug(
179402
+ logger44.debug(
178832
179403
  `[migrateGroupsToThreads] Found ${groupConversations.length} group conversation(s) to migrate`
178833
179404
  );
178834
179405
  for (const conv of groupConversations) {
@@ -178840,14 +179411,14 @@ async function migrateGroupsToThreads() {
178840
179411
  const updatedAt = row.updated_at;
178841
179412
  const group = await groupFileStore.get(groupId);
178842
179413
  if (!group) {
178843
- logger42.warn(
179414
+ logger44.warn(
178844
179415
  `[migrateGroupsToThreads] Group directory not found for ${groupId}, skipping conversation ${threadId}`
178845
179416
  );
178846
179417
  continue;
178847
179418
  }
178848
179419
  const existingDefault = await sessionFileStore.findDefaultByGroupId(groupId);
178849
179420
  if (existingDefault) {
178850
- logger42.debug(
179421
+ logger44.debug(
178851
179422
  `[migrateGroupsToThreads] Group ${groupId} already has default thread ${existingDefault.id}, skipping creation (DB record will still be cleaned)`
178852
179423
  );
178853
179424
  continue;
@@ -178865,7 +179436,7 @@ async function migrateGroupsToThreads() {
178865
179436
  };
178866
179437
  await atomicWriteJson2(getThreadMetaPath(groupId, threadId), threadMeta);
178867
179438
  }
178868
- logger42.debug("Thread files created");
179439
+ logger44.debug("Thread files created");
178869
179440
  let groupsWithThread = 0;
178870
179441
  for (const conv of groupConversations) {
178871
179442
  const row = conv;
@@ -178887,10 +179458,10 @@ async function migrateGroupsToThreads() {
178887
179458
  `Thread file verification failed: expected ${groupConversations.length} groups with threads, found ${groupsWithThread}. Aborting before DB deletion.`
178888
179459
  );
178889
179460
  }
178890
- logger42.debug(`Verified ${groupsWithThread} group(s) with threads, safe to proceed with DB cleanup`);
179461
+ logger44.debug(`Verified ${groupsWithThread} group(s) with threads, safe to proceed with DB cleanup`);
178891
179462
  if (groupConversations.length > 0) {
178892
179463
  await sequelize.query("DELETE FROM conversations WHERE type = 'group'");
178893
- logger42.debug(
179464
+ logger44.debug(
178894
179465
  `Deleted ${groupConversations.length} group conversation(s) from DB`
178895
179466
  );
178896
179467
  }
@@ -178904,18 +179475,18 @@ async function migrateGroupsToThreads() {
178904
179475
  `Message count mismatch after migration: before=${beforeTotal}, after=${afterTotal}`
178905
179476
  );
178906
179477
  }
178907
- logger42.debug(
179478
+ logger44.debug(
178908
179479
  `[migrateGroupsToThreads] Migration completed successfully. Messages preserved: ${afterTotal}`
178909
179480
  );
178910
179481
  } catch (error48) {
178911
- logger42.error("Migration failed:", error48);
179482
+ logger44.error("Migration failed:", error48);
178912
179483
  if ((0, import_fs24.existsSync)(backupPath)) {
178913
- logger42.debug("Restoring database from backup...");
179484
+ logger44.debug("Restoring database from backup...");
178914
179485
  try {
178915
179486
  await (0, import_promises36.copyFile)(backupPath, dbPath);
178916
- logger42.debug("Database restored from backup");
179487
+ logger44.debug("Database restored from backup");
178917
179488
  } catch (restoreError) {
178918
- logger42.error(
179489
+ logger44.error(
178919
179490
  "[migrateGroupsToThreads] CRITICAL: Backup restore also failed:",
178920
179491
  restoreError
178921
179492
  );
@@ -178929,7 +179500,7 @@ async function rollbackThreads() {
178929
179500
  const dbPath = getDbPath();
178930
179501
  const groupsRoot = (0, import_path97.join)(getKaiRoot(), "groups");
178931
179502
  if (!(0, import_fs24.existsSync)(groupsRoot)) {
178932
- logger42.debug("No groups directory, nothing to rollback.");
179503
+ logger44.debug("No groups directory, nothing to rollback.");
178933
179504
  return;
178934
179505
  }
178935
179506
  const { readdir: readdir18 } = await import("fs/promises");
@@ -178938,7 +179509,7 @@ async function rollbackThreads() {
178938
179509
  (g2) => (0, import_fs24.existsSync)((0, import_path97.join)(getGroupDir(g2), "threads"))
178939
179510
  );
178940
179511
  if (!hasThreads) {
178941
- logger42.debug("No threads directories found, nothing to rollback.");
179512
+ logger44.debug("No threads directories found, nothing to rollback.");
178942
179513
  return;
178943
179514
  }
178944
179515
  const beforeRows = await sequelize.query(
@@ -178946,13 +179517,13 @@ async function rollbackThreads() {
178946
179517
  { type: QueryTypes.SELECT }
178947
179518
  );
178948
179519
  const beforeTotal = beforeRows[0]?.total ?? 0;
178949
- logger42.debug(`Messages before rollback: ${beforeTotal}`);
179520
+ logger44.debug(`Messages before rollback: ${beforeTotal}`);
178950
179521
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
178951
179522
  const backupPath = `${dbPath}.bak.rollback.${timestamp}`;
178952
- logger42.debug(`Backing up database to ${backupPath}`);
179523
+ logger44.debug(`Backing up database to ${backupPath}`);
178953
179524
  await (0, import_promises36.copyFile)(dbPath, backupPath);
178954
179525
  try {
178955
- logger42.debug("Restoring group conversations from thread files");
179526
+ logger44.debug("Restoring group conversations from thread files");
178956
179527
  let restored = 0;
178957
179528
  for (const groupId of dirs) {
178958
179529
  const threadsDir = (0, import_path97.join)(getGroupDir(groupId), "threads");
@@ -178975,7 +179546,7 @@ async function rollbackThreads() {
178975
179546
  );
178976
179547
  const count = orphanCount[0]?.count ?? 0;
178977
179548
  if (count > 0) {
178978
- logger42.warn(
179549
+ logger44.warn(
178979
179550
  `Non-default thread "${threadId}" has ${count} message(s) that will become orphans after FK restore`
178980
179551
  );
178981
179552
  }
@@ -178997,10 +179568,10 @@ async function rollbackThreads() {
178997
179568
  restored++;
178998
179569
  }
178999
179570
  }
179000
- logger42.debug(
179571
+ logger44.debug(
179001
179572
  `[rollbackThreads] Restored ${restored} group conversation(s) to DB`
179002
179573
  );
179003
- logger42.debug("Rebuilding messages table (restoring FK)");
179574
+ logger44.debug("Rebuilding messages table (restoring FK)");
179004
179575
  await sequelize.transaction(async (t) => {
179005
179576
  await sequelize.query(
179006
179577
  `CREATE TABLE messages_rollback (
@@ -179090,8 +179661,8 @@ async function rollbackThreads() {
179090
179661
  `Message count mismatch after FK restore: before=${beforeTotal}, after=${afterFkTotal}`
179091
179662
  );
179092
179663
  }
179093
- logger42.debug("Messages table rebuilt with FK restored");
179094
- logger42.debug("Removing threads directories");
179664
+ logger44.debug("Messages table rebuilt with FK restored");
179665
+ logger44.debug("Removing threads directories");
179095
179666
  for (const groupId of dirs) {
179096
179667
  const threadsDir = (0, import_path97.join)(getGroupDir(groupId), "threads");
179097
179668
  if ((0, import_fs24.existsSync)(threadsDir)) {
@@ -179108,18 +179679,18 @@ async function rollbackThreads() {
179108
179679
  `Message count mismatch after rollback: before=${beforeTotal}, after=${finalTotal}`
179109
179680
  );
179110
179681
  }
179111
- logger42.debug(
179682
+ logger44.debug(
179112
179683
  `[rollbackThreads] Rollback completed successfully. Messages preserved: ${finalTotal}`
179113
179684
  );
179114
179685
  } catch (error48) {
179115
- logger42.error("Rollback failed:", error48);
179686
+ logger44.error("Rollback failed:", error48);
179116
179687
  if ((0, import_fs24.existsSync)(backupPath)) {
179117
- logger42.debug("Restoring database from backup...");
179688
+ logger44.debug("Restoring database from backup...");
179118
179689
  try {
179119
179690
  await (0, import_promises36.copyFile)(backupPath, dbPath);
179120
- logger42.debug("Database restored from backup");
179691
+ logger44.debug("Database restored from backup");
179121
179692
  } catch (restoreError) {
179122
- logger42.error(
179693
+ logger44.error(
179123
179694
  "[rollbackThreads] CRITICAL: Backup restore also failed:",
179124
179695
  restoreError
179125
179696
  );
@@ -179128,7 +179699,7 @@ async function rollbackThreads() {
179128
179699
  throw error48;
179129
179700
  }
179130
179701
  }
179131
- var import_path97, import_fs24, import_promises36, logger42;
179702
+ var import_path97, import_fs24, import_promises36, logger44;
179132
179703
  var init_threads_migration = __esm({
179133
179704
  "src/adapters/db/migration/threads-migration.ts"() {
179134
179705
  "use strict";
@@ -179141,7 +179712,7 @@ var init_threads_migration = __esm({
179141
179712
  init_logger();
179142
179713
  init_group_file_store();
179143
179714
  init_session_file_store();
179144
- logger42 = createLogger("threads-migration");
179715
+ logger44 = createLogger("threads-migration");
179145
179716
  }
179146
179717
  });
179147
179718
 
@@ -179219,19 +179790,19 @@ async function migrateTasks(sequelize) {
179219
179790
  try {
179220
179791
  const task = rowToTask(row, conversationMap);
179221
179792
  if (!task) {
179222
- logger43.warn(`Skip task ${row.id}: cannot determine type from ${row.type}`);
179793
+ logger45.warn(`Skip task ${row.id}: cannot determine type from ${row.type}`);
179223
179794
  continue;
179224
179795
  }
179225
179796
  const dir = getTaskDir2(task);
179226
179797
  const filePath = (0, import_path98.join)(dir, `${task.id}.json`);
179227
179798
  if ((0, import_fs25.existsSync)(filePath)) {
179228
- logger43.debug(`Task ${task.id} already exists in filesystem, skipping`);
179799
+ logger45.debug(`Task ${task.id} already exists in filesystem, skipping`);
179229
179800
  continue;
179230
179801
  }
179231
179802
  await writeJsonAtomic(filePath, task);
179232
179803
  migrated++;
179233
179804
  } catch (err2) {
179234
- logger43.error(`Failed to migrate task ${row.id}:`, err2);
179805
+ logger45.error(`Failed to migrate task ${row.id}:`, err2);
179235
179806
  }
179236
179807
  }
179237
179808
  return migrated;
@@ -179274,7 +179845,7 @@ async function migrateExecutions(sequelize) {
179274
179845
  migrated++;
179275
179846
  }
179276
179847
  } catch (err2) {
179277
- logger43.error(`Failed to migrate executions for task ${taskId}:`, err2);
179848
+ logger45.error(`Failed to migrate executions for task ${taskId}:`, err2);
179278
179849
  }
179279
179850
  }
179280
179851
  return migrated;
@@ -179295,7 +179866,7 @@ async function loadConversationMap(sequelize) {
179295
179866
  map3.set(row.id, row);
179296
179867
  }
179297
179868
  } catch (err2) {
179298
- logger43.warn("Failed to load conversation map for cron migration:", err2);
179869
+ logger45.warn("Failed to load conversation map for cron migration:", err2);
179299
179870
  }
179300
179871
  return map3;
179301
179872
  }
@@ -179383,9 +179954,9 @@ async function dropLegacyTables(sequelize) {
179383
179954
  try {
179384
179955
  await sequelize.query("DROP TABLE IF EXISTS task_executions");
179385
179956
  await sequelize.query("DROP TABLE IF EXISTS scheduled_tasks");
179386
- logger43.debug("Dropped legacy scheduled_tasks/task_executions tables");
179957
+ logger45.debug("Dropped legacy scheduled_tasks/task_executions tables");
179387
179958
  } catch (err2) {
179388
- logger43.warn("Failed to drop legacy cron tables (non-fatal):", err2);
179959
+ logger45.warn("Failed to drop legacy cron tables (non-fatal):", err2);
179389
179960
  }
179390
179961
  }
179391
179962
  async function migrateCronSqliteToFileStore() {
@@ -179396,16 +179967,16 @@ async function migrateCronSqliteToFileStore() {
179396
179967
  { type: QueryTypes.SELECT }
179397
179968
  );
179398
179969
  if (tables.length === 0) {
179399
- logger43.debug("No scheduled_tasks/task_executions tables found, skipping cron migration");
179970
+ logger45.debug("No scheduled_tasks/task_executions tables found, skipping cron migration");
179400
179971
  return;
179401
179972
  }
179402
- logger43.debug("Starting cron SQLite \u2192 filesystem migration");
179973
+ logger45.debug("Starting cron SQLite \u2192 filesystem migration");
179403
179974
  const tasksMigrated = await migrateTasks(sequelize);
179404
179975
  const execsMigrated = await migrateExecutions(sequelize);
179405
- logger43.debug(`Migrated ${tasksMigrated} tasks and ${execsMigrated} executions to filesystem`);
179976
+ logger45.debug(`Migrated ${tasksMigrated} tasks and ${execsMigrated} executions to filesystem`);
179406
179977
  await dropLegacyTables(sequelize);
179407
179978
  }
179408
- var import_path98, import_promises37, import_fs25, logger43, CRON_DIR2;
179979
+ var import_path98, import_promises37, import_fs25, logger45, CRON_DIR2;
179409
179980
  var init_cron_sqlite_migration = __esm({
179410
179981
  "src/adapters/db/migration/cron-sqlite-migration.ts"() {
179411
179982
  "use strict";
@@ -179415,7 +179986,7 @@ var init_cron_sqlite_migration = __esm({
179415
179986
  import_fs25 = require("fs");
179416
179987
  init_config();
179417
179988
  init_logger();
179418
- logger43 = createLogger("cron-sqlite-migration");
179989
+ logger45 = createLogger("cron-sqlite-migration");
179419
179990
  CRON_DIR2 = "cron";
179420
179991
  }
179421
179992
  });
@@ -228534,6 +229105,7 @@ var import_aibot_node_sdk = __toESM(require_index_cjs());
228534
229105
  init_logger();
228535
229106
  var log = createLogger("WeComBotClient");
228536
229107
  var CONNECT_TIMEOUT_MS = 2e4;
229108
+ var SEND_TIMEOUT_MS = 1e4;
228537
229109
  var INITIAL_RECONNECT_DELAY_MS = 5e3;
228538
229110
  var MAX_RECONNECT_DELAY_MS = 6e4;
228539
229111
  function getRuntimeVoiceContent(body) {
@@ -228747,41 +229319,44 @@ var WeComBotClient = class {
228747
229319
  async sendMarkdown(chatId, content3, _chatType) {
228748
229320
  this.assertCanSend();
228749
229321
  if (!this.sdk) throw new Error("Client not initialized");
228750
- await this.sdk.sendMessage(chatId, {
229322
+ await this.withSendTimeout("sendMessage", this.sdk.sendMessage(chatId, {
228751
229323
  msgtype: "markdown",
228752
229324
  markdown: { content: content3 }
228753
- });
229325
+ }));
228754
229326
  }
228755
229327
  async uploadMedia(fileBuffer, options2) {
228756
229328
  this.assertCanSend();
228757
229329
  if (!this.sdk) throw new Error("Client not initialized");
228758
- const result = await this.sdk.uploadMedia(fileBuffer, options2);
229330
+ const result = await this.withSendTimeout("uploadMedia", this.sdk.uploadMedia(fileBuffer, options2));
228759
229331
  return { media_id: result.media_id };
228760
229332
  }
228761
229333
  async sendMediaMessage(chatId, mediaType, mediaId) {
228762
229334
  this.assertCanSend();
228763
229335
  if (!this.sdk) throw new Error("Client not initialized");
228764
- await this.sdk.sendMediaMessage(chatId, mediaType, mediaId);
229336
+ await this.withSendTimeout("sendMediaMessage", this.sdk.sendMediaMessage(chatId, mediaType, mediaId));
228765
229337
  }
228766
229338
  // ── 流式回复(aibot_respond_msg,被动回复通道) ──────────
228767
229339
  /** 开始流式回复(空内容占位) */
228768
229340
  async replyStreamStart(frame, streamId) {
228769
229341
  this.assertCanSend();
228770
229342
  if (!this.sdk) throw new Error("Client not initialized");
228771
- await this.sdk.replyStream(frame, streamId, "", false);
229343
+ await this.withSendTimeout("replyStreamStart", this.sdk.replyStream(frame, streamId, "", false));
228772
229344
  }
228773
229345
  /** 刷新流式内容(累积全文,非增量)。跳过时返回 'skipped' */
228774
229346
  async replyStreamUpdate(frame, streamId, content3) {
228775
229347
  this.assertCanSend();
228776
229348
  if (!this.sdk) throw new Error("Client not initialized");
228777
- const result = await this.sdk.replyStreamNonBlocking(frame, streamId, content3, false);
229349
+ const result = await this.withSendTimeout(
229350
+ "replyStreamUpdate",
229351
+ this.sdk.replyStreamNonBlocking(frame, streamId, content3, false)
229352
+ );
228778
229353
  return result === "skipped" ? "skipped" : "sent";
228779
229354
  }
228780
229355
  /** 结束流式回复(最终内容 + finish=true) */
228781
229356
  async replyStreamFinish(frame, streamId, content3) {
228782
229357
  this.assertCanSend();
228783
229358
  if (!this.sdk) throw new Error("Client not initialized");
228784
- await this.sdk.replyStream(frame, streamId, content3, true);
229359
+ await this.withSendTimeout("replyStreamFinish", this.sdk.replyStream(frame, streamId, content3, true));
228785
229360
  }
228786
229361
  // ── 事件订阅(和旧接口保持一致) ────────────────────
228787
229362
  onMessage(cb) {
@@ -228954,6 +229529,21 @@ var WeComBotClient = class {
228954
229529
  throw new Error(availability.message);
228955
229530
  }
228956
229531
  }
229532
+ async withSendTimeout(label, promise2, timeoutMs = SEND_TIMEOUT_MS) {
229533
+ let timer;
229534
+ try {
229535
+ return await Promise.race([
229536
+ promise2,
229537
+ new Promise((_5, reject) => {
229538
+ timer = setTimeout(() => {
229539
+ reject(new Error(`${label} timeout after ${timeoutMs}ms`));
229540
+ }, timeoutMs);
229541
+ })
229542
+ ]);
229543
+ } finally {
229544
+ if (timer) clearTimeout(timer);
229545
+ }
229546
+ }
228957
229547
  };
228958
229548
  function extractQuoteText(quote) {
228959
229549
  if (!quote) return void 0;
@@ -231139,6 +231729,7 @@ var import_promises20 = require("node:fs/promises");
231139
231729
  init_config();
231140
231730
  var log20 = createLogger("ChannelManager");
231141
231731
  var PASSIVE_STREAM_EXPIRY_MS = 9 * 60 * 1e3;
231732
+ var WECOM_REPLY_RUN_TIMEOUT_MS = 5 * 60 * 1e3;
231142
231733
  var ChannelManager = class {
231143
231734
  adapters = /* @__PURE__ */ new Map();
231144
231735
  configStore;
@@ -231427,6 +232018,7 @@ var ChannelManager = class {
231427
232018
  chatId: message.conversation.id,
231428
232019
  chatType: message.conversation.kind === "group" ? "group" : "single",
231429
232020
  channelType: message.channelType,
232021
+ sessionId: directSession.id,
231430
232022
  streamFrame: message.extra?.frame,
231431
232023
  streamId: message.extra?.frame ? genId(ID_TYPE.STREAM) : void 0
231432
232024
  });
@@ -231448,6 +232040,7 @@ var ChannelManager = class {
231448
232040
  chatId: message.conversation.id,
231449
232041
  chatType: message.conversation.kind === "group" ? "group" : "single",
231450
232042
  channelType: message.channelType,
232043
+ sessionId: session.id,
231451
232044
  streamFrame: message.extra?.frame,
231452
232045
  streamId: message.extra?.frame ? genId(ID_TYPE.STREAM) : void 0
231453
232046
  });
@@ -231551,6 +232144,7 @@ var ChannelManager = class {
231551
232144
  await adapter2.stream.start(pending.streamFrame, pending.streamId);
231552
232145
  pending.streamStarted = true;
231553
232146
  pending.streamStartedAt = Date.now();
232147
+ this.scheduleWeComReplyTimeout(runId, pending);
231554
232148
  log20.noise(`stream started: runId=${runId}, streamId=${pending.streamId}`);
231555
232149
  } catch (err2) {
231556
232150
  pending.streamStarted = false;
@@ -231559,6 +232153,22 @@ var ChannelManager = class {
231559
232153
  );
231560
232154
  }
231561
232155
  }
232156
+ scheduleWeComReplyTimeout(runId, pending) {
232157
+ if (pending.channelType !== "wecom-bot" || !pending.sessionId) return;
232158
+ setTimeout(() => {
232159
+ const activeRunId = this.replyState.getActiveRunId(pending.sessionId);
232160
+ if (activeRunId !== runId || !pending.streamStarted || pending.streamExpired || pending.timeoutNotified) return;
232161
+ pending.timeoutNotified = true;
232162
+ log20.warn(`wecom reply run timeout, notify only session=${pending.sessionId}, runId=${runId}`);
232163
+ void this.finishStartedStream(
232164
+ pending.sessionId,
232165
+ runId,
232166
+ pending,
232167
+ "\u26A0\uFE0F \u56DE\u590D\u65F6\u95F4\u8F83\u957F\uFF0C\u4EFB\u52A1\u4ECD\u5728\u7EE7\u7EED\u3002\u5B8C\u6210\u540E\u4F1A\u7EE7\u7EED\u53D1\u9001\u7ED3\u679C\u3002",
232168
+ { ignoreTimeoutNotice: true }
232169
+ );
232170
+ }, WECOM_REPLY_RUN_TIMEOUT_MS).unref?.();
232171
+ }
231562
232172
  /** message.block.updated → 刷新流式内容 */
231563
232173
  async handleBlockUpdated(sessionId, block) {
231564
232174
  if (block.type !== "text" || !block.text) return;
@@ -231568,6 +232178,7 @@ var ChannelManager = class {
231568
232178
  if (!pendings?.length) return;
231569
232179
  for (const pending of pendings) {
231570
232180
  if (!pending.streamStarted) continue;
232181
+ if (pending.timeoutNotified) continue;
231571
232182
  if (this.isStreamExpired(pending)) {
231572
232183
  pending.streamExpired = true;
231573
232184
  continue;
@@ -231601,46 +232212,78 @@ var ChannelManager = class {
231601
232212
  log20.warn(
231602
232213
  `no assistant reply found for channel outbound: ${sessionId}, messageId=${messageId}`
231603
232214
  );
232215
+ await this.finishStartedStreams(sessionId, runId, pendings, "\u26A0\uFE0F \u56DE\u590D\u5B8C\u6210\uFF0C\u4F46\u672A\u627E\u5230\u53EF\u53D1\u9001\u5185\u5BB9");
231604
232216
  return;
231605
232217
  }
231606
232218
  const text7 = assistantMsg.blocks.filter((b2) => b2.type === "text").map((b2) => b2.text).join("");
231607
232219
  if (!text7) {
231608
- log20.info(`assistant reply has no text, skip text outbound: ${sessionId}`);
232220
+ log20.info(`assistant reply has no text, finish stream without text outbound: ${sessionId}`);
232221
+ await this.finishStartedStreams(sessionId, runId, pendings, "");
231609
232222
  return;
231610
232223
  }
231611
232224
  for (const pending of pendings) {
231612
- await this.sendFilesFromBlocks(pending, assistantMsg.blocks);
231613
- if (pending.streamStarted && !this.isStreamExpired(pending)) {
231614
- const adapter2 = this.adapters.get(pending.connectionId);
231615
- if (adapter2?.stream) {
231616
- try {
231617
- await adapter2.stream.finish(pending.streamFrame, pending.streamId, text7);
231618
- log20.info(`stream finished: sessionId=${sessionId}`);
231619
- continue;
231620
- } catch (err2) {
231621
- if (!this.isPassiveStreamExpiredError(err2)) throw err2;
231622
- pending.streamExpired = true;
231623
- log20.warn(`stream finish expired, fallback to send: ${err2 instanceof Error ? err2.message : String(err2)}`);
231624
- }
231625
- }
231626
- }
231627
- const reply = {
231628
- connectionId: pending.connectionId,
231629
- sessionId: pending.chatId,
231630
- chatType: pending.chatType,
231631
- text: text7
231632
- };
231633
- const result = await this.send(reply);
231634
- if (result.ok) {
231635
- log20.info(`channel reply sent: sessionId=${sessionId}`);
231636
- } else {
231637
- log20.error(`channel reply failed: ${result.code} ${result.message}`);
232225
+ try {
232226
+ await this.sendFilesFromBlocks(pending, assistantMsg.blocks);
232227
+ await this.sendTextReply(sessionId, pending, text7);
232228
+ } catch (err2) {
232229
+ log20.error(`channel reply failed for ${pending.connectionId}/${pending.chatId}:`, err2);
232230
+ await this.finishStartedStream(sessionId, runId, pending, "\u26A0\uFE0F \u56DE\u590D\u51FA\u9519");
231638
232231
  }
231639
232232
  }
231640
232233
  } catch (error48) {
231641
232234
  log20.error(`channel reply error:`, error48);
231642
232235
  }
231643
232236
  }
232237
+ async sendTextReply(sessionId, pending, text7) {
232238
+ if (pending.streamStarted && !pending.timeoutNotified && !this.isStreamExpired(pending)) {
232239
+ const adapter2 = this.adapters.get(pending.connectionId);
232240
+ if (adapter2?.stream) {
232241
+ try {
232242
+ await adapter2.stream.finish(pending.streamFrame, pending.streamId, text7);
232243
+ log20.info(`stream finished: sessionId=${sessionId}`);
232244
+ return;
232245
+ } catch (err2) {
232246
+ if (!this.isPassiveStreamExpiredError(err2)) throw err2;
232247
+ pending.streamExpired = true;
232248
+ log20.warn(`stream finish expired, fallback to send: ${err2 instanceof Error ? err2.message : String(err2)}`);
232249
+ }
232250
+ }
232251
+ }
232252
+ const reply = {
232253
+ connectionId: pending.connectionId,
232254
+ sessionId: pending.chatId,
232255
+ chatType: pending.chatType,
232256
+ text: text7
232257
+ };
232258
+ const result = await this.send(reply);
232259
+ if (result.ok) {
232260
+ log20.info(`channel reply sent: sessionId=${sessionId}`);
232261
+ } else {
232262
+ throw new Error(`channel reply failed: ${result.code} ${result.message}`);
232263
+ }
232264
+ }
232265
+ async finishStartedStreams(sessionId, runId, pendings, content3) {
232266
+ for (const pending of pendings) {
232267
+ await this.finishStartedStream(sessionId, runId, pending, content3);
232268
+ }
232269
+ }
232270
+ async finishStartedStream(sessionId, runId, pending, content3, options2 = {}) {
232271
+ if (pending.timeoutNotified && !options2.ignoreTimeoutNotice) return;
232272
+ if (!pending.streamStarted || this.isStreamExpired(pending)) return;
232273
+ const adapter2 = this.adapters.get(pending.connectionId);
232274
+ if (!adapter2?.stream) return;
232275
+ try {
232276
+ await adapter2.stream.finish(pending.streamFrame, pending.streamId, content3);
232277
+ log20.info(`stream finished: sessionId=${sessionId}, runId=${runId}`);
232278
+ } catch (err2) {
232279
+ if (this.isPassiveStreamExpiredError(err2)) {
232280
+ pending.streamExpired = true;
232281
+ }
232282
+ log20.warn(
232283
+ `stream finish failed: sessionId=${sessionId}, runId=${runId}, error=${err2 instanceof Error ? err2.message : String(err2)}`
232284
+ );
232285
+ }
232286
+ }
231644
232287
  isStreamExpired(pending) {
231645
232288
  if (pending.streamExpired) return true;
231646
232289
  if (!pending.streamStartedAt) return false;
@@ -231653,20 +232296,17 @@ var ChannelManager = class {
231653
232296
  async cleanupRun(sessionId, runId) {
231654
232297
  const pendings = this.replyState.cleanupRun(sessionId, runId);
231655
232298
  if (pendings?.length) {
232299
+ await this.finishStartedStreams(sessionId, runId, pendings, "\u26A0\uFE0F \u56DE\u590D\u51FA\u9519");
231656
232300
  for (const pending of pendings) {
231657
- if (!pending.streamStarted) continue;
231658
- const adapter2 = this.adapters.get(pending.connectionId);
231659
- if (adapter2?.stream) {
231660
- try {
231661
- await adapter2.stream.finish(pending.streamFrame, pending.streamId, "\u26A0\uFE0F \u56DE\u590D\u51FA\u9519");
231662
- log20.info(
231663
- `stream finished (run cleanup): sessionId=${sessionId}, runId=${runId}`
231664
- );
231665
- } catch (err2) {
231666
- log20.warn(
231667
- `stream finish failed during cleanup: ${err2 instanceof Error ? err2.message : String(err2)}`
231668
- );
231669
- }
232301
+ if (pending.streamStarted) continue;
232302
+ const result = await this.send({
232303
+ connectionId: pending.connectionId,
232304
+ sessionId: pending.chatId,
232305
+ chatType: pending.chatType,
232306
+ text: "\u26A0\uFE0F \u56DE\u590D\u51FA\u9519"
232307
+ });
232308
+ if (!result.ok) {
232309
+ log20.error(`channel failure reply failed: ${result.code} ${result.message}`);
231670
232310
  }
231671
232311
  }
231672
232312
  }
@@ -231794,7 +232434,7 @@ init_scheduler2();
231794
232434
 
231795
232435
  // src/shared/mention-directive.ts
231796
232436
  init_logger();
231797
- var logger28 = createLogger("MentionDirective");
232437
+ var logger30 = createLogger("MentionDirective");
231798
232438
  function normalizeMentionDirective(metadata) {
231799
232439
  const mentionIds = Array.from(new Set((metadata?.mentions ?? []).filter(Boolean)));
231800
232440
  if (metadata?.broadcast && "all" in metadata.broadcast && metadata.broadcast.all) {
@@ -231805,7 +232445,7 @@ function normalizeMentionDirective(metadata) {
231805
232445
  };
231806
232446
  }
231807
232447
  if (metadata?.broadcast && mentionIds.length <= 1 && !("all" in metadata.broadcast)) {
231808
- logger28.warn("Broadcast metadata conflicts with mention count, prefer single/none semantics", {
232448
+ logger30.warn("Broadcast metadata conflicts with mention count, prefer single/none semantics", {
231809
232449
  mentions: mentionIds,
231810
232450
  broadcast: metadata.broadcast
231811
232451
  });
@@ -231871,6 +232511,7 @@ init_conversation_event_bus();
231871
232511
  init_logger();
231872
232512
  init_message_deps();
231873
232513
  init_id2();
232514
+ init_skill();
231874
232515
  var log21 = createLogger("SlashCommand");
231875
232516
  var COMPACT_RUNNING_TEXT = "\u23F3 \u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587...";
231876
232517
  var COMPACT_COMPLETED_TEXT = "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29";
@@ -231891,6 +232532,41 @@ function parseSlashCommand(content3) {
231891
232532
  args: match[2]?.trim() ?? ""
231892
232533
  };
231893
232534
  }
232535
+ function parseSkillInvocation(content3) {
232536
+ const raw = content3.trim();
232537
+ if (!raw.startsWith("/")) return null;
232538
+ const match = raw.match(/^\/([^\s/]+)(?:\s+([\s\S]*))?$/);
232539
+ if (!match) return null;
232540
+ if (raw.startsWith(`/${match[1]}/`)) return null;
232541
+ const name21 = match[1];
232542
+ if (KNOWN_COMMANDS.has(name21)) return null;
232543
+ if (validateSkillName(name21)) return null;
232544
+ return {
232545
+ skillName: name21,
232546
+ raw,
232547
+ input: match[2]?.trim() ?? ""
232548
+ };
232549
+ }
232550
+ function buildSkillLLMMessagesOverride(invocation, skillContent) {
232551
+ if (!invocation || !skillContent) return void 0;
232552
+ const messages = [
232553
+ {
232554
+ role: "user",
232555
+ content: `The following skill is loaded for this request only:
232556
+
232557
+ ${skillContent}`,
232558
+ metadata: { source: "runtime-skill", skillName: invocation.skillName }
232559
+ }
232560
+ ];
232561
+ if (invocation.input) {
232562
+ messages.push({
232563
+ role: "user",
232564
+ content: invocation.input,
232565
+ metadata: { source: "human" }
232566
+ });
232567
+ }
232568
+ return messages;
232569
+ }
231894
232570
  async function publishUserMessageWithSlashCommandHandling(sessionId, blocks, content3, publishOptions, handlers) {
231895
232571
  const hasAttachments = blocks.some((block) => block.type === "attachments");
231896
232572
  const invocation = hasAttachments ? null : parseSlashCommand(content3);
@@ -231969,6 +232645,7 @@ async function updateLocalSystemMessage(sessionId, messageId, blockId, text7) {
231969
232645
  }
231970
232646
 
231971
232647
  // src/electron/main/handlers/chat-handlers.ts
232648
+ init_skill();
231972
232649
  init_group_file_store();
231973
232650
  init_agent_file_store();
231974
232651
  init_message2();
@@ -232328,7 +233005,7 @@ function createManualCompactionWorkerId(agentId, sessionId) {
232328
233005
  }
232329
233006
 
232330
233007
  // src/core/context-compaction/manual/ManualContextCompactionUseCase.ts
232331
- var logger29 = createLogger("ManualContextCompactionUseCase");
233008
+ var logger31 = createLogger("ManualContextCompactionUseCase");
232332
233009
  var MANUAL_KEEP_RECENT_COUNT = 0;
232333
233010
  var MAX_TIPS_LENGTH = 500;
232334
233011
  var ManualContextCompactionUseCase = class {
@@ -232348,11 +233025,11 @@ var ManualContextCompactionUseCase = class {
232348
233025
  const idType = await this.resolveSessionIdType(input.sessionId);
232349
233026
  const sessionId = idType.sessionId;
232350
233027
  if (this.isSessionRunning(sessionId)) {
232351
- logger29.warn(`compact: agent is running for ${sessionId}, rejecting`);
233028
+ logger31.warn(`compact: agent is running for ${sessionId}, rejecting`);
232352
233029
  throw new Error("Agent is running, please wait or stop before compacting");
232353
233030
  }
232354
233031
  if (this.compactingSessions.has(sessionId)) {
232355
- logger29.warn(`compact: already compacting ${sessionId}`);
233032
+ logger31.warn(`compact: already compacting ${sessionId}`);
232356
233033
  throw new Error("Already compacting, please wait");
232357
233034
  }
232358
233035
  this.compactingSessions.add(sessionId);
@@ -232361,18 +233038,18 @@ var ManualContextCompactionUseCase = class {
232361
233038
  const cleanTips = input.tips?.trim().slice(0, MAX_TIPS_LENGTH) || void 0;
232362
233039
  const agentId = await this.resolveCompactionAgentId(idType, input.sessionId);
232363
233040
  if (!agentId) {
232364
- logger29.warn(`compact: no agent for ${sessionId}`);
233041
+ logger31.warn(`compact: no agent for ${sessionId}`);
232365
233042
  return null;
232366
233043
  }
232367
233044
  const { agentRepository } = this.resolveMessageDeps();
232368
233045
  const agentConfig = await agentRepository.readConfig(agentId);
232369
233046
  if (!agentConfig) {
232370
- logger29.warn(`compact: no agent config for agent ${agentId}`);
233047
+ logger31.warn(`compact: no agent config for agent ${agentId}`);
232371
233048
  return null;
232372
233049
  }
232373
233050
  const messages = await this.loadContextMessages(idType, agentId);
232374
233051
  if (messages.length === 0) {
232375
- logger29.debug(`compact: no messages to compact for ${input.sessionId}`);
233052
+ logger31.debug(`compact: no messages to compact for ${input.sessionId}`);
232376
233053
  return null;
232377
233054
  }
232378
233055
  const { modelSettings, primaryModel, maxOutputTokens, languageModelFactory } = this.resolveModelSettings(agentId, agentConfig);
@@ -232436,7 +233113,7 @@ var ManualContextCompactionUseCase = class {
232436
233113
  afterTokens,
232437
233114
  durationMs: Date.now() - startedAt
232438
233115
  });
232439
- logger29.info(`compact: compressed ${messages.length} messages for ${sessionId}`);
233116
+ logger31.info(`compact: compressed ${messages.length} messages for ${sessionId}`);
232440
233117
  return {
232441
233118
  sessionId: idType.sessionId,
232442
233119
  agentId,
@@ -232633,7 +233310,7 @@ var manualContextCompactionUseCase = new ManualContextCompactionUseCase();
232633
233310
 
232634
233311
  // src/electron/main/handlers/chat-handlers.ts
232635
233312
  init_message_deps();
232636
- var logger30 = createLogger("ChatHandlers");
233313
+ var logger32 = createLogger("ChatHandlers");
232637
233314
  function resolveSessionIdType(id) {
232638
233315
  return resolveSessionIdTypeWithDeps(id, resolveMessageDeps());
232639
233316
  }
@@ -232699,15 +233376,15 @@ async function inferGroupMentionsFromContent(groupId, content3) {
232699
233376
  );
232700
233377
  }
232701
233378
  async function handleStopRun(runId) {
232702
- logger30.debug("IPC_STOP_RUN received runId:", runId);
233379
+ logger32.debug("IPC_STOP_RUN received runId:", runId);
232703
233380
  const sessionId = messageQueue.getSessionIdByRunId(runId);
232704
- logger30.debug("Mapped to sessionId:", sessionId);
233381
+ logger32.debug("Mapped to sessionId:", sessionId);
232705
233382
  if (!sessionId) {
232706
- logger30.warn("runId not found:", runId);
233383
+ logger32.warn("runId not found:", runId);
232707
233384
  return;
232708
233385
  }
232709
233386
  messageQueue.stop(sessionId);
232710
- logger30.debug("Stop called for sessionId:", sessionId);
233387
+ logger32.debug("Stop called for sessionId:", sessionId);
232711
233388
  }
232712
233389
  async function handleCreateNewSession(sessionId) {
232713
233390
  const idType = await resolveSessionIdType(sessionId);
@@ -232715,7 +233392,7 @@ async function handleCreateNewSession(sessionId) {
232715
233392
  await clearGoalWorkspaceState(idType.groupId, idType.sessionId, ACTIVE_GOAL_WORKSPACE_ID);
232716
233393
  await sessionStorage.saveSessionContext(idType.groupId, idType.sessionId, []);
232717
233394
  await messagePublisher.publishContextMarker(idType.sessionId);
232718
- logger30.noise(`reset context for group session ${idType.sessionId}`);
233395
+ logger32.noise(`reset context for group session ${idType.sessionId}`);
232719
233396
  return idType.sessionId;
232720
233397
  }
232721
233398
  return messagePublisher.resetSession(sessionId);
@@ -232743,8 +233420,20 @@ async function handleSendUserMessage(request) {
232743
233420
  const slashCommand = hasAttachments ? null : parseSlashCommand(content3);
232744
233421
  const isSlashCommand = slashCommand !== null;
232745
233422
  const isGoalCommand = slashCommand?.name === "goal";
233423
+ const skillInvocation = !isSlashCommand && !hasAttachments ? parseSkillInvocation(content3) : null;
233424
+ let skillContentOverride;
233425
+ if (skillInvocation) {
233426
+ const skill = await skillManager.getGlobalSkill(skillInvocation.skillName);
233427
+ if (!skill || !skill.enabled) {
233428
+ await messagePublisher.publishLocalSystemMessage(idType.sessionId, [
233429
+ { type: "text", text: `\u672A\u627E\u5230 Skill "${skillInvocation.skillName}"\u3002\u8BF7\u68C0\u67E5\u540D\u79F0\u662F\u5426\u6B63\u786E\uFF0C\u6216\u786E\u8BA4\u8BE5 skill \u5DF2\u5B89\u88C5\u3002` }
233430
+ ], { clientRequestId });
233431
+ return void 0;
233432
+ }
233433
+ skillContentOverride = await buildSkillToolOutput(skill);
233434
+ }
232746
233435
  if (await manualContextCompactionUseCase.isCompactingSession(idType.sessionId)) {
232747
- throw new Error("Conversation is being compacted, please wait");
233436
+ throw new Error("\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u7A0D\u540E\u518D\u53D1\u9001");
232748
233437
  }
232749
233438
  if (isGoalCommand && !groupId) {
232750
233439
  throw new Error("/goal is only available in group sessions");
@@ -232752,8 +233441,8 @@ async function handleSendUserMessage(request) {
232752
233441
  const goalSupervisorId = isGoalCommand && groupId ? await resolveTargetAgent(sessionId, groupId, mentionDirective, directOwnerAgentId) : void 0;
232753
233442
  const goalId = goalSupervisorId ? createGoalWorkspaceId() : void 0;
232754
233443
  const activeGoalState = !isGoalCommand && groupId ? await readGoalWorkspaceState(groupId, sessionId, ACTIVE_GOAL_WORKSPACE_ID) : null;
232755
- const activeGoalSupervisorId = activeGoalState?.status === "active" || activeGoalState?.status === "completed" ? activeGoalState.supervisorId : void 0;
232756
- const activeGoalMode = activeGoalState?.status === "active" || activeGoalState?.status === "completed" ? "continue" : void 0;
233444
+ const activeGoalSupervisorId = activeGoalState?.status === "active" ? activeGoalState.supervisorId : void 0;
233445
+ const activeGoalMode = activeGoalState?.status === "active" ? "continue" : void 0;
232757
233446
  const activeGoalId = activeGoalMode ? activeGoalState?.goalId : void 0;
232758
233447
  const metadataWithoutSupervisor = normalizedMetadata ? { ...normalizedMetadata, supervisorId: void 0 } : void 0;
232759
233448
  const publishMetadata = goalSupervisorId ? { ...metadataWithoutSupervisor, supervisorId: goalSupervisorId, goalMode: "start", goalId } : activeGoalSupervisorId && activeGoalMode ? { ...metadataWithoutSupervisor, supervisorId: activeGoalSupervisorId, goalMode: activeGoalMode, goalId: activeGoalId } : metadataWithoutSupervisor;
@@ -232763,12 +233452,14 @@ async function handleSendUserMessage(request) {
232763
233452
  mentionDirective,
232764
233453
  directOwnerAgentId
232765
233454
  );
233455
+ const llmMessagesOverride = buildSkillLLMMessagesOverride(skillInvocation, skillContentOverride);
232766
233456
  try {
232767
233457
  const result = await publishUserMessageWithSlashCommandHandling(sessionId, blocks, content3, {
232768
233458
  metadata: publishMetadata,
232769
233459
  clientRequestId,
232770
233460
  targetAgentId,
232771
- originalContent: content3
233461
+ originalContent: content3,
233462
+ llmMessagesOverride
232772
233463
  }, {
232773
233464
  clearContext: async (sessionId2) => {
232774
233465
  await handleCreateNewSession(sessionId2);
@@ -232778,24 +233469,25 @@ async function handleSendUserMessage(request) {
232778
233469
  return result.message?.id;
232779
233470
  } catch (error48) {
232780
233471
  if (isSqliteIOError(error48)) {
232781
- logger30.warn("SEND_USER_MESSAGE hit SQLITE_IOERR, attempting reconnect + retry");
233472
+ logger32.warn("SEND_USER_MESSAGE hit SQLITE_IOERR, attempting reconnect + retry");
232782
233473
  try {
232783
233474
  await reconnectSequelize();
232784
233475
  const result = await publishUserMessageWithSlashCommandHandling(sessionId, blocks, content3, {
232785
233476
  metadata: publishMetadata,
232786
233477
  clientRequestId,
232787
233478
  targetAgentId,
232788
- originalContent: content3
233479
+ originalContent: content3,
233480
+ llmMessagesOverride
232789
233481
  }, {
232790
233482
  clearContext: async (sessionId2) => {
232791
233483
  await handleCreateNewSession(sessionId2);
232792
233484
  },
232793
233485
  compactContext: handleCompactConversation
232794
233486
  });
232795
- logger30.info("SEND_USER_MESSAGE retry succeeded after reconnect");
233487
+ logger32.info("SEND_USER_MESSAGE retry succeeded after reconnect");
232796
233488
  return result.message?.id;
232797
233489
  } catch (retryError) {
232798
- logger30.error("SEND_USER_MESSAGE retry still failed after reconnect:", retryError);
233490
+ logger32.error("SEND_USER_MESSAGE retry still failed after reconnect:", retryError);
232799
233491
  throw new Error(
232800
233492
  "\u6570\u636E\u5E93\u8BFB\u5199\u5931\u8D25\uFF0C\u53EF\u80FD\u662F\u78C1\u76D8\u7A7A\u95F4\u4E0D\u8DB3\u6216\u5B89\u5168\u8F6F\u4EF6\u62E6\u622A\u4E86\u6587\u4EF6\u8BBF\u95EE\u3002\u8BF7\u5C1D\u8BD5\u91CD\u542F KAi\u3002"
232801
233493
  );
@@ -232808,7 +233500,7 @@ async function handleCompactConversation(sessionId, tips) {
232808
233500
  await manualContextCompactionUseCase.compactManual({ sessionId, tips });
232809
233501
  }
232810
233502
  async function handleCancelQueuedMessages(sessionId) {
232811
- logger30.debug("IPC_CANCEL_QUEUED_MESSAGES, sessionId:", sessionId);
233503
+ logger32.debug("IPC_CANCEL_QUEUED_MESSAGES, sessionId:", sessionId);
232812
233504
  const cancelledItems = messageQueue.cancelQueuedMessages(sessionId);
232813
233505
  if (cancelledItems.length === 0) {
232814
233506
  return { cancelledContent: "" };
@@ -232823,7 +233515,7 @@ async function handleCancelQueuedMessages(sessionId) {
232823
233515
  messageIds
232824
233516
  });
232825
233517
  const cancelledContent = cancelledItems.map((item) => item.originalContent).filter(Boolean).join("\n");
232826
- logger30.info(`cancelled ${cancelledItems.length} queued messages for ${sessionId}`);
233518
+ logger32.info(`cancelled ${cancelledItems.length} queued messages for ${sessionId}`);
232827
233519
  return { cancelledContent };
232828
233520
  }
232829
233521
  function registerChatHandlers() {
@@ -233899,7 +234591,7 @@ async function createDirectoryAttachmentPayload(path19) {
233899
234591
  }
233900
234592
 
233901
234593
  // src/electron/main/handlers/conversation-handlers.ts
233902
- var logger31 = createLogger("conversation-handlers");
234594
+ var logger33 = createLogger("conversation-handlers");
233903
234595
  var filterVisibleMessages = (messages) => messages.filter((message) => !message.compressionMetadata?.isSummary);
233904
234596
  async function removeAgentFromAllGroups(agentId) {
233905
234597
  const groups = await groupFileStore.list();
@@ -234002,7 +234694,7 @@ async function emitConversationSnapshot(sessionId) {
234002
234694
  activeRun ? { activeRun } : void 0
234003
234695
  );
234004
234696
  } catch (error48) {
234005
- logger31.error("Failed to emit snapshot", { sessionId, error: error48 });
234697
+ logger33.error("Failed to emit snapshot", { sessionId, error: error48 });
234006
234698
  }
234007
234699
  }
234008
234700
  async function handleCreateConversation(type, title, agentIds) {
@@ -234021,7 +234713,7 @@ async function handleCreateConversation(type, title, agentIds) {
234021
234713
  try {
234022
234714
  await sessionService.deleteDirectSession(directSession.id);
234023
234715
  } catch (cleanupError) {
234024
- logger31.warn("Failed to rollback direct session after message publish failure", {
234716
+ logger33.warn("Failed to rollback direct session after message publish failure", {
234025
234717
  sessionId: directSession.id,
234026
234718
  error: cleanupError
234027
234719
  });
@@ -234061,15 +234753,15 @@ async function handleListConversations() {
234061
234753
  });
234062
234754
  }
234063
234755
  } catch (error48) {
234064
- logger31.warn("Failed to list direct sessions for agent", {
234756
+ logger33.warn("Failed to list direct sessions for agent", {
234065
234757
  agentId: agent.id,
234066
234758
  error: error48
234067
234759
  });
234068
234760
  }
234069
234761
  }
234070
- logger31.debug("single chats loaded", { count: singleChats.length });
234762
+ logger33.debug("single chats loaded", { count: singleChats.length });
234071
234763
  const groups = await groupFileStore.list();
234072
- logger31.debug("groups loaded", { count: groups.length });
234764
+ logger33.debug("groups loaded", { count: groups.length });
234073
234765
  const groupSessionItems = [];
234074
234766
  for (const group of groups) {
234075
234767
  const sessionsWithLastMsg = await sessionService.listByGroupIdWithLastMessage(group.id);
@@ -234093,7 +234785,7 @@ async function handleListConversations() {
234093
234785
  const bTime = b2.lastMessage?.createdAt ?? b2.createdAt;
234094
234786
  return bTime - aTime;
234095
234787
  });
234096
- logger31.debug("conversations merged", { total: all2.length, groups: groupSessionItems.length });
234788
+ logger33.debug("conversations merged", { total: all2.length, groups: groupSessionItems.length });
234097
234789
  return all2;
234098
234790
  }
234099
234791
  async function handleGetConversationAgents(sessionId) {
@@ -254567,7 +255259,7 @@ function bucket(value, limits, suffix) {
254567
255259
  }
254568
255260
 
254569
255261
  // src/electron/main/telemetry/MainTelemetryService.ts
254570
- var logger32 = createLogger("telemetry");
255262
+ var logger34 = createLogger("telemetry");
254571
255263
  function sanitizeEventName(value) {
254572
255264
  if (typeof value !== "string") return "";
254573
255265
  return value.trim().slice(0, 200);
@@ -254628,21 +255320,21 @@ var MainTelemetryService = class {
254628
255320
  if (!defaultTelemetryPolicy.shouldUploadEventName(name21)) return;
254629
255321
  this.client.track(name21, defaultTelemetryPolicy.sanitizeProperties(name21, properties));
254630
255322
  } catch (err2) {
254631
- logger32.debug("telemetry track ignored", err2);
255323
+ logger34.debug("telemetry track ignored", err2);
254632
255324
  }
254633
255325
  }
254634
255326
  reportCrash(report) {
254635
255327
  try {
254636
255328
  this.client.reportCrash(report);
254637
255329
  } catch (err2) {
254638
- logger32.debug("telemetry reportCrash ignored", err2);
255330
+ logger34.debug("telemetry reportCrash ignored", err2);
254639
255331
  }
254640
255332
  }
254641
255333
  async sendFeedback(feedback) {
254642
255334
  try {
254643
255335
  await this.client.sendFeedback(feedback);
254644
255336
  } catch (err2) {
254645
- logger32.debug("telemetry sendFeedback ignored", err2);
255337
+ logger34.debug("telemetry sendFeedback ignored", err2);
254646
255338
  }
254647
255339
  }
254648
255340
  setEnabled(enabled) {
@@ -254672,7 +255364,7 @@ var MainTelemetryService = class {
254672
255364
  try {
254673
255365
  await this.client.flush();
254674
255366
  } catch (err2) {
254675
- logger32.debug("telemetry flush ignored", err2);
255367
+ logger34.debug("telemetry flush ignored", err2);
254676
255368
  }
254677
255369
  }
254678
255370
  isEnabled() {
@@ -254728,7 +255420,7 @@ var MainTelemetryService = class {
254728
255420
  try {
254729
255421
  fs2.writeFileSync(prefsPath, JSON.stringify({ enabled }, null, 2), "utf-8");
254730
255422
  } catch (err2) {
254731
- logger32.debug("failed to persist telemetry preference", err2);
255423
+ logger34.debug("failed to persist telemetry preference", err2);
254732
255424
  }
254733
255425
  }
254734
255426
  // --- 配置读取 ---
@@ -254781,7 +255473,7 @@ var telemetryService = new MainTelemetryService();
254781
255473
  // src/adapters/llm/llm-telemetry.ts
254782
255474
  init_logger();
254783
255475
  init_error_utils();
254784
- var logger33 = createLogger("llm-telemetry");
255476
+ var logger35 = createLogger("llm-telemetry");
254785
255477
  function withLlmLanguageTelemetry(model, context2) {
254786
255478
  if (!isLanguageModelV3(model)) return model;
254787
255479
  const middleware = {
@@ -254911,9 +255603,9 @@ function captureLlmCallFinished(event) {
254911
255603
  errorFingerprint: properties.errorFingerprint
254912
255604
  };
254913
255605
  if (event.ok) {
254914
- logger33.debug("call finished", logPayload);
255606
+ logger35.debug("call finished", logPayload);
254915
255607
  } else {
254916
- logger33.warn("call failed", logPayload);
255608
+ logger35.warn("call failed", logPayload);
254917
255609
  }
254918
255610
  }
254919
255611
  function sanitizeLlmTelemetry(event) {
@@ -255240,7 +255932,7 @@ init_AgentConfigModel();
255240
255932
  init_agent_identity();
255241
255933
  init_logger();
255242
255934
  init_SessionService();
255243
- var logger34 = createLogger("agent-handlers");
255935
+ var logger36 = createLogger("agent-handlers");
255244
255936
  function mapAgentPersistenceError(error48) {
255245
255937
  return error48 instanceof Error ? error48 : new Error(String(error48));
255246
255938
  }
@@ -255293,10 +255985,10 @@ async function ensureAgentNameUnique(name21, selfId) {
255293
255985
  }
255294
255986
  async function rollbackCreatedAgent(agentId) {
255295
255987
  await sessionService.deleteAllDirectSessionsByAgentId(agentId).catch((cleanupError) => {
255296
- logger34.warn(`Failed to rollback direct sessions for ${agentId}:`, cleanupError);
255988
+ logger36.warn(`Failed to rollback direct sessions for ${agentId}:`, cleanupError);
255297
255989
  });
255298
255990
  await agentFileStore.delete(agentId).catch((cleanupError) => {
255299
- logger34.warn(`Failed to rollback agent creation for ${agentId}:`, cleanupError);
255991
+ logger36.warn(`Failed to rollback agent creation for ${agentId}:`, cleanupError);
255300
255992
  });
255301
255993
  }
255302
255994
  async function handleCreateAgent(agentData, configData) {
@@ -255337,7 +256029,7 @@ async function handleCreateAgent(agentData, configData) {
255337
256029
  if (shouldRollback && rollbackAgentId) {
255338
256030
  await rollbackCreatedAgent(rollbackAgentId);
255339
256031
  }
255340
- logger34.error("Failed to create agent:", error48);
256032
+ logger36.error("Failed to create agent:", error48);
255341
256033
  throw mapAgentPersistenceError(error48);
255342
256034
  }
255343
256035
  }
@@ -255508,7 +256200,7 @@ async function handleGetAgentChannels(agentId) {
255508
256200
  autoFallback: derived.autoFallback
255509
256201
  };
255510
256202
  } catch (error48) {
255511
- logger34.error("Failed to get agent channels:", error48);
256203
+ logger36.error("Failed to get agent channels:", error48);
255512
256204
  return null;
255513
256205
  }
255514
256206
  }
@@ -255521,7 +256213,7 @@ async function handleUpdateAgentChannels(agentId, channelConfig) {
255521
256213
  });
255522
256214
  await agentFileStore.writeConfig(next2);
255523
256215
  } catch (error48) {
255524
- logger34.error("Failed to update agent channels:", error48);
256216
+ logger36.error("Failed to update agent channels:", error48);
255525
256217
  throw error48;
255526
256218
  }
255527
256219
  }
@@ -255544,7 +256236,7 @@ async function handleSwitchChannel(agentId, target) {
255544
256236
  });
255545
256237
  await agentFileStore.writeConfig(next2);
255546
256238
  } catch (error48) {
255547
- logger34.error("Failed to switch channel:", error48);
256239
+ logger36.error("Failed to switch channel:", error48);
255548
256240
  throw error48;
255549
256241
  }
255550
256242
  }
@@ -255610,7 +256302,7 @@ var quickReplyStorage = new QuickReplyStorage();
255610
256302
  init_id2();
255611
256303
  init_logger();
255612
256304
  init_ipc_events();
255613
- var logger35 = createLogger("settings-handlers");
256305
+ var logger37 = createLogger("settings-handlers");
255614
256306
  function migrateMultimodalModel(raw) {
255615
256307
  if (!raw || typeof raw !== "object") return raw;
255616
256308
  const obj = raw;
@@ -255721,14 +256413,14 @@ async function handleFetchModels(baseUrl, apiKey, apiType) {
255721
256413
  }
255722
256414
  const statusCode = typeof err2 === "object" && err2 && "statusCode" in err2 ? err2.statusCode : void 0;
255723
256415
  if (statusCode === 401) {
255724
- logger35.error("Failed to fetch models: auth failed");
256416
+ logger37.error("Failed to fetch models: auth failed");
255725
256417
  return { models: [], error: "auth_failed" };
255726
256418
  }
255727
256419
  if (typeof statusCode === "number" && statusCode >= 400) {
255728
- logger35.error(`Failed to fetch models: status ${statusCode}`);
256420
+ logger37.error(`Failed to fetch models: status ${statusCode}`);
255729
256421
  return { models: [], error: "api_error" };
255730
256422
  }
255731
- logger35.error("Failed to fetch models:", err2);
256423
+ logger37.error("Failed to fetch models:", err2);
255732
256424
  return { models: [], error: "network_error" };
255733
256425
  }
255734
256426
  }
@@ -255862,7 +256554,7 @@ function validateMcpConfig(config3) {
255862
256554
 
255863
256555
  // src/electron/main/handlers/mcp-handlers.ts
255864
256556
  init_logger();
255865
- var logger36 = createLogger("mcp-handlers");
256557
+ var logger38 = createLogger("mcp-handlers");
255866
256558
  async function handleGetMcpServers() {
255867
256559
  const mcpConfig = config.getMcpConfig();
255868
256560
  const status = mcpManager.getServerStatus();
@@ -255892,7 +256584,7 @@ async function handleSaveMcpServers(servers) {
255892
256584
  config.saveMcpConfig({ mcpServers: servers });
255893
256585
  await mcpManager.updateConfig({ servers });
255894
256586
  } catch (error48) {
255895
- logger36.error("Failed to save MCP servers:", error48);
256587
+ logger38.error("Failed to save MCP servers:", error48);
255896
256588
  throw error48;
255897
256589
  }
255898
256590
  }
@@ -260274,7 +260966,7 @@ init_ipc_events();
260274
260966
  init_logger();
260275
260967
  init_scheduled_task_target();
260276
260968
  init_scheduled_task_state();
260277
- var logger37 = createLogger("TaskHandlers");
260969
+ var logger39 = createLogger("TaskHandlers");
260278
260970
  function omitSchedulerState(input) {
260279
260971
  const { lastRunAt: _lastRunAt, nextRunAt: _nextRunAt, ...rest } = input;
260280
260972
  return rest;
@@ -260301,7 +260993,7 @@ function isDuplicateScheduledTask(task, existing) {
260301
260993
  }
260302
260994
  async function handleCreateScheduledTask(task) {
260303
260995
  const input = omitSchedulerState(task);
260304
- logger37.debug("\u521B\u5EFA\u4EFB\u52A1:", input.name);
260996
+ logger39.debug("\u521B\u5EFA\u4EFB\u52A1:", input.name);
260305
260997
  await assertValidScheduledTaskTarget(input);
260306
260998
  const existingTasks = await cronFileStore.findAllTasks();
260307
260999
  const duplicate = existingTasks.find((existing) => isDuplicateScheduledTask(input, existing));
@@ -260373,7 +261065,7 @@ async function handleTriggerMemoryUpdate(agentId) {
260373
261065
  const scheduler = requireScheduler();
260374
261066
  const tempId = `temp-memory-update-${agentId}`;
260375
261067
  if (scheduler.isRunning(tempId)) {
260376
- logger37.debug("Manual memory update already running for agent:", agentId);
261068
+ logger39.debug("Manual memory update already running for agent:", agentId);
260377
261069
  return {
260378
261070
  status: "failed",
260379
261071
  totalAgents: 1,
@@ -260442,7 +261134,7 @@ init_scheduled_task_state();
260442
261134
  init_ipc_events();
260443
261135
  init_nightly_memory();
260444
261136
  init_logger();
260445
- var logger38 = createLogger("MemoryGrowthHandlers");
261137
+ var logger40 = createLogger("MemoryGrowthHandlers");
260446
261138
  var NIGHTLY_MEMORY_TASK_ID = "nightly-memory-update";
260447
261139
  var DEFAULT_NAME = "\u591C\u95F4\u6574\u7406";
260448
261140
  var DISABLED_SCOPE = { enabled: false, mode: "all" };
@@ -260469,7 +261161,7 @@ function buildDailyCronExpression(time3) {
260469
261161
  async function ensureNightlyTask() {
260470
261162
  const existing = await cronFileStore.findTaskById(NIGHTLY_MEMORY_TASK_ID);
260471
261163
  if (existing) return migrateLegacyNightlyTask(existing);
260472
- logger38.debug("Creating default nightly memory task");
261164
+ logger40.debug("Creating default nightly memory task");
260473
261165
  return cronFileStore.ensureNightlyMemoryTask();
260474
261166
  }
260475
261167
  async function migrateLegacyNightlyTask(task) {
@@ -260770,7 +261462,7 @@ function registerTeamMemoryHandlers() {
260770
261462
  init_config();
260771
261463
  init_logger();
260772
261464
  init_ipc_events();
260773
- var logger39 = createLogger("HealthMonitor");
261465
+ var logger41 = createLogger("HealthMonitor");
260774
261466
  var MAX_TTFT_HISTORY = 10;
260775
261467
  var DEGRADED_TTFT_THRESHOLD_MS = 3e3;
260776
261468
  var UNHEALTHY_ERROR_COUNT = 3;
@@ -260814,7 +261506,7 @@ var HealthMonitor = class {
260814
261506
  s3.errors = 0;
260815
261507
  s3.status = this.calcStatus(s3);
260816
261508
  s3.lastUsedAt = Date.now();
260817
- logger39.debug(`health: ${channelId}:${model} ttft=${timeToFirstChunkMs ?? "n/a"}ms status=${s3.status}`);
261509
+ logger41.debug(`health: ${channelId}:${model} ttft=${timeToFirstChunkMs ?? "n/a"}ms status=${s3.status}`);
260818
261510
  this.broadcast();
260819
261511
  }
260820
261512
  recordError(channelId, model, timeToFirstChunkMs) {
@@ -260826,7 +261518,7 @@ var HealthMonitor = class {
260826
261518
  }
260827
261519
  s3.status = this.calcStatus(s3);
260828
261520
  s3.lastUsedAt = Date.now();
260829
- logger39.debug(`health: ${channelId}:${model} errors=${s3.errors} ttft=${timeToFirstChunkMs ?? "n/a"}ms status=${s3.status}`);
261521
+ logger41.debug(`health: ${channelId}:${model} errors=${s3.errors} ttft=${timeToFirstChunkMs ?? "n/a"}ms status=${s3.status}`);
260830
261522
  this.broadcast();
260831
261523
  }
260832
261524
  /**
@@ -260839,7 +261531,7 @@ var HealthMonitor = class {
260839
261531
  if (Date.now() - s3.lastUsedAt > UNHEALTHY_COOLDOWN_MS) {
260840
261532
  s3.errors = 0;
260841
261533
  s3.status = "unknown";
260842
- logger39.info(`health: ${channelId}:${model} cooldown expired, resetting to unknown`);
261534
+ logger41.info(`health: ${channelId}:${model} cooldown expired, resetting to unknown`);
260843
261535
  this.broadcast();
260844
261536
  return true;
260845
261537
  }
@@ -260878,7 +261570,7 @@ var HealthMonitor = class {
260878
261570
  lastUsedAt: Date.now()
260879
261571
  });
260880
261572
  }
260881
- logger39.info(`health: initialized ${channels.length} channels`);
261573
+ logger41.info(`health: initialized ${channels.length} channels`);
260882
261574
  }
260883
261575
  reset() {
260884
261576
  this.store.clear();
@@ -260895,7 +261587,7 @@ function setupHealthIPC() {
260895
261587
  try {
260896
261588
  healthMonitor.initialize(config.getLLMChannels());
260897
261589
  } catch {
260898
- logger39.debug("health: config not ready at setup time");
261590
+ logger41.debug("health: config not ready at setup time");
260899
261591
  }
260900
261592
  registerRpc(IPC_HEALTH_GET_ALL, handleGetAllHealth);
260901
261593
  registerRpc(IPC_HEALTH_GET, handleGetHealth);
@@ -260960,7 +261652,7 @@ var import_busboy = __toESM(require_lib3());
260960
261652
  // src/adapters/transport/token-auth.ts
260961
261653
  var import_node_crypto5 = __toESM(require("node:crypto"));
260962
261654
  init_logger();
260963
- var logger40 = createLogger("token-auth");
261655
+ var logger42 = createLogger("token-auth");
260964
261656
  var tokenState = null;
260965
261657
  function generateToken() {
260966
261658
  const value = import_node_crypto5.default.randomBytes(32).toString("hex");
@@ -260968,7 +261660,7 @@ function generateToken() {
260968
261660
  value,
260969
261661
  createdAt: Date.now()
260970
261662
  };
260971
- logger40.debug("token generated");
261663
+ logger42.debug("token generated");
260972
261664
  return value;
260973
261665
  }
260974
261666
  function restoreToken(token, createdAt = Date.now()) {
@@ -260976,7 +261668,7 @@ function restoreToken(token, createdAt = Date.now()) {
260976
261668
  value: token,
260977
261669
  createdAt
260978
261670
  };
260979
- logger40.debug("token restored");
261671
+ logger42.debug("token restored");
260980
261672
  return tokenState.value;
260981
261673
  }
260982
261674
  function validateToken(token) {
@@ -260984,7 +261676,7 @@ function validateToken(token) {
260984
261676
  return false;
260985
261677
  }
260986
261678
  if (token !== tokenState.value) {
260987
- logger40.warn("token mismatch");
261679
+ logger42.warn("token mismatch");
260988
261680
  return false;
260989
261681
  }
260990
261682
  return true;
@@ -260993,7 +261685,7 @@ function clearToken() {
260993
261685
  const had = tokenState !== null;
260994
261686
  tokenState = null;
260995
261687
  if (had) {
260996
- logger40.debug("token cleared");
261688
+ logger42.debug("token cleared");
260997
261689
  }
260998
261690
  }
260999
261691
  function getCurrentToken() {
@@ -261013,7 +261705,7 @@ var MAX_MISSED_HEARTBEATS = 2;
261013
261705
  var MAX_BUFFERED_AMOUNT = 4 * 1024 * 1024;
261014
261706
  var MAX_LOGGED_DROPS_PER_CONNECTION = 5;
261015
261707
  var CLOSE_TRY_AGAIN_LATER = 1013;
261016
- var logger41 = createLogger("ws-manager");
261708
+ var logger43 = createLogger("ws-manager");
261017
261709
  var WsConnectionManager = class {
261018
261710
  constructor(wss) {
261019
261711
  this.wss = wss;
@@ -261054,7 +261746,7 @@ var WsConnectionManager = class {
261054
261746
  };
261055
261747
  this.connections.set(id, connection);
261056
261748
  eventBridge.addChannel(connection.channel);
261057
- logger41.info("ws connection accepted", {
261749
+ logger43.info("ws connection accepted", {
261058
261750
  connectionId: id,
261059
261751
  ip,
261060
261752
  activeConnections: this.connections.size
@@ -261063,7 +261755,7 @@ var WsConnectionManager = class {
261063
261755
  connection.missedHeartbeats = 0;
261064
261756
  });
261065
261757
  socket.on("close", () => {
261066
- logger41.info("ws connection closed", {
261758
+ logger43.info("ws connection closed", {
261067
261759
  connectionId: id,
261068
261760
  ip,
261069
261761
  sentEvents: connection.sentEvents,
@@ -261072,7 +261764,7 @@ var WsConnectionManager = class {
261072
261764
  this.removeConnection(id);
261073
261765
  });
261074
261766
  socket.on("error", () => {
261075
- logger41.warn("ws connection error", {
261767
+ logger43.warn("ws connection error", {
261076
261768
  connectionId: id,
261077
261769
  ip,
261078
261770
  sentEvents: connection.sentEvents,
@@ -261085,7 +261777,7 @@ var WsConnectionManager = class {
261085
261777
  if (payloadBytes > MAX_BUFFERED_AMOUNT || socket.bufferedAmount + payloadBytes > MAX_BUFFERED_AMOUNT) {
261086
261778
  connection.droppedEvents++;
261087
261779
  if (connection.droppedEvents <= MAX_LOGGED_DROPS_PER_CONNECTION) {
261088
- logger41.warn("ws channel backpressure, closing connection to force client resync", {
261780
+ logger43.warn("ws channel backpressure, closing connection to force client resync", {
261089
261781
  connectionId: connection.id,
261090
261782
  ip: connection.ip,
261091
261783
  event,
@@ -261095,7 +261787,7 @@ var WsConnectionManager = class {
261095
261787
  });
261096
261788
  }
261097
261789
  if (connection.droppedEvents === MAX_LOGGED_DROPS_PER_CONNECTION) {
261098
- logger41.warn("ws channel backpressure reached threshold", {
261790
+ logger43.warn("ws channel backpressure reached threshold", {
261099
261791
  connectionId: connection.id,
261100
261792
  ip: connection.ip,
261101
261793
  bufferedAmount: socket.bufferedAmount
@@ -261106,7 +261798,7 @@ var WsConnectionManager = class {
261106
261798
  }
261107
261799
  socket.send(payload, (error48) => {
261108
261800
  if (!error48) return;
261109
- logger41.warn("ws send failed", {
261801
+ logger43.warn("ws send failed", {
261110
261802
  connectionId: connection.id,
261111
261803
  ip: connection.ip,
261112
261804
  event,
@@ -261122,7 +261814,7 @@ var WsConnectionManager = class {
261122
261814
  for (const connection of this.connections.values()) {
261123
261815
  connection.missedHeartbeats++;
261124
261816
  if (connection.missedHeartbeats > MAX_MISSED_HEARTBEATS) {
261125
- logger41.warn("ws connection heartbeat timeout", {
261817
+ logger43.warn("ws connection heartbeat timeout", {
261126
261818
  connectionId: connection.id,
261127
261819
  ip: connection.ip,
261128
261820
  missedHeartbeats: connection.missedHeartbeats,
@@ -261134,7 +261826,7 @@ var WsConnectionManager = class {
261134
261826
  continue;
261135
261827
  }
261136
261828
  if (connection.socket.bufferedAmount > MAX_BUFFERED_AMOUNT) {
261137
- logger41.warn("ws heartbeat sees backpressure", {
261829
+ logger43.warn("ws heartbeat sees backpressure", {
261138
261830
  connectionId: connection.id,
261139
261831
  ip: connection.ip,
261140
261832
  bufferedAmount: connection.socket.bufferedAmount,
@@ -262556,7 +263248,7 @@ init_agent_identity();
262556
263248
  init_sequelize();
262557
263249
  init_config();
262558
263250
  init_logger();
262559
- var logger44 = createLogger("migration");
263251
+ var logger46 = createLogger("migration");
262560
263252
  var FILE_STORE_KAI_VERSION = "1.4.0";
262561
263253
  var GROUP_FILE_STORE_KAI_VERSION = "1.5.0";
262562
263254
  var CONVERSATION_ID_MIGRATION_VERSION = "1.5.0";
@@ -262589,7 +263281,7 @@ function readKaiDataFile() {
262589
263281
  try {
262590
263282
  return JSON.parse((0, import_fs26.readFileSync)(path19, "utf-8"));
262591
263283
  } catch (error48) {
262592
- logger44.error("Failed to read kai.json:", error48);
263284
+ logger46.error("Failed to read kai.json:", error48);
262593
263285
  return null;
262594
263286
  }
262595
263287
  }
@@ -262645,7 +263337,7 @@ async function migrateAgentsToFileStore() {
262645
263337
  { type: QueryTypes.SELECT }
262646
263338
  );
262647
263339
  if (tables.length === 0) {
262648
- logger44.debug("agents table not found, skipping agent file-store migration");
263340
+ logger46.debug("agents table not found, skipping agent file-store migration");
262649
263341
  return;
262650
263342
  }
262651
263343
  const agents = await sequelize.query(
@@ -262656,7 +263348,7 @@ async function migrateAgentsToFileStore() {
262656
263348
  const meta3 = await agentFileStore.readMeta(agent.id);
262657
263349
  const agentConfig = await findAgentConfigByAgentId(agent.id);
262658
263350
  if (!agentConfig) {
262659
- logger44.warn(`Skip agent ${agent.id}: config not found in DB`);
263351
+ logger46.warn(`Skip agent ${agent.id}: config not found in DB`);
262660
263352
  continue;
262661
263353
  }
262662
263354
  const normalizedConfig = materializeAgentConfig(agent.id, agentConfig);
@@ -262685,7 +263377,7 @@ async function migrateGroupsToFileStore() {
262685
263377
  );
262686
263378
  const tableNames = new Set(tables.map((t) => t.name));
262687
263379
  if (!tableNames.has("groups")) {
262688
- logger44.debug("No groups table found, skipping group migration");
263380
+ logger46.debug("No groups table found, skipping group migration");
262689
263381
  return;
262690
263382
  }
262691
263383
  const groups = await sequelize.query("SELECT * FROM groups", { type: QueryTypes.SELECT });
@@ -262699,7 +263391,7 @@ async function migrateGroupsToFileStore() {
262699
263391
  members = memberRows.map((m2) => m2.agent_id);
262700
263392
  }
262701
263393
  if (await groupFileStore.exists(group.id)) {
262702
- logger44.debug(`Group ${group.id} already exists in file store, skipping`);
263394
+ logger46.debug(`Group ${group.id} already exists in file store, skipping`);
262703
263395
  continue;
262704
263396
  }
262705
263397
  await groupFileStore.writeFromDbData({
@@ -262715,17 +263407,17 @@ async function migrateGroupsToFileStore() {
262715
263407
  createdAt: group.created_at,
262716
263408
  updatedAt: group.updated_at
262717
263409
  });
262718
- logger44.debug(`Migrated group: ${group.name} (${group.id})`);
263410
+ logger46.debug(`Migrated group: ${group.name} (${group.id})`);
262719
263411
  }
262720
- logger44.debug(`Migrated ${groups.length} groups to file store`);
263412
+ logger46.debug(`Migrated ${groups.length} groups to file store`);
262721
263413
  try {
262722
263414
  if (tableNames.has("group_members")) {
262723
263415
  await sequelize.query("DROP TABLE IF EXISTS group_members");
262724
263416
  }
262725
263417
  await sequelize.query("DROP TABLE IF EXISTS groups");
262726
- logger44.debug("Dropped legacy groups/group_members tables");
263418
+ logger46.debug("Dropped legacy groups/group_members tables");
262727
263419
  } catch (err2) {
262728
- logger44.warn("Failed to drop legacy group tables (non-fatal):", err2);
263420
+ logger46.warn("Failed to drop legacy group tables (non-fatal):", err2);
262729
263421
  }
262730
263422
  }
262731
263423
  async function migrateSessionIds() {
@@ -262735,7 +263427,7 @@ async function migrateSessionIds() {
262735
263427
  { type: QueryTypes.SELECT }
262736
263428
  );
262737
263429
  if (tables.length === 0) {
262738
- logger44.debug("No conversations table found, skipping conversation ID migration");
263430
+ logger46.debug("No conversations table found, skipping conversation ID migration");
262739
263431
  return;
262740
263432
  }
262741
263433
  const convs = await sequelize.query("SELECT id, target_id, type FROM conversations", {
@@ -262747,7 +263439,7 @@ async function migrateSessionIds() {
262747
263439
  const targetId = conv.target_id;
262748
263440
  if (!targetId || oldId === targetId) continue;
262749
263441
  idMap.set(oldId, targetId);
262750
- logger44.debug(`Renaming conversation ${oldId} \u2192 ${targetId}`);
263442
+ logger46.debug(`Renaming conversation ${oldId} \u2192 ${targetId}`);
262751
263443
  await sequelize.query("PRAGMA foreign_keys = OFF");
262752
263444
  await sequelize.query("UPDATE messages SET conversation_id = ? WHERE conversation_id = ?", {
262753
263445
  replacements: [targetId, oldId]
@@ -262787,19 +263479,19 @@ async function migrateSessionIds() {
262787
263479
  const newDir = (0, import_path99.join)(conversationsDir, targetId);
262788
263480
  if (!(0, import_fs26.existsSync)(newDir)) {
262789
263481
  (0, import_fs26.renameSync)(oldDir, newDir);
262790
- logger44.debug(`Renamed dir ${entry.name} \u2192 ${targetId}`);
263482
+ logger46.debug(`Renamed dir ${entry.name} \u2192 ${targetId}`);
262791
263483
  } else {
262792
- logger44.debug(
263484
+ logger46.debug(
262793
263485
  `Target dir ${targetId} already exists, skipping ${entry.name}`
262794
263486
  );
262795
263487
  }
262796
263488
  }
262797
263489
  }
262798
263490
  } catch (err2) {
262799
- logger44.warn("Failed to rename conversation directories (non-fatal):", err2);
263491
+ logger46.warn("Failed to rename conversation directories (non-fatal):", err2);
262800
263492
  }
262801
263493
  }
262802
- logger44.debug(`Migrated ${idMap.size} conversation IDs to targetId`);
263494
+ logger46.debug(`Migrated ${idMap.size} conversation IDs to targetId`);
262803
263495
  }
262804
263496
  async function migrateMultimodalModelRestructure() {
262805
263497
  const raw = config.get("multimodalModel");
@@ -262818,17 +263510,17 @@ async function migrateMultimodalModelRestructure() {
262818
263510
  migrated.generation = raw.generation;
262819
263511
  }
262820
263512
  config.set("multimodalModel", migrated);
262821
- logger44.debug("Migrated multimodalModel to analysis/generation structure");
263513
+ logger46.debug("Migrated multimodalModel to analysis/generation structure");
262822
263514
  }
262823
263515
  async function runStep(fromVersion, stepVersion, label, fn3) {
262824
263516
  if (!isVersionLessThan(fromVersion, stepVersion)) return;
262825
- logger44.debug(`Running migration: ${label}`);
263517
+ logger46.debug(`Running migration: ${label}`);
262826
263518
  try {
262827
263519
  await fn3();
262828
263520
  await writeKaiDataFile(stepVersion);
262829
- logger44.debug(`Completed migration: ${label}`);
263521
+ logger46.debug(`Completed migration: ${label}`);
262830
263522
  } catch (err2) {
262831
- logger44.error(`Migration failed (will retry next launch): ${label}`, err2);
263523
+ logger46.error(`Migration failed (will retry next launch): ${label}`, err2);
262832
263524
  }
262833
263525
  }
262834
263526
  async function runKaiMigrations() {
@@ -262841,26 +263533,26 @@ async function runKaiMigrations() {
262841
263533
  const threadsNeeded = await isMigrationNeeded2();
262842
263534
  if (isVersionLessThan(fromVersion, THREADS_MIGRATION_VERSION) || threadsNeeded) {
262843
263535
  const { migrateGroupsToThreads: migrateGroupsToThreads2 } = await Promise.resolve().then(() => (init_threads_migration(), threads_migration_exports));
262844
- logger44.debug(`Running migration: Group\u2192Threads (version=${fromVersion}, needed=${threadsNeeded})`);
263536
+ logger46.debug(`Running migration: Group\u2192Threads (version=${fromVersion}, needed=${threadsNeeded})`);
262845
263537
  try {
262846
263538
  await migrateGroupsToThreads2();
262847
263539
  await writeKaiDataFile(THREADS_MIGRATION_VERSION);
262848
- logger44.debug("Completed migration: Group\u2192Threads");
263540
+ logger46.debug("Completed migration: Group\u2192Threads");
262849
263541
  } catch (err2) {
262850
- logger44.error("Migration failed (will retry next launch): Group\u2192Threads", err2);
263542
+ logger46.error("Migration failed (will retry next launch): Group\u2192Threads", err2);
262851
263543
  }
262852
263544
  }
262853
263545
  const { isCronMigrationNeeded: isCronMigrationNeeded2 } = await Promise.resolve().then(() => (init_cron_sqlite_migration(), cron_sqlite_migration_exports));
262854
263546
  const cronNeeded = await isCronMigrationNeeded2();
262855
263547
  if (isVersionLessThan(fromVersion, CRON_FILE_STORE_VERSION) || cronNeeded) {
262856
263548
  const { migrateCronSqliteToFileStore: migrateCronSqliteToFileStore2 } = await Promise.resolve().then(() => (init_cron_sqlite_migration(), cron_sqlite_migration_exports));
262857
- logger44.debug(`Running migration: Cron SQLite\u2192Filesystem (version=${fromVersion}, needed=${cronNeeded})`);
263549
+ logger46.debug(`Running migration: Cron SQLite\u2192Filesystem (version=${fromVersion}, needed=${cronNeeded})`);
262858
263550
  try {
262859
263551
  await migrateCronSqliteToFileStore2();
262860
263552
  await writeKaiDataFile(CRON_FILE_STORE_VERSION);
262861
- logger44.debug("Completed migration: Cron SQLite\u2192Filesystem");
263553
+ logger46.debug("Completed migration: Cron SQLite\u2192Filesystem");
262862
263554
  } catch (err2) {
262863
- logger44.error("Migration failed (will retry next launch): Cron SQLite\u2192Filesystem", err2);
263555
+ logger46.error("Migration failed (will retry next launch): Cron SQLite\u2192Filesystem", err2);
262864
263556
  }
262865
263557
  }
262866
263558
  await runStep(fromVersion, DROP_CONTEXT_CACHE_VERSION, "Drop conversation_context_cache", async () => {
@@ -263164,7 +263856,7 @@ function shellEnvSync(shell2) {
263164
263856
 
263165
263857
  // src/shared/utils/shell-env.ts
263166
263858
  init_logger();
263167
- var logger45 = createLogger("shell-env");
263859
+ var logger47 = createLogger("shell-env");
263168
263860
  var cachedEnv = null;
263169
263861
  function getUserShellEnv() {
263170
263862
  if (cachedEnv) return cachedEnv;
@@ -263172,7 +263864,7 @@ function getUserShellEnv() {
263172
263864
  cachedEnv = shellEnvSync();
263173
263865
  return cachedEnv;
263174
263866
  } catch {
263175
- logger45.warn("Failed to get user shell env, falling back to process.env");
263867
+ logger47.warn("Failed to get user shell env, falling back to process.env");
263176
263868
  return process.env;
263177
263869
  }
263178
263870
  }
@@ -280288,7 +280980,7 @@ async function resizeImageBuffer(buffer, maxDimension) {
280288
280980
 
280289
280981
  // src/adapters/tools/image/analyze.ts
280290
280982
  init_logger();
280291
- var logger46 = createLogger("AnalyzeImageTool");
280983
+ var logger48 = createLogger("AnalyzeImageTool");
280292
280984
  function resolveImagePath(imagePath) {
280293
280985
  if ((0, import_path105.isAbsolute)(imagePath)) return imagePath;
280294
280986
  return (0, import_path105.resolve)(process.cwd(), imagePath);
@@ -280368,23 +281060,23 @@ function createAnalyzeImageTool() {
280368
281060
  ],
280369
281061
  abortSignal
280370
281062
  });
280371
- logger46.info(`analyzeImage completed (model ${i + 1}/${candidates.length}), tokens:`, result.usage?.totalTokens);
281063
+ logger48.info(`analyzeImage completed (model ${i + 1}/${candidates.length}), tokens:`, result.usage?.totalTokens);
280372
281064
  return result.text;
280373
281065
  } catch (error48) {
280374
281066
  if (error48 instanceof DOMException && error48.name === "AbortError") throw error48;
280375
281067
  lastError = error48 instanceof Error ? error48 : new Error(String(error48));
280376
281068
  const isLast = i === candidates.length - 1;
280377
281069
  if (!isLast) {
280378
- logger46.warn(`analyzeImage: model ${i + 1} failed (${candidate.model ?? candidate.channelId}), trying next:`, lastError.message);
281070
+ logger48.warn(`analyzeImage: model ${i + 1} failed (${candidate.model ?? candidate.channelId}), trying next:`, lastError.message);
280379
281071
  }
280380
281072
  }
280381
281073
  }
280382
- logger46.error(`analyzeImage failed: all ${candidates.length} model(s) exhausted`);
281074
+ logger48.error(`analyzeImage failed: all ${candidates.length} model(s) exhausted`);
280383
281075
  return `\u5206\u6790\u56FE\u7247\u5931\u8D25\uFF08\u5DF2\u5C1D\u8BD5 ${candidates.length} \u4E2A\u6A21\u578B\uFF09: ${lastError?.message}`;
280384
281076
  } catch (error48) {
280385
281077
  if (error48 instanceof DOMException && error48.name === "AbortError") throw error48;
280386
281078
  const message = error48 instanceof Error ? error48.message : String(error48);
280387
- logger46.error("analyzeImage failed:", error48);
281079
+ logger48.error("analyzeImage failed:", error48);
280388
281080
  return `\u5206\u6790\u56FE\u7247\u5931\u8D25: ${message}`;
280389
281081
  }
280390
281082
  }
@@ -280400,7 +281092,7 @@ var import_fs32 = require("fs");
280400
281092
  var import_path106 = require("path");
280401
281093
  init_config();
280402
281094
  init_logger();
280403
- var logger47 = createLogger("GenerateImageTool");
281095
+ var logger49 = createLogger("GenerateImageTool");
280404
281096
  var MAX_OPENAI_EDIT_IMAGES = 16;
280405
281097
  var MAX_OPENAI_IMAGE_BYTES = 50 * 1024 * 1024;
280406
281098
  var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp", ".gif"]);
@@ -280750,23 +281442,23 @@ function createGenerateImageTool() {
280750
281442
  size: parsedSize,
280751
281443
  abortSignal
280752
281444
  });
280753
- logger47.info(`generateImage completed (model ${i + 1}/${candidates.length}), size:`, buffer.length);
281445
+ logger49.info(`generateImage completed (model ${i + 1}/${candidates.length}), size:`, buffer.length);
280754
281446
  return saveGeneratedImage(buffer);
280755
281447
  } catch (error48) {
280756
281448
  if (error48 instanceof DOMException && error48.name === "AbortError") throw error48;
280757
281449
  lastError = error48 instanceof Error ? error48 : new Error(String(error48));
280758
281450
  const isLast = i === candidates.length - 1;
280759
281451
  if (!isLast) {
280760
- logger47.warn(`generateImage: model ${i + 1} failed (${candidate.model ?? candidate.channelId}), trying next:`, lastError.message);
281452
+ logger49.warn(`generateImage: model ${i + 1} failed (${candidate.model ?? candidate.channelId}), trying next:`, lastError.message);
280761
281453
  }
280762
281454
  }
280763
281455
  }
280764
- logger47.error(`generateImage failed: all ${candidates.length} model(s) exhausted`);
281456
+ logger49.error(`generateImage failed: all ${candidates.length} model(s) exhausted`);
280765
281457
  return JSON.stringify({ error: `\u56FE\u7247\u751F\u6210\u5931\u8D25\uFF08\u5DF2\u5C1D\u8BD5 ${candidates.length} \u4E2A\u6A21\u578B\uFF09: ${lastError?.message}` });
280766
281458
  } catch (error48) {
280767
281459
  if (error48 instanceof DOMException && error48.name === "AbortError") throw error48;
280768
281460
  const message = error48 instanceof Error ? error48.message : String(error48);
280769
- logger47.error("generateImage failed:", error48);
281461
+ logger49.error("generateImage failed:", error48);
280770
281462
  return JSON.stringify({ error: message });
280771
281463
  }
280772
281464
  }
@@ -280905,7 +281597,7 @@ function createSkillTool(agentId, skillNames) {
280905
281597
  return [
280906
281598
  `Skill "${name21}" \u5F53\u524D\u4E0D\u53EF\u7528\u4E8E\u8FD9\u4E2A Agent\u3002`,
280907
281599
  `\u5DF2\u914D\u7F6E\u7684 skill \u540D\u79F0\uFF1A${configuredSkillNamesText}\u3002`,
280908
- "\u5982\u679C\u76F8\u5173\uFF0C\u8BF7\u9009\u62E9\u5176\u4E2D\u4E00\u4E2A\u7CBE\u786E\u540D\u79F0\uFF1B\u5426\u5219\u4E0D\u4F7F\u7528 skill \u7EE7\u7EED\u3002"
281600
+ "\u8BF7\u9009\u62E9\u5176\u4E2D\u4E00\u4E2A\u7CBE\u786E\u540D\u79F0\uFF1B\u5426\u5219\u4E0D\u4F7F\u7528 skill \u7EE7\u7EED\u3002"
280909
281601
  ].join(" ");
280910
281602
  }
280911
281603
  return await buildSkillToolOutput(skill);
@@ -281857,7 +282549,7 @@ function resolveSessionDir(scope) {
281857
282549
  // src/adapters/agent/multimodal-asset-resolver.ts
281858
282550
  init_logger();
281859
282551
  var import_promises48 = require("fs/promises");
281860
- var logger48 = createLogger("MultimodalAssetResolver");
282552
+ var logger50 = createLogger("MultimodalAssetResolver");
281861
282553
  var IMAGE_READ_TIMEOUT_MS = 5e3;
281862
282554
  function createMultimodalAssetResolver(attachmentPort2) {
281863
282555
  return {
@@ -281875,7 +282567,7 @@ function createMultimodalAssetResolver(attachmentPort2) {
281875
282567
  const resized = await resizeImageBuffer(Buffer.from(buffer), maxDim);
281876
282568
  return `data:${resized.mediaType};base64,${resized.buffer.toString("base64")}`;
281877
282569
  } catch (error48) {
281878
- logger48.warn(`Failed to load image asset: ${relativePath}`, error48);
282570
+ logger50.warn(`Failed to load image asset: ${relativePath}`, error48);
281879
282571
  return null;
281880
282572
  }
281881
282573
  }
@@ -281911,7 +282603,7 @@ var import_path110 = require("path");
281911
282603
  init_config();
281912
282604
  init_logger();
281913
282605
  init_ModelCapability();
281914
- var logger49 = createLogger("ModelCapabilityFileStore");
282606
+ var logger51 = createLogger("ModelCapabilityFileStore");
281915
282607
  var FILE_NAME2 = "model-capabilities.json";
281916
282608
  var SAVE_DEBOUNCE_MS = 1e3;
281917
282609
  function isRecord6(value) {
@@ -281947,7 +282639,7 @@ var ModelCapabilityFileStore = class {
281947
282639
  try {
281948
282640
  return parseSnapshot(JSON.parse((0, import_fs33.readFileSync)(this.filePath, "utf-8")));
281949
282641
  } catch (error48) {
281950
- logger49.warn("failed to load model capability cache", error48);
282642
+ logger51.warn("failed to load model capability cache", error48);
281951
282643
  return { models: {} };
281952
282644
  }
281953
282645
  }
@@ -281983,7 +282675,7 @@ var ModelCapabilityFileStore = class {
281983
282675
  (0, import_fs33.mkdirSync)((0, import_path110.dirname)(this.filePath), { recursive: true });
281984
282676
  (0, import_fs33.writeFileSync)(this.filePath, JSON.stringify(file2, null, 2));
281985
282677
  } catch (error48) {
281986
- logger49.warn("failed to save model capability cache", error48);
282678
+ logger51.warn("failed to save model capability cache", error48);
281987
282679
  }
281988
282680
  }
281989
282681
  };
@@ -281992,52 +282684,52 @@ var modelCapabilityFileStore = new ModelCapabilityFileStore();
281992
282684
  // src/app/bootstrap.ts
281993
282685
  init_logger();
281994
282686
  init_sequelize();
281995
- var logger50 = createLogger("bootstrap");
282687
+ var logger52 = createLogger("bootstrap");
281996
282688
  var unsubscribeConversationEvents = null;
281997
282689
  async function bootstrapApplication() {
281998
- logger50.debug("step 1 config.init");
282690
+ logger52.debug("step 1 config.init");
281999
282691
  config.init();
282000
- logger50.debug("step 2 initDatabase");
282692
+ logger52.debug("step 2 initDatabase");
282001
282693
  await initDatabase();
282002
- logger50.debug("step 2.5 bootstrapMessageDeps");
282694
+ logger52.debug("step 2.5 bootstrapMessageDeps");
282003
282695
  bootstrapMessageDeps();
282004
- logger50.debug("step 2.6 bootstrapAgentExecutionDeps");
282696
+ logger52.debug("step 2.6 bootstrapAgentExecutionDeps");
282005
282697
  modelCapabilityFileStore.hydrate();
282006
282698
  modelCapabilityFileStore.watch();
282007
282699
  bootstrapAgentExecutionDeps();
282008
- logger50.debug("step 3 runKaiMigrations");
282700
+ logger52.debug("step 3 runKaiMigrations");
282009
282701
  await runKaiMigrations();
282010
- logger50.debug("step 4 mcpManager.init");
282702
+ logger52.debug("step 4 mcpManager.init");
282011
282703
  const mcpConfig = config.getMcpConfig();
282012
282704
  await mcpManager.init({ servers: mcpConfig.mcpServers });
282013
- logger50.debug("step 6 registerHandlers");
282705
+ logger52.debug("step 6 registerHandlers");
282014
282706
  registerHandlers();
282015
282707
  if (!unsubscribeConversationEvents) {
282016
- logger50.debug("step 6.2 subscribe conversation events");
282708
+ logger52.debug("step 6.2 subscribe conversation events");
282017
282709
  unsubscribeConversationEvents = eventBus.subscribe((event) => {
282018
282710
  eventBridge.broadcast(IPC_CONVERSATION_EVENT, event);
282019
282711
  });
282020
282712
  }
282021
- logger50.debug("step 6.5 sessionManagerPool startCleanup");
282713
+ logger52.debug("step 6.5 sessionManagerPool startCleanup");
282022
282714
  sessionManagerPool.setMessageQueue(messageQueue);
282023
282715
  sessionManagerPool.startCleanup();
282024
- logger50.debug("step 7 initScheduler");
282716
+ logger52.debug("step 7 initScheduler");
282025
282717
  const database = getDatabase();
282026
282718
  await initScheduler({
282027
282719
  db: database,
282028
282720
  eventBridge,
282029
282721
  logger: {
282030
- log: (...args2) => logger50.info(...args2),
282031
- error: (...args2) => logger50.error(...args2)
282722
+ log: (...args2) => logger52.info(...args2),
282723
+ error: (...args2) => logger52.error(...args2)
282032
282724
  }
282033
282725
  });
282034
- logger50.debug("step 9 cleanOldSessions");
282726
+ logger52.debug("step 9 cleanOldSessions");
282035
282727
  sessionCleaner.cleanOldSessions(30).catch((err2) => {
282036
- logger50.error("Failed to clean old sessions:", err2);
282728
+ logger52.error("Failed to clean old sessions:", err2);
282037
282729
  });
282038
- logger50.debug("step 11 channelManager.init");
282730
+ logger52.debug("step 11 channelManager.init");
282039
282731
  channelManager.init().catch((err2) => {
282040
- logger50.error("Failed to init channels:", err2);
282732
+ logger52.error("Failed to init channels:", err2);
282041
282733
  });
282042
282734
  }
282043
282735
  async function cleanup() {