chatlab-cli 0.26.3 → 0.27.1

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 (87) hide show
  1. package/README.md +10 -4
  2. package/dist/{chat-command-D37MMEJ7.mjs → chat-command-B7POB3C3.mjs} +6 -5
  3. package/dist/{chat-command-D37MMEJ7.mjs.map → chat-command-B7POB3C3.mjs.map} +1 -1
  4. package/dist/{chunk-K5SGXTVJ.mjs → chunk-3FUF3PEY.mjs} +21 -19
  5. package/dist/{chunk-K5SGXTVJ.mjs.map → chunk-3FUF3PEY.mjs.map} +1 -1
  6. package/dist/{chunk-742TAKEP.mjs → chunk-3JNVGW62.mjs} +2 -2
  7. package/dist/{chunk-VSOWNKPA.mjs → chunk-GFHSSCCR.mjs} +11 -1
  8. package/dist/{chunk-YPTJVTVJ.mjs → chunk-I7BHOZPX.mjs} +13159 -19038
  9. package/dist/chunk-I7BHOZPX.mjs.map +1 -0
  10. package/dist/chunk-N3G43SCQ.mjs +7337 -0
  11. package/dist/chunk-N3G43SCQ.mjs.map +1 -0
  12. package/dist/{chunk-GNGZHBKM.mjs → chunk-RJ4D4QWK.mjs} +42 -7
  13. package/dist/chunk-RJ4D4QWK.mjs.map +1 -0
  14. package/dist/{chunk-VCN64OD6.mjs → chunk-SAE2H2LN.mjs} +7 -5
  15. package/dist/{chunk-VCN64OD6.mjs.map → chunk-SAE2H2LN.mjs.map} +1 -1
  16. package/dist/{chunk-QMXNJRTT.mjs → chunk-SIVERPF5.mjs} +280 -104
  17. package/dist/chunk-SIVERPF5.mjs.map +1 -0
  18. package/dist/{chunk-RMITK4IC.mjs → chunk-WQMKKUSD.mjs} +468 -118
  19. package/dist/chunk-WQMKKUSD.mjs.map +1 -0
  20. package/dist/{chunk-D5MWER7N.mjs → chunk-YUFYTDRH.mjs} +6 -4
  21. package/dist/{chunk-D5MWER7N.mjs.map → chunk-YUFYTDRH.mjs.map} +1 -1
  22. package/dist/cli.mjs +5 -4
  23. package/dist/{http-6F6TYWCI.mjs → http-A54ZBBAY.mjs} +10 -9
  24. package/dist/{import-VYPOMSSA.mjs → import-EA3TB3S2.mjs} +6 -5
  25. package/dist/index.mjs +10 -9
  26. package/dist/{mcp-AR7L5FA3.mjs → mcp-DJDOWHH3.mjs} +11 -9
  27. package/dist/{mcp-AR7L5FA3.mjs.map → mcp-DJDOWHH3.mjs.map} +1 -1
  28. package/dist/onnxruntime_binding-6Q6HXASN.node +0 -0
  29. package/dist/onnxruntime_binding-EKZT2NRK.node +0 -0
  30. package/dist/onnxruntime_binding-P6S7V3CI.node +0 -0
  31. package/dist/onnxruntime_binding-PJNNIIUO.node +0 -0
  32. package/dist/onnxruntime_binding-UN6SPTQK.node +0 -0
  33. package/dist/semantic-index-worker.mjs +34 -0
  34. package/dist/semantic-index-worker.mjs.map +1 -0
  35. package/dist/{service-KZTHBDQ5.mjs → service-KGL3RAIA.mjs} +2 -2
  36. package/dist/{src-6S7JPKHX.mjs → src-EKPMJRG6.mjs} +65 -109
  37. package/dist/{stream-import-KZFC3XT2.mjs → stream-import-FQFNRQ2B.mjs} +5 -4
  38. package/dist/transformers.node-PUMHAODN.mjs +42889 -0
  39. package/dist/transformers.node-PUMHAODN.mjs.map +1 -0
  40. package/dist/{update-checker-3N7HQEP2.mjs → update-checker-LGMTEKMT.mjs} +2 -2
  41. package/dist/worker-runtime-UH2OBO3T.mjs +71 -0
  42. package/dist/worker-runtime-UH2OBO3T.mjs.map +1 -0
  43. package/dist-web/assets/{DebugToolsPanel-DzZmSzIU.css → DebugToolsPanel-DFw6_G5V.css} +1 -1
  44. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-NL1sTF6i.js +110 -0
  45. package/dist-web/assets/{MessageExportModal-CF6yaor7.js → MessageExportModal-B60rvfCh.js} +1 -1
  46. package/dist-web/assets/{electron-DKVw61Ww.js → electron-BRUg9LnY.js} +1 -1
  47. package/dist-web/assets/{fetch-CUw-PUYP.js → fetch-BIpjJHxj.js} +1 -1
  48. package/dist-web/assets/{fetch-BMdgfBVS.js → fetch-BRsMdFcn.js} +1 -1
  49. package/dist-web/assets/{fetch-CPeSfqsU.js → fetch-C-m3IysH.js} +1 -1
  50. package/dist-web/assets/{fetch-CpYSD089.js → fetch-Cma-mZjd.js} +1 -1
  51. package/dist-web/assets/{fetch-D2jNBqs8.js → fetch-DE8gj5Ke.js} +1 -1
  52. package/dist-web/assets/{fetch-DqEMAea3.js → fetch-DLAp7h55.js} +1 -1
  53. package/dist-web/assets/{fetch-BvVfWR-P.js → fetch-DNSaxRnL.js} +1 -1
  54. package/dist-web/assets/{fetch-BC8jyJ_U.js → fetch-DOEbyLSD.js} +1 -1
  55. package/dist-web/assets/{fetch-BQlEQsqi.js → fetch-DSN-QYZE.js} +1 -1
  56. package/dist-web/assets/{fetch-Bh6HC-IR.js → fetch-woAa3H2L.js} +1 -1
  57. package/dist-web/assets/index-B3mDjury.js +11 -0
  58. package/dist-web/assets/{index-Qh0XLt3R.js → index-B9I-Y3fR.js} +1 -1
  59. package/dist-web/assets/{index-DqybGdJH.css → index-BX3tqfLz.css} +1 -1
  60. package/dist-web/assets/index-GAU7LI1r.js +173 -0
  61. package/dist-web/assets/index-I3SWZjnW.css +1 -0
  62. package/dist-web/assets/index-YmzTgkb2.css +1 -0
  63. package/dist-web/assets/index-iwqJDVMJ.js +2 -0
  64. package/dist-web/assets/index-o6veAyTB.js +64 -0
  65. package/dist-web/assets/{index-BHQnAj6l.js → index-r_zHR2t9.js} +1 -1
  66. package/dist-web/assets/{web-Bx2TiHDk.js → web-C2UtGskd.js} +1 -1
  67. package/dist-web/index.html +2 -2
  68. package/package.json +1 -1
  69. package/dist/chunk-GNGZHBKM.mjs.map +0 -1
  70. package/dist/chunk-QMXNJRTT.mjs.map +0 -1
  71. package/dist/chunk-RMITK4IC.mjs.map +0 -1
  72. package/dist/chunk-YPTJVTVJ.mjs.map +0 -1
  73. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BTdqmm0y.js +0 -107
  74. package/dist-web/assets/index-BwzuCu5R.js +0 -2
  75. package/dist-web/assets/index-CG746E15.js +0 -64
  76. package/dist-web/assets/index-CXoQ_U22.js +0 -173
  77. package/dist-web/assets/index-HgIuP1Td.css +0 -1
  78. package/dist-web/assets/index-R82N2_0b.css +0 -1
  79. package/dist-web/assets/index-wPAmuQZY.js +0 -11
  80. /package/dist/{chunk-742TAKEP.mjs.map → chunk-3JNVGW62.mjs.map} +0 -0
  81. /package/dist/{chunk-VSOWNKPA.mjs.map → chunk-GFHSSCCR.mjs.map} +0 -0
  82. /package/dist/{http-6F6TYWCI.mjs.map → http-A54ZBBAY.mjs.map} +0 -0
  83. /package/dist/{import-VYPOMSSA.mjs.map → import-EA3TB3S2.mjs.map} +0 -0
  84. /package/dist/{service-KZTHBDQ5.mjs.map → service-KGL3RAIA.mjs.map} +0 -0
  85. /package/dist/{src-6S7JPKHX.mjs.map → src-EKPMJRG6.mjs.map} +0 -0
  86. /package/dist/{stream-import-KZFC3XT2.mjs.map → stream-import-FQFNRQ2B.mjs.map} +0 -0
  87. /package/dist/{update-checker-3N7HQEP2.mjs.map → update-checker-LGMTEKMT.mjs.map} +0 -0
@@ -25,9 +25,8 @@ import {
25
25
  getSessionMeta,
26
26
  getSessionOverview,
27
27
  getWeekdayActivity,
28
- searchMessagesLike,
29
- searchSegments
30
- } from "./chunk-YPTJVTVJ.mjs";
28
+ searchMessagesByKeywords
29
+ } from "./chunk-I7BHOZPX.mjs";
31
30
 
32
31
  // ../../packages/tools/src/definitions/sql-query.ts
33
32
  var inputSchema = {
@@ -309,15 +308,6 @@ function formatTimeRange(timeFilter, locale) {
309
308
  end: new Date(timeFilter.endTs * 1e3).toLocaleString(localeStr)
310
309
  };
311
310
  }
312
- function formatMessageCompact(msg, locale) {
313
- const localeStr = isChineseLocale(locale) ? "zh-CN" : "en-US";
314
- const time = new Date(msg.timestamp * 1e3).toLocaleString(localeStr);
315
- let content = msg.content || t("noContent", locale);
316
- if (content.length > 200) {
317
- content = content.slice(0, 200) + "...";
318
- }
319
- return `${time} ${msg.senderName}: ${content}`;
320
- }
321
311
 
322
312
  // ../../packages/tools/src/definitions/chat-overview.ts
323
313
  var inputSchema5 = {
@@ -366,7 +356,7 @@ var chatOverviewTool = {
366
356
  };
367
357
 
368
358
  // ../../packages/tools/src/utils/time-params.ts
369
- function parseExtendedTimeParams(params, contextTimeFilter) {
359
+ function parseExtendedTimeParams(params, contextToolTimeRange) {
370
360
  if (params.start_time || params.end_time) {
371
361
  let startTs;
372
362
  let endTs;
@@ -389,7 +379,7 @@ function parseExtendedTimeParams(params, contextTimeFilter) {
389
379
  };
390
380
  }
391
381
  }
392
- return contextTimeFilter;
382
+ return contextToolTimeRange;
393
383
  }
394
384
 
395
385
  // ../../packages/tools/src/utils/schemas.ts
@@ -536,70 +526,16 @@ var getMessageContextTool = {
536
526
  truncationStrategy: "keep_last"
537
527
  };
538
528
 
539
- // ../../packages/tools/src/definitions/search-segments.ts
540
- var inputSchema9 = {
541
- type: "object",
542
- properties: {
543
- keywords: { type: "array", items: { type: "string" }, description: "\u641C\u7D22\u5173\u952E\u8BCD\u5217\u8868" },
544
- limit: { type: "number", description: "\u8FD4\u56DE\u7684\u6700\u5927\u6BB5\u843D\u6570\uFF0C\u9ED8\u8BA4 20" },
545
- ...timeParamProperties
546
- }
547
- };
548
- async function handler9(params, context) {
549
- const { locale, timeFilter: contextTimeFilter } = context;
550
- const limit = params.limit || 20;
551
- const effectiveTimeFilter = parseExtendedTimeParams(params, contextTimeFilter);
552
- const segments = await context.dataProvider.searchSegments(
553
- params.keywords,
554
- effectiveTimeFilter,
555
- limit,
556
- 5
557
- );
558
- if (segments.length === 0) {
559
- const data2 = {
560
- total: 0,
561
- message: isChineseLocale(locale) ? "\u672A\u627E\u5230\u5339\u914D\u7684\u6BB5\u843D" : "No matching segments found"
562
- };
563
- return { content: JSON.stringify(data2), data: data2 };
564
- }
565
- const localeStr = isChineseLocale(locale) ? "zh-CN" : "en-US";
566
- const msgSuffix = isChineseLocale(locale) ? "\u6761\u6D88\u606F" : " messages";
567
- const completeLabel = isChineseLocale(locale) ? "\u5B8C\u6574\u6BB5\u843D" : "complete";
568
- const data = {
569
- total: segments.length,
570
- timeRange: formatTimeRange(effectiveTimeFilter, locale),
571
- segments: segments.map((s) => {
572
- const startTime = new Date(s.startTs * 1e3).toLocaleString(localeStr);
573
- const endTime = new Date(s.endTs * 1e3).toLocaleString(localeStr);
574
- const completeTag = s.isComplete ? ` [${completeLabel}]` : "";
575
- return {
576
- segmentId: s.id,
577
- time: `${startTime} ~ ${endTime}`,
578
- messageCount: `${s.messageCount}${msgSuffix}${completeTag}`,
579
- preview: s.previewMessages.map((m) => formatMessageCompact(m, locale))
580
- };
581
- })
582
- };
583
- return { content: JSON.stringify(data), data };
584
- }
585
- var searchSegmentsTool = {
586
- name: "search_segments",
587
- description: "\u641C\u7D22\u804A\u5929\u6BB5\u843D\uFF08\u5BF9\u8BDD\u6BB5\u843D\uFF09\u3002\u6BB5\u843D\u662F\u6839\u636E\u6D88\u606F\u65F6\u95F4\u95F4\u9694\u81EA\u52A8\u5207\u5206\u7684\u5BF9\u8BDD\u5355\u5143\u3002\u8FD4\u56DE\u5339\u914D\u7684\u6BB5\u843D\u5217\u8868\u53CA\u6BCF\u4E2A\u6BB5\u843D\u7684\u524D5\u6761\u6D88\u606F\u9884\u89C8\u3002",
588
- inputSchema: inputSchema9,
589
- handler: handler9,
590
- category: "core"
591
- };
592
-
593
529
  // ../../packages/tools/src/definitions/get-segment-messages.ts
594
- var inputSchema10 = {
530
+ var inputSchema9 = {
595
531
  type: "object",
596
532
  properties: {
597
- segment_id: { type: "number", description: "\u6BB5\u843D ID\uFF08\u901A\u8FC7 search_segments \u83B7\u53D6\uFF09" },
533
+ segment_id: { type: "number", description: "\u6BB5\u843D ID\uFF08\u901A\u8FC7 get_segment_summaries \u83B7\u53D6\uFF09" },
598
534
  limit: { type: "number", description: "\u8FD4\u56DE\u7684\u6700\u5927\u6D88\u606F\u6761\u6570" }
599
535
  },
600
536
  required: ["segment_id"]
601
537
  };
602
- async function handler10(params, context) {
538
+ async function handler9(params, context) {
603
539
  const { locale, maxMessagesLimit } = context;
604
540
  const limit = maxMessagesLimit || params.limit || 1e3;
605
541
  const result = await context.dataProvider.getSegmentMessages(params.segment_id, limit);
@@ -631,22 +567,22 @@ async function handler10(params, context) {
631
567
  }
632
568
  var getSegmentMessagesTool = {
633
569
  name: "get_segment_messages",
634
- description: "\u83B7\u53D6\u6307\u5B9A\u6BB5\u843D\u7684\u5B8C\u6574\u6D88\u606F\u5217\u8868\u3002\u7528\u4E8E\u5728 search_segments \u627E\u5230\u76F8\u5173\u6BB5\u843D\u540E\uFF0C\u83B7\u53D6\u8BE5\u6BB5\u843D\u7684\u5B8C\u6574\u4E0A\u4E0B\u6587\u3002",
635
- inputSchema: inputSchema10,
636
- handler: handler10,
570
+ description: "\u83B7\u53D6\u6307\u5B9A\u6BB5\u843D\u7684\u5B8C\u6574\u6D88\u606F\u5217\u8868\u3002\u7528\u4E8E\u5728 get_segment_summaries \u627E\u5230\u76F8\u5173\u6BB5\u843D\u6458\u8981\u540E\uFF0C\u83B7\u53D6\u8BE5\u6BB5\u843D\u7684\u5B8C\u6574\u539F\u6587\u4E0A\u4E0B\u6587\u3002",
571
+ inputSchema: inputSchema9,
572
+ handler: handler9,
637
573
  category: "core",
638
574
  truncationStrategy: "keep_last"
639
575
  };
640
576
 
641
577
  // ../../packages/tools/src/definitions/get-members.ts
642
- var inputSchema11 = {
578
+ var inputSchema10 = {
643
579
  type: "object",
644
580
  properties: {
645
581
  search: { type: "string", description: "\u6309\u540D\u79F0/\u522B\u540D/\u5E73\u53F0ID\u641C\u7D22\u8FC7\u6EE4" },
646
582
  limit: { type: "number", description: "\u6700\u5927\u8FD4\u56DE\u6570\u91CF" }
647
583
  }
648
584
  };
649
- async function handler11(params, context) {
585
+ async function handler10(params, context) {
650
586
  const { locale } = context;
651
587
  const members = await context.dataProvider.getMembers();
652
588
  let filteredMembers = members;
@@ -679,13 +615,13 @@ async function handler11(params, context) {
679
615
  var getMembersTool = {
680
616
  name: "get_members",
681
617
  description: '\u83B7\u53D6\u6210\u5458\u5217\u8868\uFF0C\u5305\u62EC\u6210\u5458\u7684\u57FA\u672C\u4FE1\u606F\u3001\u522B\u540D\u548C\u6D88\u606F\u7EDF\u8BA1\u3002\u9002\u7528\u4E8E\u67E5\u8BE2"\u6709\u54EA\u4E9B\u4EBA"\u3001"\u67D0\u4EBA\u7684\u522B\u540D\u662F\u4EC0\u4E48"\u7B49\u95EE\u9898\u3002',
682
- inputSchema: inputSchema11,
683
- handler: handler11,
618
+ inputSchema: inputSchema10,
619
+ handler: handler10,
684
620
  category: "core"
685
621
  };
686
622
 
687
623
  // ../../packages/tools/src/definitions/member-stats.ts
688
- var inputSchema12 = {
624
+ var inputSchema11 = {
689
625
  type: "object",
690
626
  properties: {
691
627
  top: {
@@ -695,7 +631,7 @@ var inputSchema12 = {
695
631
  }
696
632
  }
697
633
  };
698
- async function handler12(params, context) {
634
+ async function handler11(params, context) {
699
635
  const top = params.top || 20;
700
636
  const members = await context.dataProvider.getMemberStats({ timeFilter: context.timeFilter, top });
701
637
  const data = {
@@ -714,13 +650,13 @@ async function handler12(params, context) {
714
650
  var memberStatsTool = {
715
651
  name: "get_member_stats",
716
652
  description: "\u83B7\u53D6\u6210\u5458\u6D3B\u8DC3\u5EA6\u6392\u884C\uFF0C\u5305\u62EC\u6D88\u606F\u6570\u91CF\u548C\u5360\u6BD4",
717
- inputSchema: inputSchema12,
718
- handler: handler12,
653
+ inputSchema: inputSchema11,
654
+ handler: handler11,
719
655
  category: "core"
720
656
  };
721
657
 
722
658
  // ../../packages/tools/src/definitions/time-stats.ts
723
- var inputSchema13 = {
659
+ var inputSchema12 = {
724
660
  type: "object",
725
661
  properties: {
726
662
  type: {
@@ -731,7 +667,7 @@ var inputSchema13 = {
731
667
  }
732
668
  }
733
669
  };
734
- async function handler13(params, context) {
670
+ async function handler12(params, context) {
735
671
  const type = params.type || "hourly";
736
672
  const data = await context.dataProvider.getTimeStats(type, { timeFilter: context.timeFilter });
737
673
  return {
@@ -742,13 +678,13 @@ async function handler13(params, context) {
742
678
  var timeStatsTool = {
743
679
  name: "get_time_stats",
744
680
  description: "\u83B7\u53D6\u804A\u5929\u6D3B\u8DC3\u65F6\u6BB5\u5206\u5E03\uFF08\u6309\u5C0F\u65F6/\u661F\u671F/\u6BCF\u65E5\u8D8B\u52BF\uFF09",
745
- inputSchema: inputSchema13,
746
- handler: handler13,
681
+ inputSchema: inputSchema12,
682
+ handler: handler12,
747
683
  category: "core"
748
684
  };
749
685
 
750
686
  // ../../packages/tools/src/definitions/recent-messages.ts
751
- var inputSchema14 = {
687
+ var inputSchema13 = {
752
688
  type: "object",
753
689
  properties: {
754
690
  limit: {
@@ -759,7 +695,7 @@ var inputSchema14 = {
759
695
  ...timeParamProperties
760
696
  }
761
697
  };
762
- async function handler14(params, context) {
698
+ async function handler13(params, context) {
763
699
  const { locale, timeFilter: contextTimeFilter, maxMessagesLimit } = context;
764
700
  const limit = maxMessagesLimit || params.limit || 100;
765
701
  const effectiveTimeFilter = parseExtendedTimeParams(params, contextTimeFilter);
@@ -779,21 +715,21 @@ async function handler14(params, context) {
779
715
  var recentMessagesTool = {
780
716
  name: "get_recent_messages",
781
717
  description: '\u83B7\u53D6\u6307\u5B9A\u65F6\u95F4\u6BB5\u5185\u7684\u7FA4\u804A\u6D88\u606F\u3002\u9002\u7528\u4E8E\u56DE\u7B54"\u6700\u8FD1\u5927\u5BB6\u804A\u4E86\u4EC0\u4E48"\u7B49\u6982\u89C8\u6027\u95EE\u9898\u3002\u652F\u6301\u7CBE\u786E\u5230\u5206\u949F\u7EA7\u522B\u7684\u65F6\u95F4\u67E5\u8BE2\u3002',
782
- inputSchema: inputSchema14,
783
- handler: handler14,
718
+ inputSchema: inputSchema13,
719
+ handler: handler13,
784
720
  category: "core",
785
721
  truncationStrategy: "keep_last"
786
722
  };
787
723
 
788
724
  // ../../packages/tools/src/definitions/get-member-name-history.ts
789
- var inputSchema15 = {
725
+ var inputSchema14 = {
790
726
  type: "object",
791
727
  properties: {
792
728
  member_id: { type: "number", description: "\u6210\u5458 ID\uFF08\u901A\u8FC7 get_members \u83B7\u53D6\uFF09" }
793
729
  },
794
730
  required: ["member_id"]
795
731
  };
796
- async function handler15(params, context) {
732
+ async function handler14(params, context) {
797
733
  const { locale } = context;
798
734
  const memberId = params.member_id;
799
735
  const members = await context.dataProvider.getMembers();
@@ -829,13 +765,13 @@ async function handler15(params, context) {
829
765
  var getMemberNameHistoryTool = {
830
766
  name: "get_member_name_history",
831
767
  description: '\u83B7\u53D6\u6210\u5458\u7684\u6635\u79F0\u53D8\u66F4\u5386\u53F2\u8BB0\u5F55\u3002\u9002\u7528\u4E8E\u56DE\u7B54"\u67D0\u4EBA\u4EE5\u524D\u53EB\u4EC0\u4E48\u540D\u5B57"\u3001"\u67D0\u4EBA\u7684\u6635\u79F0\u53D8\u5316"\u7B49\u95EE\u9898\u3002',
832
- inputSchema: inputSchema15,
833
- handler: handler15,
768
+ inputSchema: inputSchema14,
769
+ handler: handler14,
834
770
  category: "analysis"
835
771
  };
836
772
 
837
773
  // ../../packages/tools/src/definitions/get-conversation-between.ts
838
- var inputSchema16 = {
774
+ var inputSchema15 = {
839
775
  type: "object",
840
776
  properties: {
841
777
  member_id_1: { type: "number", description: "\u7B2C\u4E00\u4E2A\u6210\u5458\u7684 ID\uFF08\u901A\u8FC7 get_members \u83B7\u53D6\uFF09" },
@@ -845,7 +781,7 @@ var inputSchema16 = {
845
781
  },
846
782
  required: ["member_id_1", "member_id_2"]
847
783
  };
848
- async function handler16(params, context) {
784
+ async function handler15(params, context) {
849
785
  const { locale, timeFilter: contextTimeFilter, maxMessagesLimit } = context;
850
786
  const limit = maxMessagesLimit || params.limit || 100;
851
787
  const effectiveTimeFilter = parseExtendedTimeParams(params, contextTimeFilter);
@@ -876,14 +812,14 @@ async function handler16(params, context) {
876
812
  var getConversationBetweenTool = {
877
813
  name: "get_conversation_between",
878
814
  description: '\u83B7\u53D6\u4E24\u4E2A\u7FA4\u6210\u5458\u4E4B\u95F4\u7684\u5BF9\u8BDD\u8BB0\u5F55\u3002\u9002\u7528\u4E8E\u56DE\u7B54"A\u548CB\u4E4B\u95F4\u804A\u4E86\u4EC0\u4E48"\u7B49\u95EE\u9898\u3002\u9700\u8981\u5148\u901A\u8FC7 get_members \u83B7\u53D6\u6210\u5458 ID\u3002',
879
- inputSchema: inputSchema16,
880
- handler: handler16,
815
+ inputSchema: inputSchema15,
816
+ handler: handler15,
881
817
  category: "analysis",
882
818
  truncationStrategy: "keep_last"
883
819
  };
884
820
 
885
821
  // ../../packages/tools/src/definitions/get-segment-summaries.ts
886
- var inputSchema17 = {
822
+ var inputSchema16 = {
887
823
  type: "object",
888
824
  properties: {
889
825
  keywords: { type: "array", items: { type: "string" }, description: "\u6309\u5173\u952E\u8BCD\u8FC7\u6EE4\u6458\u8981\u5185\u5BB9" },
@@ -891,7 +827,7 @@ var inputSchema17 = {
891
827
  ...timeParamProperties
892
828
  }
893
829
  };
894
- async function handler17(params, context) {
830
+ async function handler16(params, context) {
895
831
  const { locale, timeFilter: contextTimeFilter } = context;
896
832
  const limit = params.limit || 20;
897
833
  const effectiveTimeFilter = parseExtendedTimeParams(params, contextTimeFilter);
@@ -937,20 +873,20 @@ async function handler17(params, context) {
937
873
  var getSegmentSummariesTool = {
938
874
  name: "get_segment_summaries",
939
875
  description: "\u83B7\u53D6\u6BB5\u843D\u6458\u8981\u5217\u8868\uFF0C\u5FEB\u901F\u4E86\u89E3\u7FA4\u804A\u5386\u53F2\u8BA8\u8BBA\u7684\u4E3B\u9898\u3002\u53EF\u4EE5\u6309\u5173\u952E\u8BCD\u641C\u7D22\u8BA8\u8BBA\u8FC7\u7684\u8BDD\u9898\u3002",
940
- inputSchema: inputSchema17,
941
- handler: handler17,
876
+ inputSchema: inputSchema16,
877
+ handler: handler16,
942
878
  category: "analysis"
943
879
  };
944
880
 
945
881
  // ../../packages/tools/src/definitions/response-time-analysis.ts
946
- var inputSchema18 = {
882
+ var inputSchema17 = {
947
883
  type: "object",
948
884
  properties: {
949
885
  days: { type: "number", description: "\u5206\u6790\u6700\u8FD1\u591A\u5C11\u5929\u7684\u6570\u636E\uFF0C\u9ED8\u8BA4 30" },
950
886
  top_n: { type: "number", description: "\u8FD4\u56DE\u524D\u591A\u5C11\u540D\uFF0C\u9ED8\u8BA4 10" }
951
887
  }
952
888
  };
953
- async function handler18(params, context) {
889
+ async function handler17(params, context) {
954
890
  const { locale } = context;
955
891
  const isZh = isChineseLocale(locale);
956
892
  const days = params.days || 30;
@@ -1015,20 +951,20 @@ async function handler18(params, context) {
1015
951
  var responseTimeAnalysisTool = {
1016
952
  name: "response_time_analysis",
1017
953
  description: "\u5206\u6790\u7FA4\u6210\u5458\u7684\u54CD\u5E94\u901F\u5EA6\u6392\u884C\uFF0C\u57FA\u4E8E\u56DE\u590D\u95F4\u9694\u7684\u4E2D\u4F4D\u6570\u548C\u5E73\u5747\u503C\u3002",
1018
- inputSchema: inputSchema18,
1019
- handler: handler18,
954
+ inputSchema: inputSchema17,
955
+ handler: handler17,
1020
956
  category: "analysis"
1021
957
  };
1022
958
 
1023
959
  // ../../packages/tools/src/definitions/keyword-frequency.ts
1024
- var inputSchema19 = {
960
+ var inputSchema18 = {
1025
961
  type: "object",
1026
962
  properties: {
1027
963
  days: { type: "number", description: "\u5206\u6790\u6700\u8FD1\u591A\u5C11\u5929\u7684\u6570\u636E\uFF0C\u9ED8\u8BA4 30" },
1028
964
  top_n: { type: "number", description: "\u8FD4\u56DE\u524D\u591A\u5C11\u4E2A\u9AD8\u9891\u8BCD\uFF0C\u9ED8\u8BA4 50" }
1029
965
  }
1030
966
  };
1031
- async function handler19(params, context) {
967
+ async function handler18(params, context) {
1032
968
  const { locale, segmentText } = context;
1033
969
  const isZh = isChineseLocale(locale);
1034
970
  const days = params.days || 30;
@@ -1076,9 +1012,415 @@ async function handler19(params, context) {
1076
1012
  var keywordFrequencyTool = {
1077
1013
  name: "keyword_frequency",
1078
1014
  description: "\u7EDF\u8BA1\u7FA4\u804A\u4E2D\u7684\u9AD8\u9891\u5173\u952E\u8BCD\uFF0C\u901A\u8FC7 NLP \u5206\u8BCD\u5206\u6790\u6D88\u606F\u5185\u5BB9\u3002",
1015
+ inputSchema: inputSchema18,
1016
+ handler: handler18,
1017
+ category: "analysis"
1018
+ };
1019
+
1020
+ // ../../packages/tools/src/types.ts
1021
+ var SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP = 20;
1022
+
1023
+ // ../../packages/tools/src/definitions/semantic-search-current-chat.ts
1024
+ var inputSchema19 = {
1025
+ type: "object",
1026
+ properties: {
1027
+ query: {
1028
+ type: "string",
1029
+ description: "\u8BED\u4E49\u68C0\u7D22\u67E5\u8BE2\uFF0C\u5E94\u6539\u5199\u6210\u9002\u5408\u68C0\u7D22\u5F53\u524D\u804A\u5929\u5386\u53F2\u7684\u81EA\u7136\u8BED\u8A00\u63CF\u8FF0\uFF08\u56F4\u7ED5\u9700\u8981\u786E\u8BA4\u7684\u4E8B\u5B9E/\u4EBA\u7269/\u5730\u70B9/\u4E8B\u4EF6/\u8FC7\u5F80\u63D0\u53CA\uFF09\u3002"
1030
+ },
1031
+ max_results: {
1032
+ type: "number",
1033
+ description: `\u671F\u671B\u8FD4\u56DE\u7684\u76F8\u5173\u7247\u6BB5\u6570\uFF0C\u53EF\u9009\u3002\u4E0D\u586B\u4F7F\u7528\u7528\u6237\u914D\u7F6E\u7684\u9ED8\u8BA4\u503C\uFF1B\u53EF\u6309\u95EE\u9898\u590D\u6742\u5EA6\u63D0\u9AD8\uFF0C\u786C\u4E0A\u9650 ${SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP}\u3002`,
1034
+ minimum: 1,
1035
+ maximum: SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP
1036
+ }
1037
+ },
1038
+ required: ["query"]
1039
+ };
1040
+ async function handler19(params, context) {
1041
+ const service = context.semanticIndexService;
1042
+ if (!service) {
1043
+ return { content: "Semantic search is not available for this conversation." };
1044
+ }
1045
+ const query = typeof params.query === "string" ? params.query.trim() : "";
1046
+ if (!query) {
1047
+ return { content: "Please provide a non-empty query describing what to look up in this conversation history." };
1048
+ }
1049
+ const maxResults = typeof params.max_results === "number" && Number.isFinite(params.max_results) ? Math.max(1, Math.min(SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP, Math.floor(params.max_results))) : void 0;
1050
+ const result = await service.searchForTool(context.sessionId, query, {
1051
+ maxResults,
1052
+ preprocessConfig: context.preprocessConfig,
1053
+ ownerPlatformId: context.ownerPlatformId,
1054
+ locale: context.locale,
1055
+ maxResultTokens: context.maxToolResultTokens,
1056
+ timeFilter: context.timeFilter ? { startTs: context.timeFilter.startTs * 1e3, endTs: context.timeFilter.endTs * 1e3 } : void 0
1057
+ });
1058
+ if (!result.available) {
1059
+ return { content: `No semantic index available for this conversation (${result.reason ?? "unavailable"}).` };
1060
+ }
1061
+ const data = {
1062
+ query,
1063
+ returned: result.returned,
1064
+ hitCount: result.hitCount,
1065
+ partial: result.partial,
1066
+ coverage: result.coverage,
1067
+ truncated: result.truncated,
1068
+ timeRange: result.timeRange,
1069
+ sources: result.sources
1070
+ };
1071
+ if (result.returned === 0) {
1072
+ return { content: "No relevant excerpts found in this conversation history.", data };
1073
+ }
1074
+ let content = result.text;
1075
+ if (result.partial) {
1076
+ content = `Note: index is incomplete, evidence may be partial.
1077
+
1078
+ ${content}`;
1079
+ }
1080
+ if (result.truncated) {
1081
+ content = `${content}
1082
+
1083
+ Reached the result limit; there may be more matching history. Use a narrower query to continue searching.`;
1084
+ }
1085
+ return { content, data };
1086
+ }
1087
+ var semanticSearchCurrentChatTool = {
1088
+ name: "semantic_search_current_chat",
1089
+ description: "Semantically search the CURRENT conversation history for relevant excerpts. Use when the question needs concrete facts, people, places, events, or past mentions from this chat. Do NOT use for greetings, writing, or explaining general concepts.",
1079
1090
  inputSchema: inputSchema19,
1080
1091
  handler: handler19,
1081
- category: "analysis"
1092
+ category: "core",
1093
+ truncationStrategy: "keep_first"
1094
+ };
1095
+
1096
+ // ../../packages/tools/src/definitions/retrieve-chat-evidence.ts
1097
+ var EVIDENCE_GROUP_GAP_SECONDS = 2 * 60 * 60;
1098
+ var EVIDENCE_GROUP_GAP_MS = EVIDENCE_GROUP_GAP_SECONDS * 1e3;
1099
+ var EVIDENCE_GROUP_MAX_SOURCES = 5;
1100
+ var EVIDENCE_SNIPPET_MAX_CHARS = 160;
1101
+ var KEYWORD_DEFAULT_LIMIT = 80;
1102
+ var PLANNING_WORDS = ["\u51C6\u5907", "\u6253\u7B97", "\u653B\u7565", "\u60F3\u53BB", "\u8BA1\u5212", "\u8981\u4E0D\u8981\u53BB", "\u8003\u8651\u53BB", "\u5B89\u6392\u4E00\u4E0B"];
1103
+ var EVIDENCE_WORDS = ["\u5230\u4E86", "\u5230\u8FBE", "\u51FA\u53D1", "\u8FD4\u7A0B", "\u56DE\u6765", "\u5165\u4F4F", "\u4F4F\u4E86", "\u95E8\u7968", "\u5408\u5F71", "\u6253\u5361", "\u73A9\u4E86"];
1104
+ var inputSchema20 = {
1105
+ type: "object",
1106
+ properties: {
1107
+ query: {
1108
+ type: "string",
1109
+ description: "\u9700\u8981\u7528\u804A\u5929\u8BC1\u636E\u786E\u8BA4\u7684\u95EE\u9898/\u68C0\u7D22\u76EE\u6807\uFF0C\u4F8B\u5982\u201C\u6211\u4EEC\u53BB\u4E50\u5C71\u65C5\u884C\u8FC7\u591A\u5C11\u6B21\u201D\u3002"
1110
+ },
1111
+ criteria: {
1112
+ type: "string",
1113
+ description: "\u5224\u5B9A\u6807\u51C6\uFF1A\u4EC0\u4E48\u7B97\u8BA1\u5165\u3001\u4EC0\u4E48\u4E0D\u8BA1\u5165\u3002\u7EDF\u8BA1/\u5224\u65AD\u7C7B\u95EE\u9898\u5E94\u586B\u5199\uFF0C\u4F8B\u5982\u201C\u8BA1\u5165\uFF1A\u6709\u5B9E\u9645\u51FA\u884C/\u5230\u8FBE/\u4F4F\u5BBF\u8BC1\u636E\uFF1B\u4E0D\u8BA1\u5165\uFF1A\u4EC5\u8BA1\u5212\u3001\u653B\u7565\u3001\u522B\u4EBA\u7ECF\u5386\u3001\u6CDB\u804A\u201D\u3002"
1114
+ },
1115
+ keywords: {
1116
+ type: "array",
1117
+ items: { type: "string" },
1118
+ description: "\u5173\u952E\u8BCD\u5217\u8868\uFF0C\u7531\u4F60\u663E\u5F0F\u7ED9\u51FA\uFF08\u5DE5\u5177\u4E0D\u505A\u540C\u4E49\u8BCD\u6269\u5C55\uFF09\u3002hybrid/keyword \u6A21\u5F0F\u7528\u4E8E\u7CBE\u786E\u53EC\u56DE\u3002"
1119
+ },
1120
+ mode: {
1121
+ type: "string",
1122
+ enum: ["auto", "hybrid", "semantic", "keyword"],
1123
+ description: "auto(\u9ED8\u8BA4)/hybrid(\u8BED\u4E49+\u5173\u952E\u8BCD)/semantic(\u4EC5\u8BED\u4E49)/keyword(\u4EC5\u5173\u952E\u8BCD)\u3002\u5386\u53F2\u4E8B\u5B9E\u7EDF\u8BA1\u901A\u5E38\u7528 hybrid\u3002"
1124
+ },
1125
+ max_results: {
1126
+ type: "number",
1127
+ description: `\u8BED\u4E49\u8DEF\u5F84\u671F\u671B\u8FD4\u56DE\u7247\u6BB5\u6570\uFF0C\u786C\u4E0A\u9650 ${SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP}\u3002`,
1128
+ minimum: 1,
1129
+ maximum: SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP
1130
+ },
1131
+ ...timeParamProperties
1132
+ },
1133
+ required: ["query"]
1134
+ };
1135
+ function isChinese(locale) {
1136
+ return !locale || locale.toLowerCase().startsWith("zh");
1137
+ }
1138
+ function truncateSnippet(text) {
1139
+ const t2 = text.trim();
1140
+ return t2.length > EVIDENCE_SNIPPET_MAX_CHARS ? `${t2.slice(0, EVIDENCE_SNIPPET_MAX_CHARS)}\u2026` : t2;
1141
+ }
1142
+ var LINE_TIME_PREFIX = /^\s*\d{1,4}[/-]\d{1,2}[/-]\d{1,4},?\s+\d{1,2}:\d{2}(?::\d{2})?(?:\s?[APap][Mm])?\s+/;
1143
+ function stripLineTimestamps(text) {
1144
+ return text.split("\n").map((line) => line.replace(LINE_TIME_PREFIX, "")).join("\n").trim();
1145
+ }
1146
+ function parseDateMs(s) {
1147
+ if (typeof s !== "string" || !s.trim()) return void 0;
1148
+ const d = new Date(s.trim().replace(" ", "T"));
1149
+ const t2 = d.getTime();
1150
+ return Number.isNaN(t2) ? void 0 : t2;
1151
+ }
1152
+ function parseIsoMs(s) {
1153
+ if (!s) return void 0;
1154
+ const t2 = Date.parse(s);
1155
+ return Number.isNaN(t2) ? void 0 : t2;
1156
+ }
1157
+ function parseEvidenceTimeRange(params, context) {
1158
+ const startMs = parseDateMs(params.start_time);
1159
+ const endMs = parseDateMs(params.end_time);
1160
+ if (startMs != null || endMs != null) {
1161
+ return { startTs: startMs, endTs: endMs };
1162
+ }
1163
+ if (context.timeFilter) {
1164
+ return { startTs: context.timeFilter.startTs * 1e3, endTs: context.timeFilter.endTs * 1e3 };
1165
+ }
1166
+ return void 0;
1167
+ }
1168
+ function overlapsTimeRangeMs(startMs, endMs, filter) {
1169
+ if (!filter) return true;
1170
+ if (filter.startTs != null && endMs < filter.startTs) return false;
1171
+ if (filter.endTs != null && startMs > filter.endTs) return false;
1172
+ return true;
1173
+ }
1174
+ function clampMaxResults(value) {
1175
+ if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
1176
+ return Math.max(1, Math.min(SEMANTIC_SEARCH_MAX_RESULTS_HARD_CAP, Math.floor(value)));
1177
+ }
1178
+ function toKeywordTimeFilter(rangeMs) {
1179
+ if (!rangeMs) return void 0;
1180
+ const filter = {};
1181
+ if (rangeMs.startTs != null) filter.startTs = Math.floor(rangeMs.startTs / 1e3);
1182
+ if (rangeMs.endTs != null) filter.endTs = Math.floor(rangeMs.endTs / 1e3);
1183
+ return Object.keys(filter).length > 0 ? filter : void 0;
1184
+ }
1185
+ function resolveMode(requested, semanticAvailable, hasKeywords) {
1186
+ const warnings = /* @__PURE__ */ new Set();
1187
+ if (requested !== "auto") return { mode: requested, warnings };
1188
+ if (semanticAvailable && hasKeywords) return { mode: "hybrid", warnings };
1189
+ if (semanticAvailable && !hasKeywords) {
1190
+ warnings.add("keywords_missing_for_hybrid");
1191
+ return { mode: "semantic", warnings };
1192
+ }
1193
+ warnings.add("semantic_unavailable");
1194
+ if (!hasKeywords) warnings.add("keywords_required_for_keyword_mode");
1195
+ return { mode: "keyword", warnings };
1196
+ }
1197
+ function keywordMessagesToCandidates(messages, rangeMs, desensitize) {
1198
+ const safe = desensitize ? desensitize(messages) : messages;
1199
+ const candidates = [];
1200
+ for (const m of safe) {
1201
+ if (m.id == null || !m.content) continue;
1202
+ const tsMs = m.timestamp * 1e3;
1203
+ if (!overlapsTimeRangeMs(tsMs, tsMs, rangeMs)) continue;
1204
+ candidates.push({
1205
+ messageId: m.id,
1206
+ timestamp: tsMs,
1207
+ rangeStartMs: tsMs,
1208
+ rangeEndMs: tsMs,
1209
+ snippet: truncateSnippet(m.content),
1210
+ senderName: m.senderName,
1211
+ sourceKind: "keyword"
1212
+ });
1213
+ }
1214
+ return candidates;
1215
+ }
1216
+ function mergeCandidates(semantic, keyword) {
1217
+ const keptKeyword = keyword.filter(
1218
+ (kc) => !semantic.some((sc) => kc.timestamp >= sc.rangeStartMs && kc.timestamp <= sc.rangeEndMs)
1219
+ );
1220
+ const byId = /* @__PURE__ */ new Map();
1221
+ for (const c of [...semantic, ...keptKeyword]) {
1222
+ if (!byId.has(c.messageId)) byId.set(c.messageId, c);
1223
+ }
1224
+ return [...byId.values()].sort((a, b) => a.timestamp - b.timestamp);
1225
+ }
1226
+ function classifyGroup(snippets, hasCriteria, locale) {
1227
+ if (!hasCriteria) return "uncertain";
1228
+ if (!isChinese(locale)) return "uncertain";
1229
+ const joined = snippets.join("\n");
1230
+ const hasEvidence = EVIDENCE_WORDS.some((w) => joined.includes(w));
1231
+ const hasPlanning = PLANNING_WORDS.some((w) => joined.includes(w));
1232
+ if (hasEvidence) return "included";
1233
+ if (hasPlanning) return "excluded";
1234
+ return "uncertain";
1235
+ }
1236
+ function formatDate(ms, locale) {
1237
+ const d = new Date(ms);
1238
+ const y = d.getFullYear();
1239
+ const m = String(d.getMonth() + 1).padStart(2, "0");
1240
+ const day = String(d.getDate()).padStart(2, "0");
1241
+ return isChinese(locale) ? `${y}\u5E74${m}\u6708${day}\u65E5` : `${y}-${m}-${day}`;
1242
+ }
1243
+ function buildGroups(candidates, hasCriteria, locale) {
1244
+ const groups = [];
1245
+ let current = null;
1246
+ let lastTs = 0;
1247
+ for (const c of candidates) {
1248
+ const source = {
1249
+ messageId: c.messageId,
1250
+ startMessageId: c.startMessageId,
1251
+ endMessageId: c.endMessageId,
1252
+ timestamp: c.timestamp,
1253
+ senderName: c.senderName,
1254
+ snippet: c.snippet,
1255
+ sourceKind: c.sourceKind
1256
+ };
1257
+ const continues = current && c.timestamp - lastTs <= EVIDENCE_GROUP_GAP_MS && current.sources.length < EVIDENCE_GROUP_MAX_SOURCES;
1258
+ if (continues && current) {
1259
+ current.sources.push(source);
1260
+ current.timeRange = { startTs: current.timeRange.startTs, endTs: c.timestamp };
1261
+ } else {
1262
+ current = {
1263
+ id: `g${groups.length + 1}`,
1264
+ status: "uncertain",
1265
+ title: "",
1266
+ reason: "",
1267
+ timeRange: { startTs: c.timestamp, endTs: c.timestamp },
1268
+ sources: [source]
1269
+ };
1270
+ groups.push(current);
1271
+ }
1272
+ lastTs = c.timestamp;
1273
+ }
1274
+ const cn = isChinese(locale);
1275
+ for (const g of groups) {
1276
+ const snippets = g.sources.map((s) => s.snippet);
1277
+ g.status = classifyGroup(snippets, hasCriteria, locale);
1278
+ const start = formatDate(g.timeRange.startTs, locale);
1279
+ const end = formatDate(g.timeRange.endTs, locale);
1280
+ g.title = start === end ? start : cn ? `${start} \u81F3 ${end}` : `${start} \u2013 ${end}`;
1281
+ g.reason = cn ? GROUP_REASON_CN[g.status] : GROUP_REASON_EN[g.status];
1282
+ }
1283
+ return groups;
1284
+ }
1285
+ var GROUP_REASON_CN = {
1286
+ included: "\u542B\u5B9E\u9645\u53D1\u751F/\u5230\u8FBE\u7B49\u8BC1\u636E\uFF0C\u5EFA\u8BAE\u8BA1\u5165",
1287
+ excluded: "\u4EC5\u542B\u8BA1\u5212/\u610F\u5411\uFF0C\u672A\u89C1\u5B9E\u9645\u53D1\u751F\u8BC1\u636E\uFF0C\u5EFA\u8BAE\u4E0D\u8BA1\u5165",
1288
+ uncertain: "\u8BC1\u636E\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u786E\u8BA4\u662F\u5426\u8BA1\u5165"
1289
+ };
1290
+ var GROUP_REASON_EN = {
1291
+ included: "Contains concrete evidence of an actual event; suggest counting it.",
1292
+ excluded: "Only plans/intentions without evidence of occurrence; suggest excluding.",
1293
+ uncertain: "Insufficient evidence to confirm."
1294
+ };
1295
+ function buildContent(payload, locale) {
1296
+ const cn = isChinese(locale);
1297
+ const lines = [];
1298
+ lines.push(
1299
+ cn ? `\u8BC1\u636E\u68C0\u7D22\u7ED3\u679C\uFF08mode=${payload.mode}\uFF0Cstatus=${payload.status}\uFF09` : `Evidence (mode=${payload.mode}, status=${payload.status})`
1300
+ );
1301
+ if (payload.warnings && payload.warnings.length > 0) {
1302
+ lines.push((cn ? "\u544A\u8B66: " : "Warnings: ") + payload.warnings.join(", "));
1303
+ }
1304
+ if (payload.groups.length === 0) {
1305
+ lines.push(cn ? "\u672A\u627E\u5230\u53EF\u8BA1\u5165\u7684\u660E\u786E\u8BC1\u636E\u3002" : "No conclusive evidence found.");
1306
+ }
1307
+ for (const g of payload.groups) {
1308
+ lines.push(`
1309
+ [${g.status}] ${g.title} \u2014 ${g.reason}`);
1310
+ for (const s of g.sources) {
1311
+ const who = s.senderName ? `${s.senderName}: ` : "";
1312
+ lines.push(` \xB7 ${who}${s.snippet}`);
1313
+ }
1314
+ }
1315
+ lines.push(
1316
+ cn ? "\n\u8BF7\u57FA\u4E8E\u4EE5\u4E0A\u8BC1\u636E\u4FDD\u5B88\u4F5C\u7B54\uFF1A\u53EA\u628A included \u8BA1\u5165\u786E\u5B9A\u7ED3\u8BBA\uFF0Cexcluded/uncertain \u4E0D\u8BA1\u5165\uFF1B\u8BC1\u636E\u4E0D\u8DB3\u65F6\u56DE\u7B54\u201D\u65E0\u6CD5\u786E\u8BA4\u201D\u3002" : "\nAnswer conservatively: count `included` groups toward the conclusion; for `uncertain` groups, judge based on the snippet content whether evidence of actual occurrence is present; do not count `excluded` groups."
1317
+ );
1318
+ return lines.join("\n");
1319
+ }
1320
+ function computeStatus(anyPathRan, hasResults, warnings) {
1321
+ if (!anyPathRan) return "unavailable";
1322
+ if (!hasResults) return "empty";
1323
+ const degraded = warnings.has("semantic_partial") || warnings.has("semantic_unavailable") || warnings.has("keyword_unavailable");
1324
+ return degraded ? "partial" : "complete";
1325
+ }
1326
+ async function handler20(params, context) {
1327
+ const locale = context.locale;
1328
+ const query = typeof params.query === "string" ? params.query.trim() : "";
1329
+ const criteria = typeof params.criteria === "string" && params.criteria.trim() ? params.criteria.trim() : void 0;
1330
+ const keywords = Array.isArray(params.keywords) ? params.keywords.filter((k) => typeof k === "string" && k.trim()) : [];
1331
+ const requestedMode = params.mode === "hybrid" || params.mode === "semantic" || params.mode === "keyword" || params.mode === "auto" ? params.mode : "auto";
1332
+ const service = context.semanticIndexService;
1333
+ const semanticAvailable = !!service && await service.canSearch(context.sessionId);
1334
+ const rangeMs = parseEvidenceTimeRange(params, context);
1335
+ const { mode, warnings } = resolveMode(requestedMode, semanticAvailable, keywords.length > 0);
1336
+ if (!criteria) warnings.add("criteria_missing");
1337
+ const runSemantic = mode === "semantic" || mode === "hybrid";
1338
+ const runKeyword = mode === "keyword" || mode === "hybrid";
1339
+ let semanticRan = false;
1340
+ let keywordRan = false;
1341
+ const semanticCandidates = [];
1342
+ let keywordCandidates = [];
1343
+ if (runSemantic) {
1344
+ if (!service || !semanticAvailable) {
1345
+ warnings.add("semantic_unavailable");
1346
+ } else {
1347
+ const result = await service.searchForTool(context.sessionId, query, {
1348
+ maxResults: clampMaxResults(params.max_results),
1349
+ preprocessConfig: context.preprocessConfig,
1350
+ ownerPlatformId: context.ownerPlatformId,
1351
+ locale,
1352
+ maxResultTokens: context.maxToolResultTokens,
1353
+ timeFilter: rangeMs
1354
+ });
1355
+ semanticRan = true;
1356
+ if (!result.available) {
1357
+ warnings.add("semantic_unavailable");
1358
+ } else {
1359
+ if (result.partial) warnings.add("semantic_partial");
1360
+ for (const s of result.sources) {
1361
+ const startMs = parseIsoMs(s.startTime);
1362
+ const endMs = parseIsoMs(s.endTime) ?? startMs;
1363
+ if (rangeMs && startMs != null && endMs != null && !overlapsTimeRangeMs(startMs, endMs, rangeMs)) continue;
1364
+ const evidenceText = stripLineTimestamps(s.text || s.snippet);
1365
+ semanticCandidates.push({
1366
+ messageId: s.startMessageId,
1367
+ startMessageId: s.startMessageId,
1368
+ endMessageId: s.endMessageId,
1369
+ timestamp: startMs ?? 0,
1370
+ rangeStartMs: startMs ?? 0,
1371
+ rangeEndMs: endMs ?? startMs ?? 0,
1372
+ snippet: evidenceText,
1373
+ sourceKind: "semantic",
1374
+ score: s.score
1375
+ });
1376
+ }
1377
+ }
1378
+ }
1379
+ }
1380
+ if (runKeyword) {
1381
+ if (keywords.length === 0) {
1382
+ warnings.add(mode === "keyword" ? "keywords_required_for_keyword_mode" : "keywords_missing_for_hybrid");
1383
+ } else if (!context.dataProvider) {
1384
+ warnings.add("keyword_unavailable");
1385
+ } else {
1386
+ const secFilter = toKeywordTimeFilter(rangeMs);
1387
+ const searchResult = await context.dataProvider.searchMessages(keywords, {
1388
+ timeFilter: secFilter,
1389
+ limit: context.maxMessagesLimit || KEYWORD_DEFAULT_LIMIT
1390
+ });
1391
+ keywordRan = true;
1392
+ keywordCandidates = keywordMessagesToCandidates(searchResult.messages, rangeMs, context.desensitizeMessages);
1393
+ }
1394
+ }
1395
+ const merged = mergeCandidates(semanticCandidates, keywordCandidates);
1396
+ const groups = buildGroups(merged, !!criteria, locale);
1397
+ const status = computeStatus(semanticRan || keywordRan, groups.length > 0, warnings);
1398
+ const payload = {
1399
+ version: 1,
1400
+ query,
1401
+ criteria,
1402
+ mode,
1403
+ status,
1404
+ warnings: warnings.size > 0 ? [...warnings] : void 0,
1405
+ groups
1406
+ };
1407
+ if (rangeMs) {
1408
+ payload.appliedTimeFilter = {
1409
+ startTs: rangeMs.startTs,
1410
+ endTs: rangeMs.endTs
1411
+ };
1412
+ }
1413
+ const cn = isChinese(locale);
1414
+ payload.summary = groups.length === 0 ? cn ? "\u672A\u627E\u5230\u660E\u786E\u53EF\u8BA1\u5165\u7684\u8BC1\u636E\u3002" : "No conclusive evidence found." : cn ? `\u5171 ${groups.length} \u7EC4\u5019\u9009\u8BC1\u636E\u3002` : `${groups.length} candidate evidence group(s).`;
1415
+ return { content: buildContent(payload, locale), data: { evidence: payload } };
1416
+ }
1417
+ var retrieveChatEvidenceTool = {
1418
+ name: "retrieve_chat_evidence",
1419
+ description: 'Retrieve and assemble conservative, de-identified evidence from the CURRENT conversation for fact/occurrence/count questions (e.g. "how many times did we...", "did we ever...", "prove from chat history..."). Runs semantic + keyword retrieval, groups results, and returns a structured evidence payload. Prefer this over search_messages/semantic_search_current_chat for evidence-chain or counting questions.',
1420
+ inputSchema: inputSchema20,
1421
+ handler: handler20,
1422
+ category: "core",
1423
+ truncationStrategy: "keep_first"
1082
1424
  };
1083
1425
 
1084
1426
  // ../../packages/tools/src/sql/definitions.ts
@@ -1192,7 +1534,7 @@ var SQL_TOOL_DEFS = [
1192
1534
  },
1193
1535
  execution: {
1194
1536
  type: "sqlite",
1195
- query: "SELECT COALESCE(m1.group_nickname, m1.account_name) AS member_a, COALESCE(m2.group_nickname, m2.account_name) AS member_b, COUNT(*) AS interaction_count FROM message a JOIN message b ON b.sender_id != a.sender_id AND b.ts > a.ts AND b.ts <= a.ts + 300 JOIN member m1 ON a.sender_id = m1.id JOIN member m2 ON b.sender_id = m2.id WHERE a.sender_id < b.sender_id AND a.ts > unixepoch('now', '-' || @days || ' days') AND a.type = 0 AND b.type = 0 GROUP BY a.sender_id, b.sender_id ORDER BY interaction_count DESC LIMIT @limit",
1537
+ query: "WITH ordered_messages AS (SELECT id, sender_id, ts, LAG(sender_id) OVER (ORDER BY ts, id) AS prev_sender_id, LAG(ts) OVER (ORDER BY ts, id) AS prev_ts FROM message WHERE type = 0 AND ts > unixepoch('now', '-' || @days || ' days')), pairs AS (SELECT CASE WHEN prev_sender_id < sender_id THEN prev_sender_id ELSE sender_id END AS member_a_id, CASE WHEN prev_sender_id < sender_id THEN sender_id ELSE prev_sender_id END AS member_b_id FROM ordered_messages WHERE prev_sender_id IS NOT NULL AND prev_sender_id != sender_id AND prev_ts IS NOT NULL AND ts <= prev_ts + 300) SELECT COALESCE(m1.group_nickname, m1.account_name) AS member_a, COALESCE(m2.group_nickname, m2.account_name) AS member_b, COUNT(*) AS interaction_count FROM pairs JOIN member m1 ON pairs.member_a_id = m1.id JOIN member m2 ON pairs.member_b_id = m2.id GROUP BY member_a_id, member_b_id ORDER BY interaction_count DESC LIMIT @limit",
1196
1538
  rowTemplate: "{member_a} \u2194 {member_b}\uFF1A{interaction_count} \u6B21\u4E92\u52A8",
1197
1539
  summaryTemplate: "\u4E92\u52A8\u6700\u9891\u7E41\u7684 {rowCount} \u5BF9\u597D\u53CB\uFF1A",
1198
1540
  fallback: "\u8BE5\u65F6\u95F4\u8303\u56F4\u5185\u6CA1\u6709\u68C0\u6D4B\u5230\u660E\u663E\u7684\u4E92\u52A8\u5173\u7CFB"
@@ -1351,7 +1693,6 @@ var SHARED_TOOLS = [
1351
1693
  deepSearchMessagesTool,
1352
1694
  recentMessagesTool,
1353
1695
  getMessageContextTool,
1354
- searchSegmentsTool,
1355
1696
  getSegmentMessagesTool,
1356
1697
  getMembersTool,
1357
1698
  schemaTool,
@@ -1367,7 +1708,14 @@ var SHARED_TOOLS = [
1367
1708
  // Raw SQL
1368
1709
  sqlQueryTool
1369
1710
  ];
1370
- var AGENT_TOOL_REGISTRY = [...SHARED_TOOLS, ...createAllSqlToolDefinitions(SQL_TOOL_DEFS)];
1711
+ var AGENT_TOOL_REGISTRY = [
1712
+ ...SHARED_TOOLS,
1713
+ semanticSearchCurrentChatTool,
1714
+ retrieveChatEvidenceTool,
1715
+ ...createAllSqlToolDefinitions(SQL_TOOL_DEFS)
1716
+ ];
1717
+ var SEMANTIC_SEARCH_TOOL_NAME = semanticSearchCurrentChatTool.name;
1718
+ var RETRIEVE_CHAT_EVIDENCE_TOOL_NAME = retrieveChatEvidenceTool.name;
1371
1719
  var MCP_TOOL_REGISTRY = [
1372
1720
  // MCP-specific: session discovery & schema
1373
1721
  sessionsListTool,
@@ -1383,8 +1731,12 @@ var CoreDataProvider = class {
1383
1731
  }
1384
1732
  db;
1385
1733
  async searchMessages(keywords, options) {
1386
- const keyword = keywords.join(" ");
1387
- const result = searchMessagesLike(this.db, keyword, { limit: options?.limit ?? 50 });
1734
+ const result = searchMessagesByKeywords(this.db, keywords, {
1735
+ startTs: options?.timeFilter?.startTs,
1736
+ endTs: options?.timeFilter?.endTs,
1737
+ senderId: options?.senderId,
1738
+ limit: options?.limit ?? 50
1739
+ });
1388
1740
  return {
1389
1741
  messages: result.messages.map((m) => ({
1390
1742
  id: m.id,
@@ -1450,9 +1802,6 @@ var CoreDataProvider = class {
1450
1802
  return getHourlyActivity(this.db, filter);
1451
1803
  }
1452
1804
  }
1453
- async searchSegments(keywords, timeFilter, limit, previewCount) {
1454
- return searchSegments(this.db, keywords, timeFilter, limit, previewCount);
1455
- }
1456
1805
  async getSegmentMessages(segmentId, limit) {
1457
1806
  return getSegmentMessages(this.db, segmentId, limit);
1458
1807
  }
@@ -1475,7 +1824,8 @@ var CoreDataProvider = class {
1475
1824
 
1476
1825
  export {
1477
1826
  AGENT_TOOL_REGISTRY,
1827
+ SEMANTIC_SEARCH_TOOL_NAME,
1478
1828
  MCP_TOOL_REGISTRY,
1479
1829
  CoreDataProvider
1480
1830
  };
1481
- //# sourceMappingURL=chunk-RMITK4IC.mjs.map
1831
+ //# sourceMappingURL=chunk-WQMKKUSD.mjs.map