chatlab-cli 0.31.2 → 0.31.3

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 (111) hide show
  1. package/dist/{chat-command-QPL4GNHP.mjs → chat-command-ZIXKNLSE.mjs} +15 -9
  2. package/dist/chat-command-ZIXKNLSE.mjs.map +1 -0
  3. package/dist/{chunk-OAXVKNPN.mjs → chunk-23AIEWCD.mjs} +2 -2
  4. package/dist/{chunk-F2NZ7HAY.mjs → chunk-3J7WTUEE.mjs} +2 -2
  5. package/dist/{chunk-GYPBWKAU.mjs → chunk-75FZ26HM.mjs} +896 -439
  6. package/dist/chunk-75FZ26HM.mjs.map +1 -0
  7. package/dist/{chunk-OQ6N4PDD.mjs → chunk-BLOBEOCG.mjs} +2 -2
  8. package/dist/{chunk-6JKKHPXY.mjs → chunk-DV4U34MR.mjs} +2 -2
  9. package/dist/{chunk-ZCXCHKQV.mjs → chunk-EINCXXWY.mjs} +3 -3
  10. package/dist/{chunk-3SZWD7UM.mjs → chunk-FDLLEDNW.mjs} +79 -20
  11. package/dist/chunk-FDLLEDNW.mjs.map +1 -0
  12. package/dist/{chunk-BSSR4ZYW.mjs → chunk-GZO3NAHC.mjs} +2130 -2018
  13. package/dist/chunk-GZO3NAHC.mjs.map +1 -0
  14. package/dist/{chunk-S5PQM5J4.mjs → chunk-MFOCDGCC.mjs} +17 -4
  15. package/dist/chunk-MFOCDGCC.mjs.map +1 -0
  16. package/dist/{chunk-64FKPYPJ.mjs → chunk-UIUEG7JB.mjs} +11 -11
  17. package/dist/{chunk-IK7GJTGY.mjs → chunk-YVNZ73O5.mjs} +147 -266
  18. package/dist/chunk-YVNZ73O5.mjs.map +1 -0
  19. package/dist/cli.mjs +8 -8
  20. package/dist/contacts-worker.mjs +2 -2
  21. package/dist/global-insight-worker.mjs +1 -1
  22. package/dist/{http-NOEWVWCP.mjs → http-WDG2OHOV.mjs} +11 -11
  23. package/dist/{import-RS3HW7ZM.mjs → import-4BDC37F7.mjs} +7 -7
  24. package/dist/index.mjs +11 -11
  25. package/dist/{mcp-7F3G47Z4.mjs → mcp-4KUVRGFF.mjs} +8 -8
  26. package/dist/people-relationships-worker.mjs +2 -2
  27. package/dist/semantic-index-worker.mjs +1 -1
  28. package/dist/{src-MNH5S423.mjs → src-ZOCLFBCJ.mjs} +28 -6
  29. package/dist/{stream-import-BPCHGRAN.mjs → stream-import-ERTT7U6V.mjs} +7 -7
  30. package/dist/{worker-runtime-TTAXGQ5R.mjs → worker-runtime-2TUZHV7W.mjs} +5 -5
  31. package/dist-web/assets/ActionToolsPanel-Dp-ojXjO.css +1 -0
  32. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-GgQ5ueMX.js +110 -0
  33. package/dist-web/assets/{BufferResource-Dh2kaMuP.js → BufferResource-DgKoy0Ii.js} +1 -1
  34. package/dist-web/assets/{CanvasRenderer-B8hHywwz.js → CanvasRenderer-CKpp71xg.js} +1 -1
  35. package/dist-web/assets/{EChartWordcloud-BXC_4nUP.js → EChartWordcloud-CSOuFvyM.js} +1 -1
  36. package/dist-web/assets/{Filter-Bap1KMW6.js → Filter-D32zqY5x.js} +1 -1
  37. package/dist-web/assets/{LoadingState.vue_vue_type_script_setup_true_lang-B2KAoiMG.js → LoadingState.vue_vue_type_script_setup_true_lang-DUAtrSZD.js} +1 -1
  38. package/dist-web/assets/{MessageExportModal-H3-LAaXY.js → MessageExportModal-BYLw4vZ8.js} +1 -1
  39. package/dist-web/assets/{PageHeader-CzTV_lyM.js → PageHeader-Dmu6cdAk.js} +1 -1
  40. package/dist-web/assets/{RelationshipGalaxyCanvas-C6ZoUZNc.js → RelationshipGalaxyCanvas-DsMOubHV.js} +3 -3
  41. package/dist-web/assets/{RelationshipGalaxyThreeCanvas-DV6B-7XB.js → RelationshipGalaxyThreeCanvas-Dh5HjVHr.js} +1 -1
  42. package/dist-web/assets/{RenderTargetSystem-Dpgyoac_.js → RenderTargetSystem-CovK4x_D.js} +1 -1
  43. package/dist-web/assets/{ThemeCard.vue_vue_type_script_setup_true_lang-BWJ6kuSC.js → ThemeCard.vue_vue_type_script_setup_true_lang-DhUfYrEx.js} +1 -1
  44. package/dist-web/assets/{TimeSelect.vue_vue_type_script_setup_true_lang--Tbo7p-l.js → TimeSelect.vue_vue_type_script_setup_true_lang-CaumhCAS.js} +1 -1
  45. package/dist-web/assets/{WebGLRenderer-DICnsAm5.js → WebGLRenderer-CawhbcYU.js} +1 -1
  46. package/dist-web/assets/{WebGPURenderer-Bf0gkRK9.js → WebGPURenderer-B7P1D2sA.js} +1 -1
  47. package/dist-web/assets/{annual-summary-time-range-CK0IIPsY.js → annual-summary-time-range-Bya4h2j6.js} +1 -1
  48. package/dist-web/assets/{base-D5T8QZ8b.js → base-ClGWE9aq.js} +1 -1
  49. package/dist-web/assets/{browserAll-DcoCy7xY.js → browserAll-CtQkc1DF.js} +1 -1
  50. package/dist-web/assets/{dateFormat-BDOkdsCR.js → dateFormat-Cfb89ZjM.js} +1 -1
  51. package/dist-web/assets/{electron-CmhzSjaH.js → electron-Brd7jS6W.js} +1 -1
  52. package/dist-web/assets/{fetch-CNz28Lv5.js → fetch-BJ3lnhzK.js} +1 -1
  53. package/dist-web/assets/{fetch-DfTM4Dah.js → fetch-BoB63ns8.js} +1 -1
  54. package/dist-web/assets/fetch-BtK7YvLp.js +1 -0
  55. package/dist-web/assets/{fetch-D71bG6Fc.js → fetch-CeREJiFL.js} +1 -1
  56. package/dist-web/assets/{fetch-C1mlq5VY.js → fetch-D2hvh7lO.js} +1 -1
  57. package/dist-web/assets/{fetch-DtcNaN3d.js → fetch-DVGCzZ0E.js} +1 -1
  58. package/dist-web/assets/{fetch-BddgpyKJ.js → fetch-DWoMmOlr.js} +1 -1
  59. package/dist-web/assets/{fetch-dI5w8lYN.js → fetch-DkfUUq-R.js} +1 -1
  60. package/dist-web/assets/{fetch-D8xv4lgE.js → fetch-Dr_Fjtvp.js} +1 -1
  61. package/dist-web/assets/{fetch-TATpgXht.js → fetch-u7ivV7Uy.js} +1 -1
  62. package/dist-web/assets/{index-CY5yJhCJ.js → index-BHnQaeQY.js} +1 -1
  63. package/dist-web/assets/{index-qZ7jnIna.js → index-BXaKyn8J.js} +2 -2
  64. package/dist-web/assets/{index-Dtbu8m1o.js → index-BzH9cnfy.js} +1 -1
  65. package/dist-web/assets/{index-Bs4ZX2-v.js → index-CuPE4SSh.js} +1 -1
  66. package/dist-web/assets/index-D-qNxFxp.js +173 -0
  67. package/dist-web/assets/index-D494nYee.js +64 -0
  68. package/dist-web/assets/index-D8Uq3_Dc.css +1 -0
  69. package/dist-web/assets/index-DBb03wVF.css +1 -0
  70. package/dist-web/assets/{index-DClxj4T2.js → index-DJ8kB4US.js} +2 -2
  71. package/dist-web/assets/{index-De3ImZb9.js → index-DNMWR2Vj.js} +1 -1
  72. package/dist-web/assets/{index-DphjBwbA.js → index-DSPls1YV.js} +1 -1
  73. package/dist-web/assets/{index-soX5gDgh.js → index-DcAqhCpS.js} +1 -1
  74. package/dist-web/assets/{index-a1ZrlsKo.js → index-DnkaYOFI.js} +1 -1
  75. package/dist-web/assets/index-_UKteDZB.js +25 -0
  76. package/dist-web/assets/index-gi0wgh0M.css +1 -0
  77. package/dist-web/assets/{index-Dp3gCHpK.js → index-w_1EjXiF.js} +1 -1
  78. package/dist-web/assets/{people-page-header-D93GTPBO.js → people-page-header-YGQM9G53.js} +1 -1
  79. package/dist-web/assets/{vendor-nuxt-ui-DUpPmItD.js → vendor-nuxt-ui-DmkGVKod.js} +2 -2
  80. package/dist-web/assets/{vendor-reka-ui-BLnO2MqY.js → vendor-reka-ui-BkhadcDj.js} +1 -1
  81. package/dist-web/assets/{web-H9T1dZys.js → web-zXxtk2KZ.js} +1 -1
  82. package/dist-web/assets/{webworkerAll-D1Kui8G8.js → webworkerAll-BzRoT-6m.js} +1 -1
  83. package/dist-web/index.html +4 -4
  84. package/package.json +1 -1
  85. package/dist/chat-command-QPL4GNHP.mjs.map +0 -1
  86. package/dist/chunk-3SZWD7UM.mjs.map +0 -1
  87. package/dist/chunk-BSSR4ZYW.mjs.map +0 -1
  88. package/dist/chunk-GYPBWKAU.mjs.map +0 -1
  89. package/dist/chunk-IK7GJTGY.mjs.map +0 -1
  90. package/dist/chunk-S5PQM5J4.mjs.map +0 -1
  91. package/dist-web/assets/ActionToolsPanel-CbWhu_Uv.css +0 -1
  92. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-CvvNqXuh.js +0 -110
  93. package/dist-web/assets/fetch-BJka-sCN.js +0 -1
  94. package/dist-web/assets/index-CAjUCtGD.css +0 -1
  95. package/dist-web/assets/index-CF59LLOG.js +0 -25
  96. package/dist-web/assets/index-CJ3WtSLo.js +0 -173
  97. package/dist-web/assets/index-CJS6FVuj.js +0 -64
  98. package/dist-web/assets/index-CsqMIyA9.css +0 -1
  99. package/dist-web/assets/index-CtmXho1w.css +0 -1
  100. /package/dist/{chunk-OAXVKNPN.mjs.map → chunk-23AIEWCD.mjs.map} +0 -0
  101. /package/dist/{chunk-F2NZ7HAY.mjs.map → chunk-3J7WTUEE.mjs.map} +0 -0
  102. /package/dist/{chunk-OQ6N4PDD.mjs.map → chunk-BLOBEOCG.mjs.map} +0 -0
  103. /package/dist/{chunk-6JKKHPXY.mjs.map → chunk-DV4U34MR.mjs.map} +0 -0
  104. /package/dist/{chunk-ZCXCHKQV.mjs.map → chunk-EINCXXWY.mjs.map} +0 -0
  105. /package/dist/{chunk-64FKPYPJ.mjs.map → chunk-UIUEG7JB.mjs.map} +0 -0
  106. /package/dist/{http-NOEWVWCP.mjs.map → http-WDG2OHOV.mjs.map} +0 -0
  107. /package/dist/{import-RS3HW7ZM.mjs.map → import-4BDC37F7.mjs.map} +0 -0
  108. /package/dist/{mcp-7F3G47Z4.mjs.map → mcp-4KUVRGFF.mjs.map} +0 -0
  109. /package/dist/{src-MNH5S423.mjs.map → src-ZOCLFBCJ.mjs.map} +0 -0
  110. /package/dist/{stream-import-BPCHGRAN.mjs.map → stream-import-ERTT7U6V.mjs.map} +0 -0
  111. /package/dist/{worker-runtime-TTAXGQ5R.mjs.map → worker-runtime-2TUZHV7W.mjs.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  createEmptyContactsDiagnostics,
10
10
  normalizeContactsTimeRangePreset,
11
11
  resolveContactsTimeRange
12
- } from "./chunk-F2NZ7HAY.mjs";
12
+ } from "./chunk-3J7WTUEE.mjs";
13
13
  import {
14
14
  PEOPLE_RELATIONSHIPS_ALGORITHM_VERSION,
15
15
  buildPeopleRelationshipsNeighborhoodGraph,
@@ -18,18 +18,21 @@ import {
18
18
  computePeopleRelationshipsSnapshot,
19
19
  normalizePeopleRelationshipsTimeRangePreset,
20
20
  resolvePeopleRelationshipsTimeRange
21
- } from "./chunk-OAXVKNPN.mjs";
21
+ } from "./chunk-23AIEWCD.mjs";
22
22
  import {
23
23
  ANNUAL_SUMMARY_ALGORITHM_VERSION
24
24
  } from "./chunk-YAQLYL52.mjs";
25
25
  import {
26
26
  BUILTIN_MODELS,
27
27
  BUILTIN_PROVIDERS,
28
+ BUILTIN_TOOL_CATALOG,
28
29
  CHART_CAPABILITY_SKILL_ID,
29
30
  CHAT_DB_INDEXES,
30
31
  CHAT_DB_SCHEMA,
32
+ DEFAULT_GENERAL_ASSISTANT_ID,
31
33
  DataDirCompatibilityError,
32
34
  FTS_TABLE_SCHEMA,
35
+ GENERAL_ASSISTANT_IDS,
33
36
  KNOWN_PLATFORMS,
34
37
  StreamingThinkTagParser,
35
38
  appLogger,
@@ -42,7 +45,9 @@ import {
42
45
  clearSessionIndex,
43
46
  collectPosTagStats,
44
47
  deleteAnnualSummarySnapshots,
48
+ deleteAuthProfile,
45
49
  deleteMember,
50
+ deleteMembers,
46
51
  generateIncrementalSessionIndex,
47
52
  generateMessageKey,
48
53
  generateSessionIndex,
@@ -93,7 +98,7 @@ import {
93
98
  updateSessionOwnerId,
94
99
  writeAnnualSummarySnapshot,
95
100
  writeAuthProfile
96
- } from "./chunk-IK7GJTGY.mjs";
101
+ } from "./chunk-YVNZ73O5.mjs";
97
102
  import {
98
103
  __commonJS,
99
104
  __export,
@@ -709,8 +714,8 @@ var require_FilterBase = __commonJS({
709
714
  var FilterBase = class _FilterBase extends Transform {
710
715
  static stringFilter(string, separator) {
711
716
  return (stack) => {
712
- const path31 = stack.join(separator);
713
- return path31.length === string.length && path31 === string || path31.length > string.length && path31.substr(0, string.length) === string && path31.substr(string.length, separator.length) === separator;
717
+ const path33 = stack.join(separator);
718
+ return path33.length === string.length && path33 === string || path33.length > string.length && path33.substr(0, string.length) === string && path33.substr(string.length, separator.length) === separator;
714
719
  };
715
720
  }
716
721
  static regExpFilter(regExp, separator) {
@@ -1164,12 +1169,12 @@ var require_Assembler = __commonJS({
1164
1169
  return (this.stack.length >> 1) + (this.done ? 0 : 1);
1165
1170
  }
1166
1171
  get path() {
1167
- const path31 = [];
1172
+ const path33 = [];
1168
1173
  for (let i = 0; i < this.stack.length; i += 2) {
1169
1174
  const key = this.stack[i + 1];
1170
- path31.push(key === null ? this.stack[i].length : key);
1175
+ path33.push(key === null ? this.stack[i].length : key);
1171
1176
  }
1172
- return path31;
1177
+ return path33;
1173
1178
  }
1174
1179
  dropToLevel(level) {
1175
1180
  if (level < this.depth) {
@@ -1451,7 +1456,7 @@ var require_pend = __commonJS({
1451
1456
  var require_fd_slicer = __commonJS({
1452
1457
  "../../packages/node-runtime/node_modules/yauzl/fd-slicer.js"(exports) {
1453
1458
  "use strict";
1454
- var fs35 = __require("fs");
1459
+ var fs37 = __require("fs");
1455
1460
  var util = __require("util");
1456
1461
  var stream = __require("stream");
1457
1462
  var Readable = stream.Readable;
@@ -1471,7 +1476,7 @@ var require_fd_slicer = __commonJS({
1471
1476
  FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
1472
1477
  var self = this;
1473
1478
  self.pend.go(function(cb) {
1474
- fs35.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) {
1479
+ fs37.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) {
1475
1480
  cb();
1476
1481
  callback(err, bytesRead, buffer2);
1477
1482
  });
@@ -1488,7 +1493,7 @@ var require_fd_slicer = __commonJS({
1488
1493
  self.refCount -= 1;
1489
1494
  if (self.refCount < 0) throw new Error("invalid unref");
1490
1495
  if (self.refCount > 0) return;
1491
- fs35.close(self.fd, onCloseDone);
1496
+ fs37.close(self.fd, onCloseDone);
1492
1497
  function onCloseDone(err) {
1493
1498
  if (err) {
1494
1499
  self.emit("error", err);
@@ -1520,7 +1525,7 @@ var require_fd_slicer = __commonJS({
1520
1525
  }
1521
1526
  self.context.pend.go(function(cb) {
1522
1527
  var buffer = Buffer.allocUnsafe(toRead);
1523
- fs35.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
1528
+ fs37.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
1524
1529
  if (err) {
1525
1530
  self.destroy(err);
1526
1531
  } else if (bytesRead === 0) {
@@ -1882,7 +1887,7 @@ var require_crc32 = __commonJS({
1882
1887
  var require_yauzl = __commonJS({
1883
1888
  "../../packages/node-runtime/node_modules/yauzl/index.js"(exports) {
1884
1889
  "use strict";
1885
- var fs35 = __require("fs");
1890
+ var fs37 = __require("fs");
1886
1891
  var zlib = __require("zlib");
1887
1892
  var fd_slicer = require_fd_slicer();
1888
1893
  var util = __require("util");
@@ -1907,39 +1912,39 @@ var require_yauzl = __commonJS({
1907
1912
  exports.Entry = Entry;
1908
1913
  exports.LocalFileHeader = LocalFileHeader;
1909
1914
  exports.RandomAccessReader = RandomAccessReader;
1910
- function openPromise2(path31, options2) {
1911
- return new Promise((resolve2, reject) => {
1912
- open(path31, { ...options2, lazyEntries: true }, function(err, zipfile) {
1915
+ function openPromise2(path33, options2) {
1916
+ return new Promise((resolve4, reject) => {
1917
+ open(path33, { ...options2, lazyEntries: true }, function(err, zipfile) {
1913
1918
  if (err) return reject(err);
1914
- resolve2(zipfile);
1919
+ resolve4(zipfile);
1915
1920
  });
1916
1921
  });
1917
1922
  }
1918
1923
  function fromFdPromise(fd, options2) {
1919
- return new Promise((resolve2, reject) => {
1924
+ return new Promise((resolve4, reject) => {
1920
1925
  fromFd(fd, { ...options2, lazyEntries: true }, function(err, zipfile) {
1921
1926
  if (err) return reject(err);
1922
- resolve2(zipfile);
1927
+ resolve4(zipfile);
1923
1928
  });
1924
1929
  });
1925
1930
  }
1926
1931
  function fromBufferPromise(buffer, options2) {
1927
- return new Promise((resolve2, reject) => {
1932
+ return new Promise((resolve4, reject) => {
1928
1933
  fromBuffer(buffer, { ...options2, lazyEntries: true }, function(err, zipfile) {
1929
1934
  if (err) return reject(err);
1930
- resolve2(zipfile);
1935
+ resolve4(zipfile);
1931
1936
  });
1932
1937
  });
1933
1938
  }
1934
1939
  function fromRandomAccessReaderPromise(reader, totalSize, options2) {
1935
- return new Promise((resolve2, reject) => {
1940
+ return new Promise((resolve4, reject) => {
1936
1941
  fromRandomAccessReader(reader, totalSize, { ...options2, lazyEntries: true }, function(err, zipfile) {
1937
1942
  if (err) return reject(err);
1938
- resolve2(zipfile);
1943
+ resolve4(zipfile);
1939
1944
  });
1940
1945
  });
1941
1946
  }
1942
- function open(path31, options2, callback) {
1947
+ function open(path33, options2, callback) {
1943
1948
  if (typeof options2 === "function") {
1944
1949
  callback = options2;
1945
1950
  options2 = null;
@@ -1951,10 +1956,10 @@ var require_yauzl = __commonJS({
1951
1956
  if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
1952
1957
  if (options2.strictFileNames == null) options2.strictFileNames = false;
1953
1958
  if (callback == null) callback = defaultCallback;
1954
- fs35.open(path31, "r", function(err, fd) {
1959
+ fs37.open(path33, "r", function(err, fd) {
1955
1960
  if (err) return callback(err);
1956
1961
  fromFd(fd, options2, function(err2, zipfile) {
1957
- if (err2) fs35.close(fd, defaultCallback);
1962
+ if (err2) fs37.close(fd, defaultCallback);
1958
1963
  callback(err2, zipfile);
1959
1964
  });
1960
1965
  });
@@ -1971,7 +1976,7 @@ var require_yauzl = __commonJS({
1971
1976
  if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
1972
1977
  if (options2.strictFileNames == null) options2.strictFileNames = false;
1973
1978
  if (callback == null) callback = defaultCallback;
1974
- fs35.fstat(fd, function(err, stats) {
1979
+ fs37.fstat(fd, function(err, stats) {
1975
1980
  if (err) return callback(err);
1976
1981
  var reader = new fd_slicer.FdSlicer(fd);
1977
1982
  fromRandomAccessReader(reader, stats.size, options2, callback);
@@ -2219,15 +2224,15 @@ var require_yauzl = __commonJS({
2219
2224
  if (self.autoClose) self.close();
2220
2225
  }
2221
2226
  function onEntry(entry) {
2222
- let { resolve: resolve2 } = pendingResolveReject;
2227
+ let { resolve: resolve4 } = pendingResolveReject;
2223
2228
  pendingResolveReject = null;
2224
- resolve2({ value: entry });
2229
+ resolve4({ value: entry });
2225
2230
  }
2226
2231
  function onEnd() {
2227
- let { resolve: resolve2 } = pendingResolveReject;
2232
+ let { resolve: resolve4 } = pendingResolveReject;
2228
2233
  pendingResolveReject = null;
2229
2234
  cleanup();
2230
- resolve2({ done: true });
2235
+ resolve4({ done: true });
2231
2236
  }
2232
2237
  function onError(err) {
2233
2238
  let { reject } = pendingResolveReject;
@@ -2240,9 +2245,9 @@ var require_yauzl = __commonJS({
2240
2245
  return this;
2241
2246
  },
2242
2247
  next() {
2243
- const promise = new Promise((resolve2, reject) => {
2248
+ const promise = new Promise((resolve4, reject) => {
2244
2249
  if (pendingResolveReject != null) throw new Error("next() called before previous Promise was resolved.");
2245
- pendingResolveReject = { resolve: resolve2, reject };
2250
+ pendingResolveReject = { resolve: resolve4, reject };
2246
2251
  });
2247
2252
  self.readEntry();
2248
2253
  return promise;
@@ -2431,26 +2436,26 @@ var require_yauzl = __commonJS({
2431
2436
  });
2432
2437
  };
2433
2438
  ZipFile.prototype.openReadStreamPromise = function(entry, options2) {
2434
- return new Promise((resolve2, reject) => {
2439
+ return new Promise((resolve4, reject) => {
2435
2440
  this.openReadStream(entry, options2, function(err, readStream) {
2436
2441
  if (err) return reject(err);
2437
- resolve2(readStream);
2442
+ resolve4(readStream);
2438
2443
  });
2439
2444
  });
2440
2445
  };
2441
2446
  ZipFile.prototype.openReadStreamLowLevelPromise = function(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize) {
2442
- return new Promise((resolve2, reject) => {
2447
+ return new Promise((resolve4, reject) => {
2443
2448
  this.openReadStream(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize, function(err, readStream) {
2444
2449
  if (err) return reject(err);
2445
- resolve2(readStream);
2450
+ resolve4(readStream);
2446
2451
  });
2447
2452
  });
2448
2453
  };
2449
2454
  ZipFile.prototype.readLocalFileHeaderPromise = function(entry, options2) {
2450
- return new Promise((resolve2, reject) => {
2455
+ return new Promise((resolve4, reject) => {
2451
2456
  this.readLocalFileHeader(entry, options2, function(err, localFileHeader) {
2452
2457
  if (err) return reject(err);
2453
- resolve2(localFileHeader);
2458
+ resolve4(localFileHeader);
2454
2459
  });
2455
2460
  });
2456
2461
  };
@@ -2738,6 +2743,73 @@ var require_yauzl = __commonJS({
2738
2743
  }
2739
2744
  });
2740
2745
 
2746
+ // ../../packages/node-runtime/src/temp-workspace.ts
2747
+ import * as fs from "fs";
2748
+ import * as os from "os";
2749
+ import * as path from "path";
2750
+ var CHATLAB_TEMP_ROOT_ENV = "CHATLAB_TEMP_ROOT";
2751
+ var CHATLAB_TEMP_SCOPES = /* @__PURE__ */ new Set(["tests", "runtime", "imports", "merge", "sync", "parser", "build", "bench"]);
2752
+ function optionsEnv(options2) {
2753
+ return options2.env ?? process.env;
2754
+ }
2755
+ function resolveChatLabTempRoot(options2 = {}) {
2756
+ const envRoot = optionsEnv(options2)[CHATLAB_TEMP_ROOT_ENV]?.trim();
2757
+ if (envRoot) return path.resolve(envRoot);
2758
+ const platform2 = options2.platform ?? process.platform;
2759
+ const systemTempDir = options2.systemTempDir ?? os.tmpdir();
2760
+ return path.resolve(platform2 === "darwin" ? "/private/tmp/chatlab" : path.join(systemTempDir, "chatlab"));
2761
+ }
2762
+ function ensurePrivateOwnedDirectory(dirPath, label) {
2763
+ fs.mkdirSync(dirPath, { recursive: true, mode: 448 });
2764
+ const stats = fs.lstatSync(dirPath);
2765
+ if (stats.isSymbolicLink()) {
2766
+ throw new Error(`${label} must not be a symbolic link: ${dirPath}`);
2767
+ }
2768
+ if (!stats.isDirectory()) {
2769
+ throw new Error(`${label} must be a directory: ${dirPath}`);
2770
+ }
2771
+ if (typeof process.getuid === "function" && stats.uid !== process.getuid()) {
2772
+ throw new Error(`${label} is owned by another user: ${dirPath}`);
2773
+ }
2774
+ if (process.platform !== "win32") {
2775
+ fs.chmodSync(dirPath, 448);
2776
+ }
2777
+ }
2778
+ function ensureChatLabTempRoot(options2 = {}) {
2779
+ const root = resolveChatLabTempRoot(options2);
2780
+ ensurePrivateOwnedDirectory(root, "ChatLab temp root");
2781
+ optionsEnv(options2)[CHATLAB_TEMP_ROOT_ENV] = root;
2782
+ return root;
2783
+ }
2784
+ function assertValidScope(scope) {
2785
+ if (!CHATLAB_TEMP_SCOPES.has(scope)) {
2786
+ throw new Error(`Invalid ChatLab temp scope: ${scope}`);
2787
+ }
2788
+ }
2789
+ function assertValidPrefix(prefix) {
2790
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(prefix)) {
2791
+ throw new Error(`Invalid ChatLab temp prefix: ${prefix}`);
2792
+ }
2793
+ }
2794
+ function getChatLabTempScopeDir(scope, options2 = {}) {
2795
+ assertValidScope(scope);
2796
+ const scopeDir = path.join(ensureChatLabTempRoot(options2), scope);
2797
+ ensurePrivateOwnedDirectory(scopeDir, "ChatLab temp scope");
2798
+ return scopeDir;
2799
+ }
2800
+ function createChatLabTempDir(scope, prefix, options2 = {}) {
2801
+ assertValidPrefix(prefix);
2802
+ return fs.mkdtempSync(path.join(getChatLabTempScopeDir(scope, options2), prefix));
2803
+ }
2804
+ function removeChatLabTempDir(dirPath, scope, options2 = {}) {
2805
+ const scopeDir = path.resolve(getChatLabTempScopeDir(scope, options2));
2806
+ const resolvedDir = path.resolve(dirPath);
2807
+ if (path.dirname(resolvedDir) !== scopeDir) {
2808
+ throw new Error(`Refusing to remove non-owned ChatLab temp directory: ${resolvedDir}`);
2809
+ }
2810
+ fs.rmSync(resolvedDir, { recursive: true, force: true });
2811
+ }
2812
+
2741
2813
  // ../../packages/node-runtime/src/import/write-parse-result.ts
2742
2814
  function writeParseResultToDb(db, meta, members, messages) {
2743
2815
  let messageCount = 0;
@@ -2852,28 +2924,28 @@ function writeParseResultToDb(db, meta, members, messages) {
2852
2924
  }
2853
2925
 
2854
2926
  // ../../packages/parser/src/index.ts
2855
- import * as fs17 from "fs";
2856
- import * as path13 from "path";
2927
+ import * as fs18 from "fs";
2928
+ import * as path14 from "path";
2857
2929
 
2858
2930
  // ../../packages/parser/src/sniffer.ts
2859
- import * as fs from "fs";
2860
- import * as path from "path";
2931
+ import * as fs2 from "fs";
2932
+ import * as path2 from "path";
2861
2933
  var HEAD_SIZE = 64 * 1024;
2862
2934
  function readFileHead(filePath, size = HEAD_SIZE) {
2863
- const fd = fs.openSync(filePath, "r");
2935
+ const fd = fs2.openSync(filePath, "r");
2864
2936
  const buffer = Buffer.alloc(size);
2865
- const bytesRead = fs.readSync(fd, buffer, 0, size, 0);
2866
- fs.closeSync(fd);
2937
+ const bytesRead = fs2.readSync(fd, buffer, 0, size, 0);
2938
+ fs2.closeSync(fd);
2867
2939
  return buffer.slice(0, bytesRead).toString("utf-8");
2868
2940
  }
2869
2941
  function getExtension(filePath) {
2870
- return path.extname(filePath).toLowerCase();
2942
+ return path2.extname(filePath).toLowerCase();
2871
2943
  }
2872
2944
  function matchHeadSignatures(headContent, patterns) {
2873
2945
  return patterns.some((pattern) => pattern.test(headContent));
2874
2946
  }
2875
2947
  function matchFilenameSignatures(filePath, patterns) {
2876
- const filename = path.basename(filePath);
2948
+ const filename = path2.basename(filePath);
2877
2949
  return patterns.some((pattern) => pattern.test(filename));
2878
2950
  }
2879
2951
  function matchRequiredFields(headContent, fields) {
@@ -3021,18 +3093,18 @@ var import_stream_json = __toESM(require_stream_json(), 1);
3021
3093
  var import_Pick = __toESM(require_Pick(), 1);
3022
3094
  var import_StreamValues = __toESM(require_StreamValues(), 1);
3023
3095
  var import_stream_chain = __toESM(require_stream_chain(), 1);
3024
- import * as fs3 from "fs";
3096
+ import * as fs4 from "fs";
3025
3097
 
3026
3098
  // ../../packages/parser/src/utils.ts
3027
- import * as fs2 from "fs";
3099
+ import * as fs3 from "fs";
3028
3100
  function getFileSize(filePath) {
3029
- return fs2.statSync(filePath).size;
3101
+ return fs3.statSync(filePath).size;
3030
3102
  }
3031
3103
  function readFileHeadBytes(filePath, size) {
3032
- const fd = fs2.openSync(filePath, "r");
3104
+ const fd = fs3.openSync(filePath, "r");
3033
3105
  const buffer = Buffer.alloc(size);
3034
- const bytesRead = fs2.readSync(fd, buffer, 0, size, 0);
3035
- fs2.closeSync(fd);
3106
+ const bytesRead = fs3.readSync(fd, buffer, 0, size, 0);
3107
+ fs3.closeSync(fd);
3036
3108
  return buffer.slice(0, bytesRead).toString("utf-8");
3037
3109
  }
3038
3110
  var createProgress = (stage, bytesRead, totalBytes, messagesProcessed, message) => {
@@ -3062,7 +3134,7 @@ function isValidYear(timestampSeconds) {
3062
3134
  }
3063
3135
 
3064
3136
  // ../../packages/parser/src/formats/chatlab.ts
3065
- import * as path2 from "path";
3137
+ import * as path3 from "path";
3066
3138
 
3067
3139
  // ../../packages/parser/src/native/loader.ts
3068
3140
  import { createRequire } from "module";
@@ -3145,7 +3217,7 @@ async function* pumpNativeParser(adapter, options2, parser11, fallback) {
3145
3217
  if (!batch) break;
3146
3218
  messagesProcessed += batch.length;
3147
3219
  yield { type: "messages", data: batch.map((message) => adapter.mapMessage(message, metaJson)) };
3148
- await new Promise((resolve2) => setImmediate(resolve2));
3220
+ await new Promise((resolve4) => setImmediate(resolve4));
3149
3221
  }
3150
3222
  const doneProgress = createProgress("done", totalBytes, totalBytes, messagesProcessed, "");
3151
3223
  yield { type: "progress", data: doneProgress };
@@ -3243,7 +3315,7 @@ var { pick } = import_Pick.default;
3243
3315
  var { streamValues } = import_StreamValues.default;
3244
3316
  var { chain } = import_stream_chain.default;
3245
3317
  function extractNameFromFilePath(filePath) {
3246
- const basename13 = path2.basename(filePath);
3318
+ const basename13 = path3.basename(filePath);
3247
3319
  const name = basename13.replace(/\.json$/i, "");
3248
3320
  return name || "\u672A\u77E5\u7FA4\u804A";
3249
3321
  }
@@ -3317,8 +3389,8 @@ async function* parseChatLab(options2) {
3317
3389
  const members = [];
3318
3390
  const memberMapFromMessages = /* @__PURE__ */ new Map();
3319
3391
  const messageBatch = [];
3320
- await new Promise((resolve2, reject) => {
3321
- const readStream = fs3.createReadStream(filePath, { encoding: "utf-8" });
3392
+ await new Promise((resolve4, reject) => {
3393
+ const readStream = fs4.createReadStream(filePath, { encoding: "utf-8" });
3322
3394
  readStream.on("data", (chunk) => {
3323
3395
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
3324
3396
  });
@@ -3372,7 +3444,7 @@ async function* parseChatLab(options2) {
3372
3444
  if (batchCollector.length > 0) {
3373
3445
  messageBatch.push(...batchCollector);
3374
3446
  }
3375
- resolve2();
3447
+ resolve4();
3376
3448
  });
3377
3449
  pipeline2.on("error", reject);
3378
3450
  });
@@ -3410,11 +3482,11 @@ var module_ = {
3410
3482
  var chatlab_default = module_;
3411
3483
 
3412
3484
  // ../../packages/parser/src/formats/chatlab-jsonl.ts
3413
- import * as fs4 from "fs";
3485
+ import * as fs5 from "fs";
3414
3486
  import * as readline from "readline";
3415
- import * as path3 from "path";
3487
+ import * as path4 from "path";
3416
3488
  function extractNameFromFilePath2(filePath) {
3417
- const basename13 = path3.basename(filePath);
3489
+ const basename13 = path4.basename(filePath);
3418
3490
  const name = basename13.replace(/\.jsonl$/i, "");
3419
3491
  return name || "\u672A\u77E5\u7FA4\u804A";
3420
3492
  }
@@ -3455,7 +3527,7 @@ async function* parseChatLabJsonl(options2) {
3455
3527
  const messageBatch = [];
3456
3528
  let meta = null;
3457
3529
  let headerParsed = false;
3458
- const fileStream = fs4.createReadStream(filePath, { encoding: "utf-8" });
3530
+ const fileStream = fs5.createReadStream(filePath, { encoding: "utf-8" });
3459
3531
  const rl = readline.createInterface({
3460
3532
  input: fileStream,
3461
3533
  crlfDelay: Infinity
@@ -3580,28 +3652,30 @@ var import_stream_json3 = __toESM(require_stream_json(), 1);
3580
3652
  var import_Pick3 = __toESM(require_Pick(), 1);
3581
3653
  var import_StreamValues3 = __toESM(require_StreamValues(), 1);
3582
3654
  var import_stream_chain3 = __toESM(require_stream_chain(), 1);
3583
- import * as fs6 from "fs";
3584
- import * as path5 from "path";
3655
+ import * as fs7 from "fs";
3656
+ import * as path6 from "path";
3585
3657
 
3586
3658
  // ../../packages/parser/src/formats/shuakami-qq-preprocessor.ts
3587
3659
  var import_stream_json2 = __toESM(require_stream_json(), 1);
3588
3660
  var import_Pick2 = __toESM(require_Pick(), 1);
3589
3661
  var import_StreamValues2 = __toESM(require_StreamValues(), 1);
3590
3662
  var import_stream_chain2 = __toESM(require_stream_chain(), 1);
3591
- import * as fs5 from "fs";
3592
- import * as path4 from "path";
3593
- import * as os from "os";
3663
+ import * as fs6 from "fs";
3664
+ import * as path5 from "path";
3665
+ import * as os2 from "os";
3594
3666
  var { parser: parser3 } = import_stream_json2.default;
3595
3667
  var { pick: pick2 } = import_Pick2.default;
3596
3668
  var { streamValues: streamValues2 } = import_StreamValues2.default;
3597
3669
  var { chain: chain2 } = import_stream_chain2.default;
3598
3670
  var PREPROCESS_THRESHOLD = 50 * 1024 * 1024;
3599
3671
  function getTempDir() {
3600
- return path4.join(os.tmpdir(), "chatlab");
3672
+ const configuredRoot = process.env.CHATLAB_TEMP_ROOT?.trim();
3673
+ const root = configuredRoot ? path5.resolve(configuredRoot) : path5.resolve(process.platform === "darwin" ? "/private/tmp/chatlab" : path5.join(os2.tmpdir(), "chatlab"));
3674
+ return path5.join(root, "parser");
3601
3675
  }
3602
3676
  function ensureDir(dir) {
3603
- if (!fs5.existsSync(dir)) {
3604
- fs5.mkdirSync(dir, { recursive: true });
3677
+ if (!fs6.existsSync(dir)) {
3678
+ fs6.mkdirSync(dir, { recursive: true, mode: 448 });
3605
3679
  }
3606
3680
  }
3607
3681
  function extractJsonObject(content, key) {
@@ -3643,12 +3717,12 @@ function extractJsonObject(content, key) {
3643
3717
  }
3644
3718
  function readAvatarsFromFile(filePath) {
3645
3719
  try {
3646
- const stats = fs5.statSync(filePath);
3720
+ const stats = fs6.statSync(filePath);
3647
3721
  const tailSize = Math.min(stats.size, 5e6);
3648
- const fd = fs5.openSync(filePath, "r");
3722
+ const fd = fs6.openSync(filePath, "r");
3649
3723
  const buffer = Buffer.alloc(tailSize);
3650
- fs5.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
3651
- fs5.closeSync(fd);
3724
+ fs6.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
3725
+ fs6.closeSync(fd);
3652
3726
  const tailContent = buffer.toString("utf-8");
3653
3727
  return extractJsonObject(tailContent, "avatars");
3654
3728
  } catch {
@@ -3707,15 +3781,15 @@ async function preprocessQQJson(inputPath, onProgress) {
3707
3781
  let messagesProcessed = 0;
3708
3782
  const tempDir = getTempDir();
3709
3783
  ensureDir(tempDir);
3710
- const outputFilename = `slim_${Date.now()}_${path4.basename(inputPath)}`;
3711
- const outputPath = path4.join(tempDir, outputFilename);
3784
+ const outputFilename = `slim_${Date.now()}_${path5.basename(inputPath)}`;
3785
+ const outputPath = path5.join(tempDir, outputFilename);
3712
3786
  onProgress?.(createProgress("parsing", 0, totalBytes, 0, ""));
3713
3787
  const avatarsStr = readAvatarsFromFile(inputPath);
3714
- return new Promise((resolve2, reject) => {
3788
+ return new Promise((resolve4, reject) => {
3715
3789
  const headChunks = [];
3716
3790
  let headSize = 0;
3717
3791
  const maxHeadSize = 1e5;
3718
- const headStream = fs5.createReadStream(inputPath, { encoding: "utf-8" });
3792
+ const headStream = fs6.createReadStream(inputPath, { encoding: "utf-8" });
3719
3793
  let chatInfo = { name: "\u672A\u77E5\u7FA4\u804A", type: "group" };
3720
3794
  let metadata;
3721
3795
  let statistics;
@@ -3752,8 +3826,8 @@ async function preprocessQQJson(inputPath, onProgress) {
3752
3826
  } catch {
3753
3827
  }
3754
3828
  onProgress?.(createProgress("parsing", 0, totalBytes, 0, ""));
3755
- const readStream = fs5.createReadStream(inputPath, { encoding: "utf-8" });
3756
- const writeStream = fs5.createWriteStream(outputPath, { encoding: "utf-8" });
3829
+ const readStream = fs6.createReadStream(inputPath, { encoding: "utf-8" });
3830
+ const writeStream = fs6.createWriteStream(outputPath, { encoding: "utf-8" });
3757
3831
  readStream.on("data", (chunk) => {
3758
3832
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
3759
3833
  });
@@ -3793,13 +3867,13 @@ async function preprocessQQJson(inputPath, onProgress) {
3793
3867
  writeStream.end();
3794
3868
  writeStream.on("finish", () => {
3795
3869
  onProgress?.(createProgress("done", totalBytes, totalBytes, messagesProcessed, ""));
3796
- resolve2(outputPath);
3870
+ resolve4(outputPath);
3797
3871
  });
3798
3872
  });
3799
3873
  pipeline2.on("error", (err) => {
3800
3874
  writeStream.destroy();
3801
- if (fs5.existsSync(outputPath)) {
3802
- fs5.unlinkSync(outputPath);
3875
+ if (fs6.existsSync(outputPath)) {
3876
+ fs6.unlinkSync(outputPath);
3803
3877
  }
3804
3878
  onProgress?.(createProgress("error", bytesRead, totalBytes, messagesProcessed, err.message));
3805
3879
  reject(err);
@@ -3810,8 +3884,8 @@ async function preprocessQQJson(inputPath, onProgress) {
3810
3884
  }
3811
3885
  function cleanupTempFile(filePath) {
3812
3886
  try {
3813
- if (fs5.existsSync(filePath) && filePath.includes(getTempDir())) {
3814
- fs5.unlinkSync(filePath);
3887
+ if (fs6.existsSync(filePath) && path5.dirname(path5.resolve(filePath)) === path5.resolve(getTempDir())) {
3888
+ fs6.unlinkSync(filePath);
3815
3889
  }
3816
3890
  } catch {
3817
3891
  }
@@ -3878,7 +3952,7 @@ function extractJsonObject2(content, key) {
3878
3952
  return null;
3879
3953
  }
3880
3954
  function extractNameFromFilePath3(filePath) {
3881
- const basename13 = path5.basename(filePath);
3955
+ const basename13 = path6.basename(filePath);
3882
3956
  return basename13.replace(/\.json$/i, "") || "\u672A\u77E5\u7FA4\u804A";
3883
3957
  }
3884
3958
  function isPlaceholderSenderId(id) {
@@ -3975,8 +4049,8 @@ async function* parseV4(options2) {
3975
4049
  yield { type: "meta", data: meta };
3976
4050
  const memberMap = /* @__PURE__ */ new Map();
3977
4051
  const messageBatch = [];
3978
- await new Promise((resolve2, reject) => {
3979
- const readStream = fs6.createReadStream(filePath, { encoding: "utf-8" });
4052
+ await new Promise((resolve4, reject) => {
4053
+ const readStream = fs7.createReadStream(filePath, { encoding: "utf-8" });
3980
4054
  readStream.on("data", (chunk) => {
3981
4055
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
3982
4056
  });
@@ -4031,17 +4105,17 @@ async function* parseV4(options2) {
4031
4105
  onProgress?.(progress);
4032
4106
  }
4033
4107
  });
4034
- pipeline2.on("end", resolve2);
4108
+ pipeline2.on("end", resolve4);
4035
4109
  pipeline2.on("error", reject);
4036
4110
  });
4037
4111
  const avatarsMap = /* @__PURE__ */ new Map();
4038
4112
  try {
4039
- const stats = fs6.statSync(filePath);
4113
+ const stats = fs7.statSync(filePath);
4040
4114
  const tailSize = Math.min(stats.size, 5e6);
4041
- const fd = fs6.openSync(filePath, "r");
4115
+ const fd = fs7.openSync(filePath, "r");
4042
4116
  const buffer = Buffer.alloc(tailSize);
4043
- fs6.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
4044
- fs6.closeSync(fd);
4117
+ fs7.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
4118
+ fs7.closeSync(fd);
4045
4119
  const tailContent = buffer.toString("utf-8");
4046
4120
  const avatarsStr = extractJsonObject2(tailContent, "avatars");
4047
4121
  if (avatarsStr) {
@@ -4093,8 +4167,8 @@ var module_3 = {
4093
4167
  var shuakami_qq_exporter_default = module_3;
4094
4168
 
4095
4169
  // ../../packages/parser/src/formats/shuakami-qq-exporter-chunked.ts
4096
- import * as fs7 from "fs";
4097
- import * as path6 from "path";
4170
+ import * as fs8 from "fs";
4171
+ import * as path7 from "path";
4098
4172
  import * as readline2 from "readline";
4099
4173
  var feature4 = {
4100
4174
  id: "shuakami-qq-exporter-chunked",
@@ -4143,7 +4217,7 @@ function convertMessageType2(msgType, content, isRecalled) {
4143
4217
  return 0 /* TEXT */;
4144
4218
  }
4145
4219
  function readManifest(manifestPath) {
4146
- const content = fs7.readFileSync(manifestPath, "utf-8");
4220
+ const content = fs8.readFileSync(manifestPath, "utf-8");
4147
4221
  return JSON.parse(content);
4148
4222
  }
4149
4223
  function getChunkRelativePath(chunk) {
@@ -4161,9 +4235,9 @@ function calculateTotalBytes(manifest, baseDir) {
4161
4235
  let total = 0;
4162
4236
  for (const chunk of manifest.chunked.chunks) {
4163
4237
  const relativePath = getChunkRelativePath(chunk);
4164
- const chunkPath = path6.join(baseDir, relativePath);
4165
- if (fs7.existsSync(chunkPath)) {
4166
- total += fs7.statSync(chunkPath).size;
4238
+ const chunkPath = path7.join(baseDir, relativePath);
4239
+ if (fs8.existsSync(chunkPath)) {
4240
+ total += fs8.statSync(chunkPath).size;
4167
4241
  }
4168
4242
  }
4169
4243
  return total;
@@ -4171,10 +4245,10 @@ function calculateTotalBytes(manifest, baseDir) {
4171
4245
  function readAvatars(baseDir, avatarsInfo) {
4172
4246
  const avatarsMap = /* @__PURE__ */ new Map();
4173
4247
  if (!avatarsInfo?.file) return avatarsMap;
4174
- const avatarsPath = path6.join(baseDir, avatarsInfo.file);
4175
- if (!fs7.existsSync(avatarsPath)) return avatarsMap;
4248
+ const avatarsPath = path7.join(baseDir, avatarsInfo.file);
4249
+ if (!fs8.existsSync(avatarsPath)) return avatarsMap;
4176
4250
  try {
4177
- const content = fs7.readFileSync(avatarsPath, "utf-8");
4251
+ const content = fs8.readFileSync(avatarsPath, "utf-8");
4178
4252
  const avatars = JSON.parse(content);
4179
4253
  for (const [uin, avatar] of Object.entries(avatars)) {
4180
4254
  if (avatar && typeof avatar === "string" && avatar.startsWith("data:image/")) {
@@ -4192,7 +4266,7 @@ async function* readJsonlFile(filePath, onParseError) {
4192
4266
  let parseErrorCount = 0;
4193
4267
  const MAX_PARSE_ERRORS_TO_LOG = 10;
4194
4268
  try {
4195
- fileStream = fs7.createReadStream(filePath, { encoding: "utf-8" });
4269
+ fileStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4196
4270
  rl = readline2.createInterface({
4197
4271
  input: fileStream,
4198
4272
  crlfDelay: Infinity
@@ -4223,7 +4297,7 @@ async function* readJsonlFile(filePath, onParseError) {
4223
4297
  async function* parseChunkedJsonl(options2) {
4224
4298
  const { filePath, batchSize = 5e3, onProgress, onLog } = options2;
4225
4299
  const manifestPath = filePath;
4226
- const baseDir = path6.dirname(manifestPath);
4300
+ const baseDir = path7.dirname(manifestPath);
4227
4301
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 manifest: ${manifestPath}`);
4228
4302
  onLog?.("info", `\u57FA\u7840\u76EE\u5F55: ${baseDir}`);
4229
4303
  let manifest;
@@ -4277,13 +4351,13 @@ async function* parseChunkedJsonl(options2) {
4277
4351
  for (let chunkIndex = 0; chunkIndex < manifest.chunked.chunks.length; chunkIndex++) {
4278
4352
  const chunkInfo = manifest.chunked.chunks[chunkIndex];
4279
4353
  const relativePath = getChunkRelativePath(chunkInfo);
4280
- const chunkPath = path6.join(baseDir, relativePath);
4354
+ const chunkPath = path7.join(baseDir, relativePath);
4281
4355
  const chunkMessageCount = getChunkMessageCount(chunkInfo);
4282
- if (!fs7.existsSync(chunkPath)) {
4356
+ if (!fs8.existsSync(chunkPath)) {
4283
4357
  onLog?.("error", `\u5206\u5757\u6587\u4EF6\u4E0D\u5B58\u5728: ${chunkPath}`);
4284
4358
  continue;
4285
4359
  }
4286
- const chunkSize = fs7.statSync(chunkPath).size;
4360
+ const chunkSize = fs8.statSync(chunkPath).size;
4287
4361
  let chunkMessagesRead = 0;
4288
4362
  let chunkParseErrors = 0;
4289
4363
  onLog?.(
@@ -4405,8 +4479,8 @@ var import_stream_json4 = __toESM(require_stream_json(), 1);
4405
4479
  var import_Pick4 = __toESM(require_Pick(), 1);
4406
4480
  var import_StreamValues4 = __toESM(require_StreamValues(), 1);
4407
4481
  var import_stream_chain4 = __toESM(require_stream_chain(), 1);
4408
- import * as fs8 from "fs";
4409
- import * as path7 from "path";
4482
+ import * as fs9 from "fs";
4483
+ import * as path8 from "path";
4410
4484
 
4411
4485
  // ../../packages/parser/src/native/weflow-native.ts
4412
4486
  var weflowAdapter = {
@@ -4479,7 +4553,7 @@ var { pick: pick4 } = import_Pick4.default;
4479
4553
  var { streamValues: streamValues4 } = import_StreamValues4.default;
4480
4554
  var { chain: chain4 } = import_stream_chain4.default;
4481
4555
  function extractNameFromFilePath4(filePath) {
4482
- const basename13 = path7.basename(filePath);
4556
+ const basename13 = path8.basename(filePath);
4483
4557
  const name = basename13.replace(/\.json$/i, "");
4484
4558
  return name || "\u672A\u77E5\u804A\u5929";
4485
4559
  }
@@ -4547,8 +4621,8 @@ async function* parseWeFlow(options2) {
4547
4621
  const headContent = readFileHeadBytes(filePath, 5e3);
4548
4622
  let session = null;
4549
4623
  try {
4550
- await new Promise((resolve2) => {
4551
- const sessionStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4624
+ await new Promise((resolve4) => {
4625
+ const sessionStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4552
4626
  let sessionContent = "";
4553
4627
  let inSession = false;
4554
4628
  let braceDepth = 0;
@@ -4599,9 +4673,9 @@ async function* parseWeFlow(options2) {
4599
4673
  } catch {
4600
4674
  }
4601
4675
  }
4602
- resolve2();
4676
+ resolve4();
4603
4677
  });
4604
- sessionStream.on("error", () => resolve2());
4678
+ sessionStream.on("error", () => resolve4());
4605
4679
  });
4606
4680
  } catch {
4607
4681
  }
@@ -4670,8 +4744,8 @@ async function* parseWeFlow(options2) {
4670
4744
  }
4671
4745
  if (avatarsMap.size === 0) {
4672
4746
  try {
4673
- await new Promise((resolve2) => {
4674
- const avatarStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4747
+ await new Promise((resolve4) => {
4748
+ const avatarStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4675
4749
  let avatarsContent = "";
4676
4750
  let inAvatars = false;
4677
4751
  let braceDepth = 0;
@@ -4727,9 +4801,9 @@ async function* parseWeFlow(options2) {
4727
4801
  } catch {
4728
4802
  }
4729
4803
  }
4730
- resolve2();
4804
+ resolve4();
4731
4805
  });
4732
- avatarStream.on("error", () => resolve2());
4806
+ avatarStream.on("error", () => resolve4());
4733
4807
  });
4734
4808
  } catch {
4735
4809
  }
@@ -4737,8 +4811,8 @@ async function* parseWeFlow(options2) {
4737
4811
  const groupAvatar = sessionData?.avatar || (groupId ? avatarsMap.get(groupId) : void 0);
4738
4812
  let ownerId;
4739
4813
  try {
4740
- await new Promise((resolve2) => {
4741
- const scanStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4814
+ await new Promise((resolve4) => {
4815
+ const scanStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4742
4816
  const scanPipeline = chain4([scanStream, parser5(), pick4({ filter: /^messages\.\d+$/ }), streamValues4()]);
4743
4817
  scanPipeline.on("data", ({ value }) => {
4744
4818
  if (value.isSend === 1 && value.senderUsername && !value.senderUsername.endsWith("@chatroom")) {
@@ -4746,9 +4820,9 @@ async function* parseWeFlow(options2) {
4746
4820
  scanStream.destroy();
4747
4821
  }
4748
4822
  });
4749
- scanStream.on("close", () => resolve2());
4750
- scanPipeline.on("end", () => resolve2());
4751
- scanPipeline.on("error", () => resolve2());
4823
+ scanStream.on("close", () => resolve4());
4824
+ scanPipeline.on("end", () => resolve4());
4825
+ scanPipeline.on("error", () => resolve4());
4752
4826
  });
4753
4827
  } catch {
4754
4828
  }
@@ -4763,8 +4837,8 @@ async function* parseWeFlow(options2) {
4763
4837
  yield { type: "meta", data: meta };
4764
4838
  const memberMap = /* @__PURE__ */ new Map();
4765
4839
  const messageBatch = [];
4766
- await new Promise((resolve2, reject) => {
4767
- const readStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4840
+ await new Promise((resolve4, reject) => {
4841
+ const readStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4768
4842
  readStream.on("data", (chunk) => {
4769
4843
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
4770
4844
  });
@@ -4836,7 +4910,7 @@ async function* parseWeFlow(options2) {
4836
4910
  if (batchCollector.length > 0) {
4837
4911
  messageBatch.push(...batchCollector);
4838
4912
  }
4839
- resolve2();
4913
+ resolve4();
4840
4914
  });
4841
4915
  pipeline2.on("error", reject);
4842
4916
  });
@@ -4901,7 +4975,7 @@ var import_stream_json5 = __toESM(require_stream_json(), 1);
4901
4975
  var import_Pick5 = __toESM(require_Pick(), 1);
4902
4976
  var import_StreamValues5 = __toESM(require_StreamValues(), 1);
4903
4977
  var import_stream_chain5 = __toESM(require_stream_chain(), 1);
4904
- import * as fs9 from "fs";
4978
+ import * as fs10 from "fs";
4905
4979
  var { parser: parser6 } = import_stream_json5.default;
4906
4980
  var { pick: pick5 } = import_Pick5.default;
4907
4981
  var { streamValues: streamValues5 } = import_StreamValues5.default;
@@ -5050,8 +5124,8 @@ async function* parseDiscordExporter(options2) {
5050
5124
  onLog?.("info", `\u7FA4\u804A\u540D\u79F0: ${chatName}`);
5051
5125
  const memberMap = /* @__PURE__ */ new Map();
5052
5126
  const messageBatch = [];
5053
- await new Promise((resolve2, reject) => {
5054
- const readStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
5127
+ await new Promise((resolve4, reject) => {
5128
+ const readStream = fs10.createReadStream(filePath, { encoding: "utf-8" });
5055
5129
  readStream.on("data", (chunk) => {
5056
5130
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
5057
5131
  });
@@ -5129,7 +5203,7 @@ ${stickerTexts.join("\n")}` : stickerTexts.join("\n");
5129
5203
  if (batchCollector.length > 0) {
5130
5204
  messageBatch.push(...batchCollector);
5131
5205
  }
5132
- resolve2();
5206
+ resolve4();
5133
5207
  });
5134
5208
  pipeline2.on("error", reject);
5135
5209
  });
@@ -5167,7 +5241,7 @@ var import_stream_chain6 = __toESM(require_stream_chain(), 1);
5167
5241
  var import_stream_json6 = __toESM(require_stream_json(), 1);
5168
5242
  var import_Pick6 = __toESM(require_Pick(), 1);
5169
5243
  var import_StreamValues6 = __toESM(require_StreamValues(), 1);
5170
- import * as fs10 from "fs";
5244
+ import * as fs11 from "fs";
5171
5245
 
5172
5246
  // ../../packages/parser/src/formats/utils/telegram-utils.ts
5173
5247
  function mapChatType(telegramType) {
@@ -5252,8 +5326,8 @@ var feature8 = {
5252
5326
  };
5253
5327
  async function scanChats(filePath) {
5254
5328
  const chats = [];
5255
- return new Promise((resolve2, reject) => {
5256
- const readStream = fs10.createReadStream(filePath, { encoding: "utf-8" });
5329
+ return new Promise((resolve4, reject) => {
5330
+ const readStream = fs11.createReadStream(filePath, { encoding: "utf-8" });
5257
5331
  const pipeline2 = chain6([readStream, parser7(), pick6({ filter: /^chats\.list\.\d+$/ }), streamValues6()]);
5258
5332
  pipeline2.on("data", ({ value }) => {
5259
5333
  const chat = value;
@@ -5266,7 +5340,7 @@ async function scanChats(filePath) {
5266
5340
  });
5267
5341
  });
5268
5342
  pipeline2.on("end", () => {
5269
- resolve2(chats);
5343
+ resolve4(chats);
5270
5344
  });
5271
5345
  pipeline2.on("error", (err) => {
5272
5346
  reject(new Error(`\u626B\u63CF Telegram \u6587\u4EF6\u5931\u8D25: ${err.message}`));
@@ -5285,8 +5359,8 @@ async function* parseTelegram(options2) {
5285
5359
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 Telegram JSON \u6587\u4EF6\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
5286
5360
  onLog?.("info", `\u76EE\u6807\u804A\u5929\u7D22\u5F15: ${chatIndex}`);
5287
5361
  const chatPathFilter = `chats.list.${chatIndex}`;
5288
- const chatData = await new Promise((resolve2, reject) => {
5289
- const readStream = fs10.createReadStream(filePath, { encoding: "utf-8" });
5362
+ const chatData = await new Promise((resolve4, reject) => {
5363
+ const readStream = fs11.createReadStream(filePath, { encoding: "utf-8" });
5290
5364
  readStream.on("data", (chunk) => {
5291
5365
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
5292
5366
  });
@@ -5299,10 +5373,10 @@ async function* parseTelegram(options2) {
5299
5373
  let found = false;
5300
5374
  pipeline2.on("data", ({ value }) => {
5301
5375
  found = true;
5302
- resolve2(value);
5376
+ resolve4(value);
5303
5377
  });
5304
5378
  pipeline2.on("end", () => {
5305
- if (!found) resolve2(null);
5379
+ if (!found) resolve4(null);
5306
5380
  });
5307
5381
  pipeline2.on("error", reject);
5308
5382
  });
@@ -5394,7 +5468,7 @@ var telegram_native_default = module_8;
5394
5468
  var import_stream_chain7 = __toESM(require_stream_chain(), 1);
5395
5469
  var import_stream_json7 = __toESM(require_stream_json(), 1);
5396
5470
  var import_StreamValues7 = __toESM(require_StreamValues(), 1);
5397
- import * as fs11 from "fs";
5471
+ import * as fs12 from "fs";
5398
5472
  var { chain: chain7 } = import_stream_chain7.default;
5399
5473
  var { parser: parser8 } = import_stream_json7.default;
5400
5474
  var { streamValues: streamValues7 } = import_StreamValues7.default;
@@ -5423,18 +5497,18 @@ async function* parseTelegramSingle(options2) {
5423
5497
  yield { type: "progress", data: initialProgress };
5424
5498
  onProgress?.(initialProgress);
5425
5499
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 Telegram \u5355\u804A\u5929 JSON \u6587\u4EF6\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
5426
- const chatData = await new Promise((resolve2, reject) => {
5427
- const readStream = fs11.createReadStream(filePath, { encoding: "utf-8" });
5500
+ const chatData = await new Promise((resolve4, reject) => {
5501
+ const readStream = fs12.createReadStream(filePath, { encoding: "utf-8" });
5428
5502
  const pipeline2 = chain7([readStream, parser8(), streamValues7()]);
5429
5503
  let found = false;
5430
5504
  pipeline2.on("data", ({ value }) => {
5431
5505
  if (!found) {
5432
5506
  found = true;
5433
- resolve2(value);
5507
+ resolve4(value);
5434
5508
  }
5435
5509
  });
5436
5510
  pipeline2.on("end", () => {
5437
- if (!found) resolve2(null);
5511
+ if (!found) resolve4(null);
5438
5512
  });
5439
5513
  pipeline2.on("error", reject);
5440
5514
  });
@@ -5522,11 +5596,11 @@ var module_9 = {
5522
5596
  var telegram_native_single_default = module_9;
5523
5597
 
5524
5598
  // ../../packages/parser/src/formats/whatsapp-native-txt.ts
5525
- import * as fs12 from "fs";
5526
- import * as path8 from "path";
5599
+ import * as fs13 from "fs";
5600
+ import * as path9 from "path";
5527
5601
  import * as readline3 from "readline";
5528
5602
  function extractNameFromFilePath5(filePath) {
5529
- const basename13 = path8.basename(filePath);
5603
+ const basename13 = path9.basename(filePath);
5530
5604
  const matchZhCn = basename13.match(/^与(.+?)的\s*WhatsApp\s*聊天\.txt$/i);
5531
5605
  if (matchZhCn) return matchZhCn[1].trim();
5532
5606
  const matchZhTw = basename13.match(/^與(.+?)的\s*WhatsApp\s*對話\.txt$/i);
@@ -5534,7 +5608,7 @@ function extractNameFromFilePath5(filePath) {
5534
5608
  return basename13.replace(/\.txt$/i, "") || "\u672A\u77E5\u804A\u5929";
5535
5609
  }
5536
5610
  function shouldInferPrivateChatName(filePath, fallbackName) {
5537
- const basename13 = path8.basename(filePath);
5611
+ const basename13 = path9.basename(filePath);
5538
5612
  return /^_chat\.txt$/i.test(basename13) || /^whatsapp(?:[-_\s].*)?$/i.test(fallbackName);
5539
5613
  }
5540
5614
  function inferPrivateChatName(memberMap, fallbackName) {
@@ -5713,7 +5787,7 @@ async function* parseWhatsApp(options2) {
5713
5787
  messagesProcessed++;
5714
5788
  }
5715
5789
  };
5716
- const fileStream = fs12.createReadStream(filePath, { encoding: "utf-8" });
5790
+ const fileStream = fs13.createReadStream(filePath, { encoding: "utf-8" });
5717
5791
  const rl = readline3.createInterface({
5718
5792
  input: fileStream,
5719
5793
  crlfDelay: Infinity
@@ -5834,11 +5908,11 @@ var module_10 = {
5834
5908
  var whatsapp_native_txt_default = module_10;
5835
5909
 
5836
5910
  // ../../packages/parser/src/formats/qq-native-txt.ts
5837
- import * as fs13 from "fs";
5838
- import * as path9 from "path";
5911
+ import * as fs14 from "fs";
5912
+ import * as path10 from "path";
5839
5913
  import * as readline4 from "readline";
5840
5914
  function extractNameFromFilePath6(filePath) {
5841
- const basename13 = path9.basename(filePath);
5915
+ const basename13 = path10.basename(filePath);
5842
5916
  const name = basename13.replace(/\.txt$/i, "");
5843
5917
  return name || "\u672A\u77E5\u7FA4\u804A";
5844
5918
  }
@@ -5920,7 +5994,7 @@ async function* parseTxt(options2) {
5920
5994
  messagesProcessed++;
5921
5995
  }
5922
5996
  };
5923
- const fileStream = fs13.createReadStream(filePath, { encoding: "utf-8" });
5997
+ const fileStream = fs14.createReadStream(filePath, { encoding: "utf-8" });
5924
5998
  const rl = readline4.createInterface({
5925
5999
  input: fileStream,
5926
6000
  crlfDelay: Infinity
@@ -6020,8 +6094,8 @@ var module_11 = {
6020
6094
  var qq_native_txt_default = module_11;
6021
6095
 
6022
6096
  // ../../packages/parser/src/formats/instagram-native.ts
6023
- import * as fs14 from "fs";
6024
- import * as path10 from "path";
6097
+ import * as fs15 from "fs";
6098
+ import * as path11 from "path";
6025
6099
  var feature12 = {
6026
6100
  id: "instagram-native",
6027
6101
  name: "Instagram \u5B98\u65B9\u5BFC\u51FA",
@@ -6047,7 +6121,7 @@ function decodeInstagramText(text) {
6047
6121
  }
6048
6122
  }
6049
6123
  function extractNameFromFilePath7(filePath) {
6050
- const basename13 = path10.basename(filePath);
6124
+ const basename13 = path11.basename(filePath);
6051
6125
  return basename13.replace(/\.json$/i, "") || "\u672A\u77E5\u5BF9\u8BDD";
6052
6126
  }
6053
6127
  function isSystemMessage2(content) {
@@ -6116,7 +6190,7 @@ async function* parseInstagram(options2) {
6116
6190
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 Instagram \u804A\u5929\u8BB0\u5F55\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
6117
6191
  let data;
6118
6192
  try {
6119
- const content = fs14.readFileSync(filePath, "utf-8");
6193
+ const content = fs15.readFileSync(filePath, "utf-8");
6120
6194
  data = JSON.parse(content);
6121
6195
  } catch (error) {
6122
6196
  const err = new Error(`\u65E0\u6CD5\u89E3\u6790 Instagram JSON \u6587\u4EF6: ${error}`);
@@ -6211,8 +6285,8 @@ var import_stream_chain8 = __toESM(require_stream_chain(), 1);
6211
6285
  var import_stream_json8 = __toESM(require_stream_json(), 1);
6212
6286
  var import_Pick7 = __toESM(require_Pick(), 1);
6213
6287
  var import_StreamValues8 = __toESM(require_StreamValues(), 1);
6214
- import * as fs15 from "fs";
6215
- import * as path11 from "path";
6288
+ import * as fs16 from "fs";
6289
+ import * as path12 from "path";
6216
6290
  var { chain: chain8 } = import_stream_chain8.default;
6217
6291
  var { parser: parser9 } = import_stream_json8.default;
6218
6292
  var { pick: pick7 } = import_Pick7.default;
@@ -6295,12 +6369,12 @@ function normalizeIdentity(user) {
6295
6369
  };
6296
6370
  }
6297
6371
  function readJson(filePath) {
6298
- return JSON.parse(fs15.readFileSync(filePath, "utf8"));
6372
+ return JSON.parse(fs16.readFileSync(filePath, "utf8"));
6299
6373
  }
6300
6374
  function resolveManifestFile(manifestDir, relativePath) {
6301
- const resolved = path11.resolve(manifestDir, relativePath);
6302
- const relative2 = path11.relative(manifestDir, resolved);
6303
- if (relative2.startsWith("..") || path11.isAbsolute(relative2)) {
6375
+ const resolved = path12.resolve(manifestDir, relativePath);
6376
+ const relative2 = path12.relative(manifestDir, resolved);
6377
+ if (relative2.startsWith("..") || path12.isAbsolute(relative2)) {
6304
6378
  throw new Error(`Google Chat manifest path escapes its directory: ${relativePath}`);
6305
6379
  }
6306
6380
  return resolved;
@@ -6313,7 +6387,7 @@ function readManifest2(filePath) {
6313
6387
  if (manifest.chatType !== "private" && manifest.chatType !== "group") {
6314
6388
  throw new Error("Invalid Google Chat chat type");
6315
6389
  }
6316
- const manifestDir = path11.dirname(filePath);
6390
+ const manifestDir = path12.dirname(filePath);
6317
6391
  return {
6318
6392
  manifest,
6319
6393
  userInfoPath: resolveManifestFile(manifestDir, manifest.userInfoFile),
@@ -6391,7 +6465,7 @@ async function* parseGoogleChat(options2) {
6391
6465
  });
6392
6466
  }
6393
6467
  yield { type: "members", data: Array.from(memberMap.values()) };
6394
- const readStream = fs15.createReadStream(messagesPath, { encoding: "utf8" });
6468
+ const readStream = fs16.createReadStream(messagesPath, { encoding: "utf8" });
6395
6469
  let bytesRead = 0;
6396
6470
  let messagesProcessed = 0;
6397
6471
  readStream.on("data", (chunk) => {
@@ -6444,8 +6518,8 @@ var module_13 = {
6444
6518
  var google_chat_takeout_default = module_13;
6445
6519
 
6446
6520
  // ../../packages/parser/src/formats/line-native-txt.ts
6447
- import * as fs16 from "fs";
6448
- import * as path12 from "path";
6521
+ import * as fs17 from "fs";
6522
+ import * as path13 from "path";
6449
6523
  var feature14 = {
6450
6524
  id: "line-native-txt",
6451
6525
  name: "LINE \u5B98\u65B9\u5BFC\u51FA TXT",
@@ -6473,7 +6547,7 @@ var feature14 = {
6473
6547
  }
6474
6548
  };
6475
6549
  function extractNameFromFilePath8(filePath) {
6476
- const basename13 = path12.basename(filePath, ".txt");
6550
+ const basename13 = path13.basename(filePath, ".txt");
6477
6551
  const name = basename13.replace(/^\[LINE\]\s*/i, "").trim();
6478
6552
  return name || "\u672A\u77E5\u804A\u5929";
6479
6553
  }
@@ -6653,7 +6727,7 @@ async function* parseLINE(options2) {
6653
6727
  yield { type: "progress", data: initialProgress };
6654
6728
  onProgress?.(initialProgress);
6655
6729
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 LINE \u5BFC\u51FA\u6587\u4EF6\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
6656
- const content = fs16.readFileSync(filePath, "utf-8");
6730
+ const content = fs17.readFileSync(filePath, "utf-8");
6657
6731
  const lines = content.split("\n").map((line) => line.replace(/\r$/, ""));
6658
6732
  let currentDate = null;
6659
6733
  let chatName = extractNameFromFilePath8(filePath);
@@ -6961,12 +7035,12 @@ function findEntryFileInDirectory(dirPath, maxDepth = 1) {
6961
7035
  if (depth > maxDepth) return null;
6962
7036
  let entries;
6963
7037
  try {
6964
- entries = fs17.readdirSync(current, { withFileTypes: true });
7038
+ entries = fs18.readdirSync(current, { withFileTypes: true });
6965
7039
  } catch {
6966
7040
  return null;
6967
7041
  }
6968
7042
  for (const entry of entries) {
6969
- const full = path13.join(current, entry.name);
7043
+ const full = path14.join(current, entry.name);
6970
7044
  if (entry.isFile() && entry.name.endsWith(".json")) {
6971
7045
  const format = detectFormat(full);
6972
7046
  if (format) return full;
@@ -6974,7 +7048,7 @@ function findEntryFileInDirectory(dirPath, maxDepth = 1) {
6974
7048
  }
6975
7049
  for (const entry of entries) {
6976
7050
  if (entry.isDirectory()) {
6977
- const found = walk(path13.join(current, entry.name), depth + 1);
7051
+ const found = walk(path14.join(current, entry.name), depth + 1);
6978
7052
  if (found) return found;
6979
7053
  }
6980
7054
  }
@@ -7023,8 +7097,8 @@ function logNativeParserStatus() {
7023
7097
  }
7024
7098
 
7025
7099
  // ../../packages/node-runtime/src/import/perf-logger.ts
7026
- import * as fs18 from "fs";
7027
- import * as path14 from "path";
7100
+ import * as fs19 from "fs";
7101
+ import * as path15 from "path";
7028
7102
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
7029
7103
  LogLevel2["ERROR"] = "ERROR";
7030
7104
  LogLevel2["INFO"] = "INFO";
@@ -7036,11 +7110,11 @@ var currentLogFile = null;
7036
7110
  var errorCount = 0;
7037
7111
  function initPerfLog(sessionId, logDir) {
7038
7112
  try {
7039
- if (!fs18.existsSync(logDir)) {
7040
- fs18.mkdirSync(logDir, { recursive: true });
7113
+ if (!fs19.existsSync(logDir)) {
7114
+ fs19.mkdirSync(logDir, { recursive: true });
7041
7115
  }
7042
- currentLogFile = path14.join(logDir, `import_${sessionId}_${Date.now()}.log`);
7043
- fs18.writeFileSync(currentLogFile, `=== Import Log ===
7116
+ currentLogFile = path15.join(logDir, `import_${sessionId}_${Date.now()}.log`);
7117
+ fs19.writeFileSync(currentLogFile, `=== Import Log ===
7044
7118
  Start time: ${(/* @__PURE__ */ new Date()).toISOString()}
7045
7119
 
7046
7120
  `, "utf-8");
@@ -7061,7 +7135,7 @@ function logPerf(event, messagesProcessed, batchSize) {
7061
7135
  const logLine = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${event} | messages: ${messagesProcessed.toLocaleString()} | elapsed: ${duration}ms | speed: ${speed.toLocaleString()}/s | memory: ${memory}MB` + (batchSize ? ` | batch: ${batchSize}` : "") + "\n";
7062
7136
  if (currentLogFile) {
7063
7137
  try {
7064
- fs18.appendFileSync(currentLogFile, logLine, "utf-8");
7138
+ fs19.appendFileSync(currentLogFile, logLine, "utf-8");
7065
7139
  } catch {
7066
7140
  }
7067
7141
  }
@@ -7071,7 +7145,7 @@ function logPerf(event, messagesProcessed, batchSize) {
7071
7145
  function logPerfDetail(detail) {
7072
7146
  if (currentLogFile) {
7073
7147
  try {
7074
- fs18.appendFileSync(currentLogFile, ` ${detail}
7148
+ fs19.appendFileSync(currentLogFile, ` ${detail}
7075
7149
  `, "utf-8");
7076
7150
  } catch {
7077
7151
  }
@@ -7091,7 +7165,7 @@ function writeLogLine(level, message) {
7091
7165
  const logLine = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${message}
7092
7166
  `;
7093
7167
  try {
7094
- fs18.appendFileSync(currentLogFile, logLine, "utf-8");
7168
+ fs19.appendFileSync(currentLogFile, logLine, "utf-8");
7095
7169
  } catch {
7096
7170
  }
7097
7171
  }
@@ -7116,7 +7190,7 @@ Total members: ${totalMembers.toLocaleString()}
7116
7190
  Errors: ${errorCount}
7117
7191
  `;
7118
7192
  try {
7119
- fs18.appendFileSync(currentLogFile, summary, "utf-8");
7193
+ fs19.appendFileSync(currentLogFile, summary, "utf-8");
7120
7194
  } catch {
7121
7195
  }
7122
7196
  }
@@ -7215,8 +7289,8 @@ function segmentText(text, locale, minLength) {
7215
7289
  }
7216
7290
 
7217
7291
  // ../../packages/node-runtime/src/nlp/dict-manager.ts
7218
- import * as fs19 from "fs";
7219
- import * as path15 from "path";
7292
+ import * as fs20 from "fs";
7293
+ import * as path16 from "path";
7220
7294
  import { createHash } from "crypto";
7221
7295
  var DICT_DOWNLOAD_URL_BASE = "https://chatlab.fun/assets/nlp";
7222
7296
  var DICT_SHA256 = {
@@ -7228,19 +7302,19 @@ var AVAILABLE_DICTS = [
7228
7302
  { id: "zh-TW", label: "\u7E41\u9AD4\u4E2D\u6587", locale: "zh-TW" }
7229
7303
  ];
7230
7304
  function getDictFilePath(nlpDir, dictId) {
7231
- return path15.join(nlpDir, `${dictId}.dict`);
7305
+ return path16.join(nlpDir, `${dictId}.dict`);
7232
7306
  }
7233
7307
  function isDictDownloaded(nlpDir, dictId) {
7234
- return fs19.existsSync(getDictFilePath(nlpDir, dictId));
7308
+ return fs20.existsSync(getDictFilePath(nlpDir, dictId));
7235
7309
  }
7236
7310
  function getDictList(nlpDir) {
7237
7311
  return AVAILABLE_DICTS.map((d) => {
7238
7312
  const filePath = getDictFilePath(nlpDir, d.id);
7239
- const downloaded = fs19.existsSync(filePath);
7313
+ const downloaded = fs20.existsSync(filePath);
7240
7314
  let fileSize;
7241
7315
  if (downloaded) {
7242
7316
  try {
7243
- fileSize = fs19.statSync(filePath).size;
7317
+ fileSize = fs20.statSync(filePath).size;
7244
7318
  } catch {
7245
7319
  }
7246
7320
  }
@@ -7249,9 +7323,9 @@ function getDictList(nlpDir) {
7249
7323
  }
7250
7324
  function loadDictBuffer(nlpDir, dictId) {
7251
7325
  const filePath = getDictFilePath(nlpDir, dictId);
7252
- if (!fs19.existsSync(filePath)) return null;
7326
+ if (!fs20.existsSync(filePath)) return null;
7253
7327
  try {
7254
- return fs19.readFileSync(filePath);
7328
+ return fs20.readFileSync(filePath);
7255
7329
  } catch (error) {
7256
7330
  console.error(`[NLP DictManager] Failed to read dict file: ${filePath}`, error);
7257
7331
  return null;
@@ -7261,7 +7335,7 @@ async function downloadDict(nlpDir, dictId, onProgress) {
7261
7335
  if (!AVAILABLE_DICTS.find((d) => d.id === dictId)) {
7262
7336
  return { success: false, error: `Unknown dict: ${dictId}` };
7263
7337
  }
7264
- fs19.mkdirSync(nlpDir, { recursive: true });
7338
+ fs20.mkdirSync(nlpDir, { recursive: true });
7265
7339
  const url = `${DICT_DOWNLOAD_URL_BASE}/${dictId}.dict`;
7266
7340
  const filePath = getDictFilePath(nlpDir, dictId);
7267
7341
  const tmpPath = filePath + ".tmp";
@@ -7302,16 +7376,16 @@ async function downloadDict(nlpDir, dictId, onProgress) {
7302
7376
  if (actualSha256 !== expectedSha256) {
7303
7377
  return { success: false, error: "Dictionary integrity check failed (SHA256 mismatch)" };
7304
7378
  }
7305
- fs19.writeFileSync(tmpPath, buffer);
7306
- if (fs19.existsSync(filePath)) fs19.unlinkSync(filePath);
7307
- fs19.renameSync(tmpPath, filePath);
7379
+ fs20.writeFileSync(tmpPath, buffer);
7380
+ if (fs20.existsSync(filePath)) fs20.unlinkSync(filePath);
7381
+ fs20.renameSync(tmpPath, filePath);
7308
7382
  clearJiebaInstance(dictId);
7309
- console.log(`[NLP DictManager] Dict downloaded: ${dictId} (${fs19.statSync(filePath).size} bytes)`);
7383
+ console.log(`[NLP DictManager] Dict downloaded: ${dictId} (${fs20.statSync(filePath).size} bytes)`);
7310
7384
  return { success: true };
7311
7385
  } catch (error) {
7312
- if (fs19.existsSync(tmpPath)) {
7386
+ if (fs20.existsSync(tmpPath)) {
7313
7387
  try {
7314
- fs19.unlinkSync(tmpPath);
7388
+ fs20.unlinkSync(tmpPath);
7315
7389
  } catch {
7316
7390
  }
7317
7391
  }
@@ -7322,9 +7396,9 @@ async function downloadDict(nlpDir, dictId, onProgress) {
7322
7396
  }
7323
7397
  function deleteDict(nlpDir, dictId) {
7324
7398
  const filePath = getDictFilePath(nlpDir, dictId);
7325
- if (!fs19.existsSync(filePath)) return { success: true };
7399
+ if (!fs20.existsSync(filePath)) return { success: true };
7326
7400
  try {
7327
- fs19.unlinkSync(filePath);
7401
+ fs20.unlinkSync(filePath);
7328
7402
  clearJiebaInstance(dictId);
7329
7403
  console.log(`[NLP DictManager] Dict deleted: ${dictId}`);
7330
7404
  return { success: true };
@@ -7424,7 +7498,7 @@ function searchByFts(db, keywords, limit = 1e3, offset = 0) {
7424
7498
  }
7425
7499
 
7426
7500
  // ../../packages/node-runtime/src/import/streaming-importer.ts
7427
- import * as fs20 from "fs";
7501
+ import * as fs21 from "fs";
7428
7502
 
7429
7503
  // ../../packages/node-runtime/src/import/message-deduplicator.ts
7430
7504
  function generateFallbackMessageKey(message) {
@@ -7456,7 +7530,7 @@ function registerMessageAndCheckDuplicate(message, state) {
7456
7530
  // ../../packages/node-runtime/src/import/streaming-importer.ts
7457
7531
  var BATCH_COMMIT_SIZE = 5e4;
7458
7532
  var CHECKPOINT_INTERVAL = 2e5;
7459
- var yieldToEventLoop = () => new Promise((resolve2) => setImmediate(resolve2));
7533
+ var yieldToEventLoop = () => new Promise((resolve4) => setImmediate(resolve4));
7460
7534
  function defaultGenerateSessionId() {
7461
7535
  const ts = Date.now();
7462
7536
  const rand = Math.random().toString(36).substring(2, 8);
@@ -7959,7 +8033,7 @@ async function streamParseFileInfo(filePath, deps) {
7959
8033
  if (!formatFeature) {
7960
8034
  throw new Error("Unrecognized file format");
7961
8035
  }
7962
- const fileSize = fs20.statSync(filePath).size;
8036
+ const fileSize = fs21.statSync(filePath).size;
7963
8037
  deps.onProgress({
7964
8038
  stage: "parsing",
7965
8039
  bytesRead: 0,
@@ -8048,7 +8122,7 @@ async function streamParseFileInfo(filePath, deps) {
8048
8122
  }
8049
8123
  db.close();
8050
8124
  try {
8051
- if (fs20.existsSync(tempDbPath)) fs20.unlinkSync(tempDbPath);
8125
+ if (fs21.existsSync(tempDbPath)) fs21.unlinkSync(tempDbPath);
8052
8126
  } catch {
8053
8127
  }
8054
8128
  throw error;
@@ -8693,8 +8767,8 @@ async function analyzeAutoImportFile(filePath, deps, options2 = {}) {
8693
8767
  }
8694
8768
 
8695
8769
  // ../../packages/node-runtime/src/import/import-lock.ts
8696
- import * as fs21 from "fs";
8697
- import * as path16 from "path";
8770
+ import * as fs22 from "fs";
8771
+ import * as path17 from "path";
8698
8772
  import { randomUUID } from "crypto";
8699
8773
  var IMPORT_LOCK_FILENAME = ".chatlab-import.lock";
8700
8774
  var IMPORT_IN_PROGRESS_ERROR_KEY = "error.import_in_progress";
@@ -8708,7 +8782,7 @@ var ImportInProgressError = class extends Error {
8708
8782
  };
8709
8783
  function parseOwner(lockPath) {
8710
8784
  try {
8711
- const parsed = JSON.parse(fs21.readFileSync(lockPath, "utf-8"));
8785
+ const parsed = JSON.parse(fs22.readFileSync(lockPath, "utf-8"));
8712
8786
  if (typeof parsed.pid !== "number" || !Number.isInteger(parsed.pid) || parsed.pid <= 0 || typeof parsed.token !== "string" || parsed.token.length === 0 || typeof parsed.startedAt !== "number") {
8713
8787
  return null;
8714
8788
  }
@@ -8731,13 +8805,13 @@ function removeStaleLock(lockPath) {
8731
8805
  if (isProcessRunning(owner.pid)) return false;
8732
8806
  } else {
8733
8807
  try {
8734
- if (Date.now() - fs21.statSync(lockPath).mtimeMs < 5e3) return false;
8808
+ if (Date.now() - fs22.statSync(lockPath).mtimeMs < 5e3) return false;
8735
8809
  } catch {
8736
8810
  return true;
8737
8811
  }
8738
8812
  }
8739
8813
  try {
8740
- fs21.unlinkSync(lockPath);
8814
+ fs22.unlinkSync(lockPath);
8741
8815
  appLogger.warn("import-lock", "Removed stale import lock", { ownerPid: owner?.pid });
8742
8816
  return true;
8743
8817
  } catch {
@@ -8746,7 +8820,7 @@ function removeStaleLock(lockPath) {
8746
8820
  }
8747
8821
  function releaseLock(lockPath, fd, owner) {
8748
8822
  try {
8749
- fs21.closeSync(fd);
8823
+ fs22.closeSync(fd);
8750
8824
  } catch (error) {
8751
8825
  appLogger.error("import-lock", "Failed to close import lock", error);
8752
8826
  }
@@ -8755,19 +8829,19 @@ function releaseLock(lockPath, fd, owner) {
8755
8829
  appLogger.warn("import-lock", "Import lock ownership changed before release");
8756
8830
  return;
8757
8831
  }
8758
- fs21.unlinkSync(lockPath);
8832
+ fs22.unlinkSync(lockPath);
8759
8833
  appLogger.info("import-lock", "Import lock released");
8760
8834
  } catch (error) {
8761
8835
  appLogger.error("import-lock", "Failed to release import lock", error);
8762
8836
  }
8763
8837
  }
8764
8838
  async function withDataDirImportLock(userDataDir, task) {
8765
- fs21.mkdirSync(userDataDir, { recursive: true });
8766
- const lockPath = path16.join(userDataDir, IMPORT_LOCK_FILENAME);
8839
+ fs22.mkdirSync(userDataDir, { recursive: true });
8840
+ const lockPath = path17.join(userDataDir, IMPORT_LOCK_FILENAME);
8767
8841
  let fd = null;
8768
8842
  for (let attempt = 0; attempt < 2; attempt++) {
8769
8843
  try {
8770
- fd = fs21.openSync(lockPath, "wx");
8844
+ fd = fs22.openSync(lockPath, "wx");
8771
8845
  break;
8772
8846
  } catch (error) {
8773
8847
  const code = error.code;
@@ -8786,8 +8860,8 @@ async function withDataDirImportLock(userDataDir, task) {
8786
8860
  startedAt: Date.now()
8787
8861
  };
8788
8862
  try {
8789
- fs21.writeFileSync(fd, JSON.stringify(owner), "utf-8");
8790
- fs21.fsyncSync(fd);
8863
+ fs22.writeFileSync(fd, JSON.stringify(owner), "utf-8");
8864
+ fs22.fsyncSync(fd);
8791
8865
  appLogger.info("import-lock", "Import lock acquired");
8792
8866
  return await task();
8793
8867
  } finally {
@@ -8807,8 +8881,8 @@ var ArchiveImportError = class extends Error {
8807
8881
 
8808
8882
  // ../../packages/node-runtime/src/import/archive/archive-reader.ts
8809
8883
  var import_yauzl = __toESM(require_yauzl(), 1);
8810
- import * as fs22 from "fs";
8811
- import * as path17 from "path";
8884
+ import * as fs23 from "fs";
8885
+ import * as path18 from "path";
8812
8886
  import { pipeline } from "stream/promises";
8813
8887
  var DEFAULT_MAX_ENTRIES = 1e5;
8814
8888
  var DEFAULT_MAX_ENTRY_BYTES = 20 * 1024 * 1024 * 1024;
@@ -8927,8 +9001,8 @@ var ZipArchiveReader = class {
8927
9001
  await this.visitEntries(async (entry, openStream) => {
8928
9002
  const destination = targets.get(entry.name);
8929
9003
  if (!destination || entry.isDirectory) return;
8930
- fs22.mkdirSync(path17.dirname(destination), { recursive: true });
8931
- await pipeline(await openStream(), fs22.createWriteStream(destination, { flags: "wx" }));
9004
+ fs23.mkdirSync(path18.dirname(destination), { recursive: true });
9005
+ await pipeline(await openStream(), fs23.createWriteStream(destination, { flags: "wx" }));
8932
9006
  remaining.delete(entry.name);
8933
9007
  });
8934
9008
  if (remaining.size > 0) {
@@ -8945,8 +9019,8 @@ var import_stream_chain9 = __toESM(require_stream_chain(), 1);
8945
9019
  var import_stream_json9 = __toESM(require_stream_json(), 1);
8946
9020
  var import_Pick8 = __toESM(require_Pick(), 1);
8947
9021
  var import_StreamValues9 = __toESM(require_StreamValues(), 1);
8948
- import * as fs23 from "fs";
8949
- import * as path18 from "path";
9022
+ import * as fs24 from "fs";
9023
+ import * as path19 from "path";
8950
9024
  var { chain: chain9 } = import_stream_chain9.default;
8951
9025
  var { parser: parser10 } = import_stream_json9.default;
8952
9026
  var { pick: pick8 } = import_Pick8.default;
@@ -9075,16 +9149,16 @@ var GoogleChatTakeoutResolver = class {
9075
9149
  `Google Chat conversation is missing required files: ${chat.chatId}`
9076
9150
  );
9077
9151
  }
9078
- fs23.mkdirSync(targetDir, { recursive: true });
9152
+ fs24.mkdirSync(targetDir, { recursive: true });
9079
9153
  await reader.pipeEntries(
9080
9154
  /* @__PURE__ */ new Map([
9081
- [userInfoEntry, path18.join(targetDir, "user_info.json")],
9082
- [groupInfoEntry, path18.join(targetDir, "group_info.json")],
9083
- [messagesEntry, path18.join(targetDir, "messages.json")]
9155
+ [userInfoEntry, path19.join(targetDir, "user_info.json")],
9156
+ [groupInfoEntry, path19.join(targetDir, "group_info.json")],
9157
+ [messagesEntry, path19.join(targetDir, "messages.json")]
9084
9158
  ])
9085
9159
  );
9086
- const manifestPath = path18.join(targetDir, "google-chat-import.json");
9087
- fs23.writeFileSync(
9160
+ const manifestPath = path19.join(targetDir, "google-chat-import.json");
9161
+ fs24.writeFileSync(
9088
9162
  manifestPath,
9089
9163
  JSON.stringify(
9090
9164
  {
@@ -9107,8 +9181,8 @@ var GoogleChatTakeoutResolver = class {
9107
9181
  };
9108
9182
 
9109
9183
  // ../../packages/node-runtime/src/import/archive/source-manager.ts
9110
- import * as fs24 from "fs";
9111
- import * as path19 from "path";
9184
+ import * as fs25 from "fs";
9185
+ import * as path20 from "path";
9112
9186
  import { randomUUID as randomUUID2 } from "crypto";
9113
9187
  var DEFAULT_TTL_MS = 30 * 60 * 1e3;
9114
9188
  var ArchiveImportSourceManager = class {
@@ -9119,11 +9193,11 @@ var ArchiveImportSourceManager = class {
9119
9193
  now;
9120
9194
  resolvers;
9121
9195
  constructor(options2 = {}) {
9122
- this.tempRoot = options2.tempRoot ?? path19.join(process.cwd(), ".chatlab-import-sources");
9196
+ this.tempRoot = options2.tempRoot ?? createChatLabTempDir("imports", "sources-");
9123
9197
  this.ttlMs = options2.ttlMs ?? DEFAULT_TTL_MS;
9124
9198
  this.now = options2.now ?? Date.now;
9125
9199
  this.resolvers = options2.resolvers ?? [new GoogleChatTakeoutResolver()];
9126
- fs24.mkdirSync(this.tempRoot, { recursive: true });
9200
+ fs25.mkdirSync(this.tempRoot, { recursive: true });
9127
9201
  }
9128
9202
  prepareLocalArchive(archivePath) {
9129
9203
  return this.prepareArchive(archivePath, false);
@@ -9180,7 +9254,7 @@ var ArchiveImportSourceManager = class {
9180
9254
  `Archive conversation was not found: ${chatId}`
9181
9255
  );
9182
9256
  }
9183
- const materializedDir = fs24.mkdtempSync(path19.join(this.tempRoot, `materialized-${sourceId}-`));
9257
+ const materializedDir = fs25.mkdtempSync(path20.join(this.tempRoot, `materialized-${sourceId}-`));
9184
9258
  try {
9185
9259
  const reader = new ZipArchiveReader(record.archivePath);
9186
9260
  const materialized = await record.resolver.materialize(reader, chat, materializedDir);
@@ -9231,7 +9305,7 @@ var ArchiveImportSourceManager = class {
9231
9305
  }
9232
9306
  removePath(targetPath) {
9233
9307
  try {
9234
- fs24.rmSync(targetPath, { recursive: true, force: true });
9308
+ fs25.rmSync(targetPath, { recursive: true, force: true });
9235
9309
  } catch {
9236
9310
  }
9237
9311
  }
@@ -9301,12 +9375,12 @@ ${rawErrorLabel}: ${details}`;
9301
9375
  }
9302
9376
 
9303
9377
  // ../../packages/node-runtime/src/ai/assistant-parser.ts
9304
- import * as path20 from "path";
9378
+ import * as path21 from "path";
9305
9379
  import matter from "gray-matter";
9306
9380
  function parseAssistantFile(content, filePath) {
9307
9381
  try {
9308
9382
  const { data: fm, content: body } = matter(content);
9309
- const id = fm.id ?? path20.basename(filePath, ".md");
9383
+ const id = fm.id ?? path21.basename(filePath, ".md");
9310
9384
  const name = fm.name;
9311
9385
  if (!name) return null;
9312
9386
  return {
@@ -9316,6 +9390,8 @@ function parseAssistantFile(content, filePath) {
9316
9390
  presetQuestions: parseStringArray(fm.presetQuestions),
9317
9391
  allowedBuiltinTools: normalizeBuiltinToolNames(parseStringArray(fm.allowedBuiltinTools)),
9318
9392
  builtinId: typeof fm.builtinId === "string" ? fm.builtinId : void 0,
9393
+ builtinVersion: parsePositiveInteger(fm.builtinVersion),
9394
+ builtinDigest: typeof fm.builtinDigest === "string" ? fm.builtinDigest : void 0,
9319
9395
  applicableChatTypes: parseChatTypes(fm.applicableChatTypes),
9320
9396
  supportedLocales: parseStringArray(fm.supportedLocales)
9321
9397
  };
@@ -9329,6 +9405,8 @@ function serializeAssistant(config) {
9329
9405
  name: config.name
9330
9406
  };
9331
9407
  if (config.builtinId) fm.builtinId = config.builtinId;
9408
+ if (config.builtinVersion) fm.builtinVersion = config.builtinVersion;
9409
+ if (config.builtinDigest) fm.builtinDigest = config.builtinDigest;
9332
9410
  if (config.applicableChatTypes?.length) fm.applicableChatTypes = config.applicableChatTypes;
9333
9411
  if (config.supportedLocales?.length) fm.supportedLocales = config.supportedLocales;
9334
9412
  if (config.allowedBuiltinTools?.length) fm.allowedBuiltinTools = normalizeBuiltinToolNames(config.allowedBuiltinTools);
@@ -9341,12 +9419,145 @@ function parseStringArray(raw) {
9341
9419
  if (Array.isArray(raw)) return raw.map(String).filter(Boolean);
9342
9420
  return [];
9343
9421
  }
9422
+ function parsePositiveInteger(raw) {
9423
+ return typeof raw === "number" && Number.isInteger(raw) && raw > 0 ? raw : void 0;
9424
+ }
9344
9425
  function parseChatTypes(raw) {
9345
9426
  if (!Array.isArray(raw)) return void 0;
9346
9427
  const valid = raw.filter((v) => v === "group" || v === "private");
9347
9428
  return valid.length > 0 ? valid : void 0;
9348
9429
  }
9349
9430
 
9431
+ // ../../packages/node-runtime/src/ai/default-assistants.ts
9432
+ var ALL_ANALYSIS_TOOL_NAMES = BUILTIN_TOOL_CATALOG.filter((tool) => tool.category === "analysis").map(
9433
+ (tool) => tool.name
9434
+ );
9435
+ var DEFAULT_GENERAL_ASSISTANT_CONFIGS = [
9436
+ {
9437
+ id: "general_cn",
9438
+ name: "\u901A\u7528\u5206\u6790\u52A9\u624B",
9439
+ builtinVersion: 2,
9440
+ supportedLocales: ["zh-CN"],
9441
+ allowedBuiltinTools: [...ALL_ANALYSIS_TOOL_NAMES],
9442
+ presetQuestions: [
9443
+ "\u6700\u8FD1\u90FD\u5728\u804A\u4EC0\u4E48\uFF1F",
9444
+ "\u8C01\u662F\u6700\u6D3B\u8DC3\u7684\u4EBA\uFF1F",
9445
+ "\u804A\u5929\u7684\u6D3B\u8DC3\u65F6\u95F4\u662F\u4EC0\u4E48\u65F6\u5019\uFF1F",
9446
+ "\u5E2E\u6211\u641C\u7D22\u5173\u4E8E\u300C\u65C5\u6E38\u300D\u7684\u804A\u5929\u8BB0\u5F55",
9447
+ "\u5206\u6790\u4E00\u4E0B\u804A\u5929\u6D3B\u8DC3\u65F6\u95F4\u6BB5"
9448
+ ],
9449
+ systemPrompt: `\u4F60\u662F ChatLab \u91CC\u7684\u804A\u5929\u8BB0\u5F55\u5206\u6790\u642D\u6863\u3002\u4F60\u64C5\u957F\u4ECE\u7FA4\u804A\u6216\u79C1\u804A\u8BB0\u5F55\u4E2D\u68B3\u7406\u4E8B\u5B9E\u3001\u65F6\u95F4\u7EBF\u3001\u8BDD\u9898\u53D8\u5316\u3001\u4E92\u52A8\u65B9\u5F0F\u548C\u503C\u5F97\u6CE8\u610F\u7684\u6A21\u5F0F\uFF0C\u5E2E\u52A9\u7528\u6237\u66F4\u6E05\u695A\u5730\u7406\u89E3\u4E00\u6BB5\u5BF9\u8BDD\uFF0C\u800C\u4E0D\u662F\u673A\u68B0\u5730\u751F\u6210\u5206\u6790\u62A5\u544A\u3002
9450
+
9451
+ ## \u4EA4\u6D41\u65B9\u5F0F
9452
+
9453
+ - \u8DDF\u968F\u7528\u6237\u4F7F\u7528\u7684\u8BED\u8A00\u548C\u4EA4\u6D41\u65B9\u5F0F\uFF0C\u8BF4\u81EA\u7136\u3001\u76F4\u63A5\u7684\u4EBA\u8BDD\uFF0C\u907F\u514D\u5BA2\u670D\u8154\u548C\u8FC7\u5EA6\u6B63\u5F0F\u7684\u8868\u8FBE\u3002
9454
+ - \u7B80\u5355\u95EE\u9898\u76F4\u63A5\u56DE\u7B54\uFF1B\u590D\u6742\u95EE\u9898\u518D\u5206\u5C42\u8BF4\u660E\u3002\u53EA\u6709\u786E\u5B9E\u6709\u52A9\u4E8E\u7406\u89E3\u65F6\uFF0C\u624D\u4F7F\u7528\u6807\u9898\u3001\u5217\u8868\u6216\u8868\u683C\u3002
9455
+ - \u5728\u8BC1\u636E\u5141\u8BB8\u65F6\u7ED9\u51FA\u660E\u786E\u5224\u65AD\uFF0C\u4E0D\u4E3A\u4E86\u663E\u5F97\u4E2D\u7ACB\u800C\u53EA\u7F57\u5217\u53EF\u80FD\u6027\uFF1B\u65E0\u6CD5\u786E\u8BA4\u7684\u90E8\u5206\u8981\u5766\u7387\u8BF4\u660E\u3002
9456
+ - \u8BED\u6C14\u53EF\u4EE5\u8F7B\u677E\u3001\u6709\u4E00\u70B9\u81EA\u7136\u7684\u5E7D\u9ED8\u611F\uFF0C\u4F46\u4E0D\u8981\u4E3A\u4E86\u6D3B\u8DC3\u6C14\u6C1B\u5F3A\u884C\u73A9\u6897\u3001\u5806\u8868\u60C5\u6216\u727A\u7272\u51C6\u786E\u6027\u3002
9457
+
9458
+ ## \u5206\u6790\u8FB9\u754C
9459
+
9460
+ - \u660E\u786E\u533A\u5206\u804A\u5929\u8BB0\u5F55\u4E2D\u80FD\u591F\u786E\u8BA4\u7684\u4E8B\u5B9E\u3001\u57FA\u4E8E\u8BC1\u636E\u4F5C\u51FA\u7684\u63A8\u65AD\uFF0C\u4EE5\u53CA\u6682\u65F6\u65E0\u6CD5\u5224\u65AD\u7684\u90E8\u5206\u3002
9461
+ - \u6D89\u53CA\u6027\u683C\u3001\u60C5\u7EEA\u3001\u5173\u7CFB\u548C\u52A8\u673A\u65F6\u5C24\u5176\u8C28\u614E\uFF0C\u4E0D\u66FF\u5F53\u4E8B\u4EBA\u7F16\u9020\u5FC3\u7406\u6D3B\u52A8\uFF0C\u4E5F\u4E0D\u8F7B\u6613\u7ED9\u4EBA\u8D34\u6807\u7B7E\u3002
9462
+ - \u53EF\u4EE5\u9002\u91CF\u5F15\u7528\u6709\u4EE3\u8868\u6027\u7684\u539F\u8BDD\u548C\u6570\u636E\u652F\u6491\u7ED3\u8BBA\uFF0C\u4F46\u4E0D\u8981\u5927\u6BB5\u5806\u780C\u804A\u5929\u8BB0\u5F55\u3002
9463
+ - \u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\uFF0C\u4E0D\u8BF4\u6559\u3001\u4E0D\u64C5\u81EA\u7ED9\u4EBA\u751F\u5EFA\u8BAE\uFF0C\u4E5F\u4E0D\u628A\u6BCF\u6B21\u56DE\u7B54\u90FD\u5199\u6210\u603B\u7ED3\u62A5\u544A\u3002`
9464
+ },
9465
+ {
9466
+ id: "general_tw",
9467
+ name: "\u901A\u7528\u5206\u6790\u52A9\u624B",
9468
+ builtinVersion: 2,
9469
+ supportedLocales: ["zh-TW"],
9470
+ allowedBuiltinTools: [...ALL_ANALYSIS_TOOL_NAMES],
9471
+ presetQuestions: [
9472
+ "\u6700\u8FD1\u90FD\u5728\u804A\u4EC0\u9EBC\uFF1F",
9473
+ "\u8AB0\u662F\u6700\u6D3B\u8E8D\u7684\u4EBA\uFF1F",
9474
+ "\u804A\u5929\u7684\u6D3B\u8E8D\u6642\u9593\u662F\u4EC0\u9EBC\u6642\u5019\uFF1F",
9475
+ "\u5E6B\u6211\u641C\u5C0B\u95DC\u65BC\u300C\u65C5\u904A\u300D\u7684\u804A\u5929\u8A18\u9304",
9476
+ "\u5206\u6790\u4E00\u4E0B\u804A\u5929\u6D3B\u8E8D\u6642\u6BB5"
9477
+ ],
9478
+ systemPrompt: `\u4F60\u662F ChatLab \u88E1\u7684\u804A\u5929\u8A18\u9304\u5206\u6790\u642D\u6A94\u3002\u4F60\u64C5\u9577\u5F9E\u7FA4\u804A\u6216\u79C1\u804A\u8A18\u9304\u4E2D\u68B3\u7406\u4E8B\u5BE6\u3001\u6642\u9593\u7DDA\u3001\u8A71\u984C\u8B8A\u5316\u3001\u4E92\u52D5\u65B9\u5F0F\u548C\u503C\u5F97\u6CE8\u610F\u7684\u6A21\u5F0F\uFF0C\u5E6B\u52A9\u4F7F\u7528\u8005\u66F4\u6E05\u695A\u5730\u7406\u89E3\u4E00\u6BB5\u5C0D\u8A71\uFF0C\u800C\u4E0D\u662F\u6A5F\u68B0\u5730\u7522\u751F\u5206\u6790\u5831\u544A\u3002
9479
+
9480
+ ## \u4EA4\u6D41\u65B9\u5F0F
9481
+
9482
+ - \u8DDF\u96A8\u4F7F\u7528\u8005\u4F7F\u7528\u7684\u8A9E\u8A00\u548C\u4EA4\u6D41\u65B9\u5F0F\uFF0C\u8AAA\u81EA\u7136\u3001\u76F4\u63A5\u7684\u4EBA\u8A71\uFF0C\u907F\u514D\u5BA2\u670D\u8154\u548C\u904E\u5EA6\u6B63\u5F0F\u7684\u8868\u9054\u3002
9483
+ - \u7C21\u55AE\u554F\u984C\u76F4\u63A5\u56DE\u7B54\uFF1B\u8907\u96DC\u554F\u984C\u518D\u5206\u5C64\u8AAA\u660E\u3002\u53EA\u6709\u78BA\u5BE6\u6709\u52A9\u65BC\u7406\u89E3\u6642\uFF0C\u624D\u4F7F\u7528\u6A19\u984C\u3001\u5217\u8868\u6216\u8868\u683C\u3002
9484
+ - \u5728\u8B49\u64DA\u5141\u8A31\u6642\u7D66\u51FA\u660E\u78BA\u5224\u65B7\uFF0C\u4E0D\u70BA\u4E86\u986F\u5F97\u4E2D\u7ACB\u800C\u53EA\u7F85\u5217\u53EF\u80FD\u6027\uFF1B\u7121\u6CD5\u78BA\u8A8D\u7684\u90E8\u5206\u8981\u5766\u7387\u8AAA\u660E\u3002
9485
+ - \u8A9E\u6C23\u53EF\u4EE5\u8F15\u9B06\u3001\u6709\u4E00\u9EDE\u81EA\u7136\u7684\u5E7D\u9ED8\u611F\uFF0C\u4F46\u4E0D\u8981\u70BA\u4E86\u6D3B\u8E8D\u6C23\u6C1B\u5F37\u884C\u73A9\u6897\u3001\u5806\u8868\u60C5\u6216\u72A7\u7272\u6E96\u78BA\u6027\u3002
9486
+
9487
+ ## \u5206\u6790\u908A\u754C
9488
+
9489
+ - \u660E\u78BA\u5340\u5206\u804A\u5929\u8A18\u9304\u4E2D\u80FD\u5920\u78BA\u8A8D\u7684\u4E8B\u5BE6\u3001\u57FA\u65BC\u8B49\u64DA\u4F5C\u51FA\u7684\u63A8\u8AD6\uFF0C\u4EE5\u53CA\u66AB\u6642\u7121\u6CD5\u5224\u65B7\u7684\u90E8\u5206\u3002
9490
+ - \u6D89\u53CA\u6027\u683C\u3001\u60C5\u7DD2\u3001\u95DC\u4FC2\u548C\u52D5\u6A5F\u6642\u5C24\u5176\u8B39\u614E\uFF0C\u4E0D\u66FF\u7576\u4E8B\u4EBA\u7DE8\u9020\u5FC3\u7406\u6D3B\u52D5\uFF0C\u4E5F\u4E0D\u8F15\u6613\u7D66\u4EBA\u8CBC\u6A19\u7C64\u3002
9491
+ - \u53EF\u4EE5\u9069\u91CF\u5F15\u7528\u6709\u4EE3\u8868\u6027\u7684\u539F\u8A71\u548C\u8CC7\u6599\u652F\u6490\u7D50\u8AD6\uFF0C\u4F46\u4E0D\u8981\u5927\u6BB5\u5806\u780C\u804A\u5929\u8A18\u9304\u3002
9492
+ - \u9664\u975E\u4F7F\u7528\u8005\u660E\u78BA\u8981\u6C42\uFF0C\u4E0D\u8AAA\u6559\u3001\u4E0D\u64C5\u81EA\u7D66\u4EBA\u751F\u5EFA\u8B70\uFF0C\u4E5F\u4E0D\u628A\u6BCF\u6B21\u56DE\u7B54\u90FD\u5BEB\u6210\u7E3D\u7D50\u5831\u544A\u3002`
9493
+ },
9494
+ {
9495
+ id: "general_en",
9496
+ name: "General Analysis Assistant",
9497
+ builtinVersion: 2,
9498
+ supportedLocales: ["en"],
9499
+ allowedBuiltinTools: [...ALL_ANALYSIS_TOOL_NAMES],
9500
+ presetQuestions: [
9501
+ "What have people been chatting about recently?",
9502
+ "Who are the most active members?",
9503
+ 'Search chat records about "travel"',
9504
+ "Analyze the active hours of the chat"
9505
+ ],
9506
+ systemPrompt: `You are ChatLab's chat analysis partner. You help users make sense of group or private chat records by clarifying facts, timelines, topic shifts, interaction patterns, and other details worth noticing. Your job is to help the user understand a conversation, not to mechanically produce an analysis report.
9507
+
9508
+ ## How to Communicate
9509
+
9510
+ - Match the user's language and conversational style. Sound natural and direct, not like customer support or a formal report.
9511
+ - Answer simple questions directly. Add structure only for genuinely complex questions, and use headings, lists, or tables only when they improve understanding.
9512
+ - Give a clear judgment when the evidence supports one instead of merely listing possibilities. Be candid about anything that cannot be established.
9513
+ - A relaxed tone and light, natural humor are welcome, but never force jokes, emojis, or entertainment at the expense of accuracy.
9514
+
9515
+ ## Analysis Boundaries
9516
+
9517
+ - Clearly distinguish what the chat records establish, what is a reasonable inference, and what remains unknown.
9518
+ - Be especially careful with personality, emotion, relationships, and motives. Do not invent inner states or casually label people.
9519
+ - Use a small number of representative quotes or data points when they support the conclusion, but do not dump large blocks of chat logs.
9520
+ - Unless the user asks, do not moralize, give unsolicited life advice, or turn every response into a summary report.`
9521
+ },
9522
+ {
9523
+ id: "general_ja",
9524
+ name: "\u6C4E\u7528\u5206\u6790\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8",
9525
+ builtinVersion: 2,
9526
+ supportedLocales: ["ja"],
9527
+ allowedBuiltinTools: [...ALL_ANALYSIS_TOOL_NAMES],
9528
+ presetQuestions: [
9529
+ "\u6700\u8FD1\u307F\u3093\u306A\u4F55\u3092\u8A71\u3057\u3066\u308B\uFF1F",
9530
+ "\u4E00\u756A\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u30E1\u30F3\u30D0\u30FC\u306F\u8AB0\uFF1F",
9531
+ "\u300C\u65C5\u884C\u300D\u306B\u95A2\u3059\u308B\u30C1\u30E3\u30C3\u30C8\u8A18\u9332\u3092\u691C\u7D22\u3057\u3066",
9532
+ "\u30C1\u30E3\u30C3\u30C8\u306E\u6D3B\u767A\u306A\u6642\u9593\u5E2F\u3092\u5206\u6790\u3057\u3066"
9533
+ ],
9534
+ systemPrompt: `\u3042\u306A\u305F\u306F ChatLab \u306E\u30C1\u30E3\u30C3\u30C8\u5206\u6790\u30D1\u30FC\u30C8\u30CA\u30FC\u3067\u3059\u3002\u30B0\u30EB\u30FC\u30D7\u30C1\u30E3\u30C3\u30C8\u3084\u500B\u4EBA\u30C1\u30E3\u30C3\u30C8\u306E\u8A18\u9332\u304B\u3089\u3001\u4E8B\u5B9F\u3001\u6642\u7CFB\u5217\u3001\u8A71\u984C\u306E\u5909\u5316\u3001\u3084\u308A\u53D6\u308A\u306E\u50BE\u5411\u3001\u6CE8\u76EE\u3059\u3079\u304D\u70B9\u3092\u6574\u7406\u3057\u3001\u6A5F\u68B0\u7684\u306A\u5206\u6790\u30EC\u30DD\u30FC\u30C8\u3067\u306F\u306A\u304F\u3001\u4F1A\u8A71\u3092\u3088\u308A\u6DF1\u304F\u7406\u89E3\u3067\u304D\u308B\u56DE\u7B54\u3092\u5C4A\u3051\u307E\u3059\u3002
9535
+
9536
+ ## \u30B3\u30DF\u30E5\u30CB\u30B1\u30FC\u30B7\u30E7\u30F3
9537
+
9538
+ - \u30E6\u30FC\u30B6\u30FC\u306E\u8A00\u8A9E\u3068\u8A71\u3057\u65B9\u306B\u5408\u308F\u305B\u3001\u30AB\u30B9\u30BF\u30DE\u30FC\u30B5\u30DD\u30FC\u30C8\u3084\u5805\u3044\u5831\u544A\u66F8\u306E\u3088\u3046\u3067\u306F\u306A\u304F\u3001\u81EA\u7136\u3067\u7387\u76F4\u306A\u8A00\u8449\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002
9539
+ - \u7C21\u5358\u306A\u8CEA\u554F\u306B\u306F\u7AEF\u7684\u306B\u7B54\u3048\u3001\u8907\u96D1\u306A\u8CEA\u554F\u3060\u3051\u3092\u6574\u7406\u3057\u3066\u8AAC\u660E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u898B\u51FA\u3057\u3001\u7B87\u6761\u66F8\u304D\u3001\u8868\u306F\u7406\u89E3\u3092\u52A9\u3051\u308B\u5834\u5408\u306B\u3060\u3051\u4F7F\u3044\u307E\u3059\u3002
9540
+ - \u6839\u62E0\u304C\u5341\u5206\u306A\u3089\u66D6\u6627\u306B\u53EF\u80FD\u6027\u3092\u4E26\u3079\u308B\u3060\u3051\u3067\u306A\u304F\u3001\u660E\u78BA\u306A\u5224\u65AD\u3092\u793A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u78BA\u8A8D\u3067\u304D\u306A\u3044\u3053\u3068\u306F\u7387\u76F4\u306B\u4F1D\u3048\u307E\u3059\u3002
9541
+ - \u8EFD\u304F\u81EA\u7136\u306A\u30E6\u30FC\u30E2\u30A2\u306F\u69CB\u3044\u307E\u305B\u3093\u304C\u3001\u7121\u7406\u306B\u5197\u8AC7\u3084\u7D75\u6587\u5B57\u3092\u5165\u308C\u305F\u308A\u3001\u6B63\u78BA\u3055\u3092\u640D\u306A\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
9542
+
9543
+ ## \u5206\u6790\u4E0A\u306E\u5883\u754C
9544
+
9545
+ - \u8A18\u9332\u304B\u3089\u78BA\u8A8D\u3067\u304D\u308B\u4E8B\u5B9F\u3001\u6839\u62E0\u306B\u57FA\u3065\u304F\u63A8\u6E2C\u3001\u73FE\u6642\u70B9\u3067\u306F\u5224\u65AD\u3067\u304D\u306A\u3044\u3053\u3068\u3092\u660E\u78BA\u306B\u533A\u5225\u3057\u3066\u304F\u3060\u3055\u3044\u3002
9546
+ - \u6027\u683C\u3001\u611F\u60C5\u3001\u4EBA\u9593\u95A2\u4FC2\u3001\u52D5\u6A5F\u306B\u3064\u3044\u3066\u306F\u7279\u306B\u614E\u91CD\u306B\u6271\u3044\u3001\u672C\u4EBA\u306E\u5185\u9762\u3092\u4F5C\u308A\u4E0A\u3052\u305F\u308A\u3001\u5B89\u6613\u306B\u30EC\u30C3\u30C6\u30EB\u3092\u8CBC\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
9547
+ - \u7D50\u8AD6\u3092\u652F\u3048\u308B\u5834\u5408\u306F\u4EE3\u8868\u7684\u306A\u767A\u8A00\u3084\u30C7\u30FC\u30BF\u3092\u5C11\u91CF\u5F15\u7528\u3067\u304D\u307E\u3059\u304C\u3001\u9577\u3044\u30C1\u30E3\u30C3\u30C8\u30ED\u30B0\u3092\u305D\u306E\u307E\u307E\u4E26\u3079\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
9548
+ - \u30E6\u30FC\u30B6\u30FC\u304C\u6C42\u3081\u306A\u3044\u9650\u308A\u3001\u8AAC\u6559\u3001\u983C\u307E\u308C\u3066\u3044\u306A\u3044\u4EBA\u751F\u76F8\u8AC7\u3001\u6BCE\u56DE\u306E\u30EC\u30DD\u30FC\u30C8\u5316\u306F\u907F\u3051\u3066\u304F\u3060\u3055\u3044\u3002`
9549
+ }
9550
+ ];
9551
+ var DEFAULT_GENERAL_ASSISTANT_RAW_CONFIGS = DEFAULT_GENERAL_ASSISTANT_CONFIGS.map((config) => ({
9552
+ id: config.id,
9553
+ content: serializeAssistant(config)
9554
+ }));
9555
+ var LEGACY_GENERAL_ASSISTANT_DIGESTS = {
9556
+ general_cn: ["42989d512b8eca58839e838639f17d04413bf67c0253f7b5998f46b89ad0d330"],
9557
+ general_en: ["3c6d223362dfc8bc863427768090c8794e0b1f8d1ec5f17068949ad728b3f9f6"],
9558
+ general_ja: ["729a52d6ab4bd23f5ed5f84913b24c82e862246abc0ee70caec2244297a91d63"]
9559
+ };
9560
+
9350
9561
  // ../../packages/node-runtime/src/ai/assistant-manager.ts
9351
9562
  function toSummary2(config) {
9352
9563
  return {
@@ -9363,18 +9574,22 @@ var AssistantManager = class {
9363
9574
  deps;
9364
9575
  generalIds;
9365
9576
  builtinCache = /* @__PURE__ */ new Map();
9577
+ builtinDigestCache = /* @__PURE__ */ new Map();
9366
9578
  cache = /* @__PURE__ */ new Map();
9367
9579
  initialized = false;
9368
9580
  constructor(deps) {
9369
9581
  this.deps = deps;
9370
- this.generalIds = deps.generalIds || ["general_cn", "general_en", "general_ja"];
9582
+ this.generalIds = [...deps.generalIds ?? GENERAL_ASSISTANT_IDS];
9371
9583
  this.initBuiltinCache();
9372
9584
  }
9373
9585
  initBuiltinCache() {
9374
9586
  if (!this.deps.builtinRawConfigs) return;
9375
9587
  for (const { id, content } of this.deps.builtinRawConfigs) {
9376
9588
  const config = parseAssistantFile(content, `${id}.md`);
9377
- if (config) this.builtinCache.set(config.id, config);
9589
+ if (config) {
9590
+ this.builtinCache.set(config.id, config);
9591
+ this.builtinDigestCache.set(config.id, this.getConfigDigest(config));
9592
+ }
9378
9593
  }
9379
9594
  }
9380
9595
  getBuiltinConfig(id) {
@@ -9385,38 +9600,120 @@ var AssistantManager = class {
9385
9600
  }
9386
9601
  // ==================== Init ====================
9387
9602
  init() {
9388
- const { fs: fs35, assistantsDir } = this.deps;
9389
- fs35.ensureDir(assistantsDir);
9390
- const generalCreated = this.ensureGeneralAssistants();
9603
+ const { fs: fs37, assistantsDir } = this.deps;
9604
+ fs37.ensureDir(assistantsDir);
9605
+ const { generalCreated, generalUpdated } = this.syncGeneralAssistants();
9391
9606
  this.loadAll();
9392
9607
  this.initialized = true;
9393
9608
  this.deps.logger?.info("AssistantManager", "Initialized", {
9394
9609
  total: this.cache.size,
9395
- generalCreated
9610
+ generalCreated,
9611
+ generalUpdated
9396
9612
  });
9397
- return { total: this.cache.size, generalCreated };
9613
+ return { total: this.cache.size, generalCreated, generalUpdated };
9398
9614
  }
9399
- ensureGeneralAssistants() {
9400
- const { fs: fs35, assistantsDir } = this.deps;
9401
- let anyCreated = false;
9615
+ syncGeneralAssistants() {
9616
+ const { fs: fs37, assistantsDir } = this.deps;
9617
+ let generalCreated = false;
9618
+ let generalUpdated = false;
9402
9619
  for (const id of this.generalIds) {
9403
9620
  const config = this.getBuiltinConfig(id);
9404
9621
  if (!config) continue;
9405
- const filePath = fs35.joinPath(assistantsDir, `${id}.md`);
9406
- if (fs35.fileExists(filePath)) continue;
9407
- fs35.writeFile(filePath, serializeAssistant({ ...config, builtinId: config.id }));
9408
- anyCreated = true;
9622
+ const filePath = fs37.joinPath(assistantsDir, `${id}.md`);
9623
+ if (!fs37.fileExists(filePath)) {
9624
+ fs37.writeFile(filePath, serializeAssistant(this.withBuiltinTracking(config)));
9625
+ generalCreated = true;
9626
+ continue;
9627
+ }
9628
+ try {
9629
+ const existing = parseAssistantFile(fs37.readFile(filePath), filePath);
9630
+ if (!existing) continue;
9631
+ if (existing.builtinId !== id) {
9632
+ try {
9633
+ const backupId = this.backupAssistantOccupyingReservedId(existing);
9634
+ fs37.writeFile(filePath, serializeAssistant(this.withBuiltinTracking(config)));
9635
+ generalCreated = true;
9636
+ this.deps.logger?.info("AssistantManager", "Backed up assistant occupying reserved default ID", {
9637
+ reservedId: id,
9638
+ backupId
9639
+ });
9640
+ } catch (error) {
9641
+ this.deps.logger?.error(
9642
+ "AssistantManager",
9643
+ `Failed to migrate assistant occupying reserved default ID: ${id}`,
9644
+ error
9645
+ );
9646
+ }
9647
+ continue;
9648
+ }
9649
+ if (!this.shouldUpgradeBuiltin(existing, config)) continue;
9650
+ fs37.writeFile(filePath, serializeAssistant(this.withBuiltinTracking(config, existing.id)));
9651
+ generalUpdated = true;
9652
+ this.deps.logger?.info("AssistantManager", "Updated unmodified default assistant template", {
9653
+ id,
9654
+ fromVersion: existing.builtinVersion,
9655
+ toVersion: config.builtinVersion
9656
+ });
9657
+ } catch (error) {
9658
+ this.deps.logger?.warn("AssistantManager", `Failed to inspect default assistant: ${id}`, {
9659
+ error: String(error)
9660
+ });
9661
+ }
9409
9662
  }
9410
- return anyCreated;
9663
+ return { generalCreated, generalUpdated };
9664
+ }
9665
+ backupAssistantOccupyingReservedId(config) {
9666
+ const { fs: fs37, assistantsDir } = this.deps;
9667
+ const baseId = this.deps.generateId?.() || `custom_${Date.now().toString(36)}`;
9668
+ let backupId = baseId;
9669
+ let suffix = 2;
9670
+ while (this.generalIds.includes(backupId) || fs37.fileExists(fs37.joinPath(assistantsDir, `${backupId}.md`))) {
9671
+ backupId = `${baseId}_${suffix++}`;
9672
+ }
9673
+ fs37.writeFile(fs37.joinPath(assistantsDir, `${backupId}.md`), serializeAssistant({ ...config, id: backupId }));
9674
+ return backupId;
9675
+ }
9676
+ getConfigDigest(config) {
9677
+ return this.deps.contentHash(
9678
+ JSON.stringify({
9679
+ name: config.name,
9680
+ systemPrompt: config.systemPrompt,
9681
+ presetQuestions: config.presetQuestions,
9682
+ allowedBuiltinTools: config.allowedBuiltinTools ?? [],
9683
+ applicableChatTypes: config.applicableChatTypes ?? [],
9684
+ supportedLocales: config.supportedLocales ?? []
9685
+ })
9686
+ );
9687
+ }
9688
+ withBuiltinTracking(config, id = config.id) {
9689
+ return {
9690
+ ...config,
9691
+ id,
9692
+ builtinId: config.id,
9693
+ builtinVersion: config.builtinVersion,
9694
+ builtinDigest: this.builtinDigestCache.get(config.id) ?? this.getConfigDigest(config)
9695
+ };
9696
+ }
9697
+ shouldUpgradeBuiltin(existing, builtin) {
9698
+ const comparison = this.compareBuiltin(existing, builtin);
9699
+ return comparison.isUnmodified && comparison.isOutdated;
9700
+ }
9701
+ compareBuiltin(existing, builtin) {
9702
+ const builtinDigest = this.builtinDigestCache.get(builtin.id) ?? this.getConfigDigest(builtin);
9703
+ const existingDigest = this.getConfigDigest(existing);
9704
+ const knownBaseDigests = existing.builtinDigest ? [existing.builtinDigest] : this.deps.legacyBuiltinDigests?.[builtin.id] ?? [];
9705
+ const isUnmodified = existingDigest === builtinDigest || knownBaseDigests.includes(existingDigest);
9706
+ const isOutdated = existing.builtinDigest !== builtinDigest || existing.builtinVersion !== builtin.builtinVersion;
9707
+ return { isUnmodified, isOutdated };
9411
9708
  }
9412
9709
  loadAll() {
9413
- const { fs: fs35, assistantsDir } = this.deps;
9710
+ const { fs: fs37, assistantsDir } = this.deps;
9414
9711
  this.cache.clear();
9415
- const files = fs35.listFiles(assistantsDir, ".md");
9712
+ const files = fs37.listFiles(assistantsDir, ".md");
9416
9713
  for (const file of files) {
9417
9714
  try {
9418
- const filePath = fs35.joinPath(assistantsDir, file);
9419
- const content = fs35.readFile(filePath);
9715
+ const filePath = fs37.joinPath(assistantsDir, file);
9716
+ const content = fs37.readFile(filePath);
9420
9717
  const config = parseAssistantFile(content, filePath);
9421
9718
  if (config) {
9422
9719
  this.cache.set(config.id, config);
@@ -9437,6 +9734,23 @@ var AssistantManager = class {
9437
9734
  this.ensureInitialized();
9438
9735
  return this.cache.get(id) ?? null;
9439
9736
  }
9737
+ getAssistantUpgradeInfo(id) {
9738
+ this.ensureInitialized();
9739
+ if (!this.generalIds.includes(id)) return null;
9740
+ const existing = this.cache.get(id);
9741
+ if (!existing?.builtinId) return null;
9742
+ const builtin = this.getBuiltinConfig(existing.builtinId);
9743
+ if (!builtin) return null;
9744
+ const comparison = this.compareBuiltin(existing, builtin);
9745
+ if (!comparison.isOutdated || comparison.isUnmodified) return null;
9746
+ return {
9747
+ assistantId: existing.id,
9748
+ builtinId: existing.builtinId,
9749
+ name: existing.name,
9750
+ currentVersion: existing.builtinVersion ?? null,
9751
+ latestVersion: builtin.builtinVersion ?? null
9752
+ };
9753
+ }
9440
9754
  hasAssistant(id) {
9441
9755
  this.ensureInitialized();
9442
9756
  return this.cache.has(id);
@@ -9455,7 +9769,7 @@ var AssistantManager = class {
9455
9769
  if (!builtinConfig) return { success: false, error: `Builtin assistant not found: ${builtinId}` };
9456
9770
  const existing = this.findByBuiltinId(builtinId);
9457
9771
  if (existing) return { success: false, error: `Assistant already imported: ${builtinId}` };
9458
- return this.saveToDisk({ ...builtinConfig, builtinId: builtinConfig.id });
9772
+ return this.saveToDisk(this.withBuiltinTracking(builtinConfig));
9459
9773
  }
9460
9774
  reimportAssistant(id) {
9461
9775
  this.ensureInitialized();
@@ -9464,7 +9778,7 @@ var AssistantManager = class {
9464
9778
  if (!existing.builtinId) return { success: false, error: "Only imported builtin assistants can be reimported" };
9465
9779
  const builtinConfig = this.getBuiltinConfig(existing.builtinId);
9466
9780
  if (!builtinConfig) return { success: false, error: `Builtin template not found: ${existing.builtinId}` };
9467
- return this.saveToDisk({ ...builtinConfig, id: existing.id, builtinId: existing.builtinId });
9781
+ return this.saveToDisk(this.withBuiltinTracking(builtinConfig, existing.id));
9468
9782
  }
9469
9783
  importAssistantFromMd(rawMd) {
9470
9784
  this.ensureInitialized();
@@ -9508,7 +9822,55 @@ var AssistantManager = class {
9508
9822
  if (!existing?.builtinId) return { success: false, error: "Only builtin assistants can be reset" };
9509
9823
  const builtinConfig = this.getBuiltinConfig(existing.builtinId);
9510
9824
  if (!builtinConfig) return { success: false, error: `Builtin config not found: ${existing.builtinId}` };
9511
- return this.saveToDisk({ ...builtinConfig, id: existing.id, builtinId: existing.builtinId });
9825
+ const result = this.saveToDisk(this.withBuiltinTracking(builtinConfig, existing.id));
9826
+ if (result.success) {
9827
+ this.deps.logger?.info("AssistantManager", "Reset builtin assistant to default template", {
9828
+ id: existing.id,
9829
+ builtinId: existing.builtinId
9830
+ });
9831
+ }
9832
+ return result;
9833
+ }
9834
+ upgradeAssistantWithBackup(id, backupName) {
9835
+ this.ensureInitialized();
9836
+ const upgradeInfo = this.getAssistantUpgradeInfo(id);
9837
+ if (!upgradeInfo) return { success: false, error: `No assistant upgrade available: ${id}` };
9838
+ const existing = this.cache.get(id);
9839
+ const builtin = this.getBuiltinConfig(upgradeInfo.builtinId);
9840
+ const normalizedBackupName = backupName.trim() || `${existing.name} (Legacy Backup)`;
9841
+ const backupConfig = {
9842
+ ...existing,
9843
+ id: this.deps.generateId?.() || `custom_${Date.now().toString(36)}`,
9844
+ name: normalizedBackupName,
9845
+ builtinId: void 0,
9846
+ builtinVersion: void 0,
9847
+ builtinDigest: void 0
9848
+ };
9849
+ const existingBackup = Array.from(this.cache.values()).find(
9850
+ (config) => !config.builtinId && this.getConfigDigest(config) === this.getConfigDigest(backupConfig)
9851
+ );
9852
+ const backupId = existingBackup?.id ?? backupConfig.id;
9853
+ if (!existingBackup) {
9854
+ const backupResult = this.saveToDisk(backupConfig);
9855
+ if (!backupResult.success) return backupResult;
9856
+ }
9857
+ const upgradeResult = this.saveToDisk(this.withBuiltinTracking(builtin, existing.id));
9858
+ if (!upgradeResult.success) {
9859
+ this.deps.logger?.warn("AssistantManager", "Default assistant upgrade failed after backup", {
9860
+ id: existing.id,
9861
+ builtinId: existing.builtinId,
9862
+ backupId
9863
+ });
9864
+ return { ...upgradeResult, backupId };
9865
+ }
9866
+ this.deps.logger?.info("AssistantManager", "Backed up and upgraded default assistant", {
9867
+ id: existing.id,
9868
+ builtinId: existing.builtinId,
9869
+ backupId,
9870
+ fromVersion: existing.builtinVersion,
9871
+ toVersion: builtin.builtinVersion
9872
+ });
9873
+ return { success: true, backupId };
9512
9874
  }
9513
9875
  // ==================== Internal ====================
9514
9876
  findByBuiltinId(builtinId) {
@@ -9528,12 +9890,12 @@ var AssistantManager = class {
9528
9890
  };
9529
9891
 
9530
9892
  // ../../packages/node-runtime/src/ai/skill-parser.ts
9531
- import * as path21 from "path";
9893
+ import * as path22 from "path";
9532
9894
  import matter2 from "gray-matter";
9533
9895
  function parseSkillFile(content, filePath) {
9534
9896
  try {
9535
9897
  const { data: fm, content: prompt } = matter2(content);
9536
- const id = fm.id ?? path21.basename(filePath, ".md");
9898
+ const id = fm.id ?? path22.basename(filePath, ".md");
9537
9899
  const name = fm.name;
9538
9900
  if (!name) return null;
9539
9901
  return {
@@ -9552,7 +9914,7 @@ function parseSkillFile(content, filePath) {
9552
9914
  function extractSkillId(content, filePath) {
9553
9915
  try {
9554
9916
  const { data: fm } = matter2(content);
9555
- return fm.id ?? path21.basename(filePath, ".md");
9917
+ return fm.id ?? path22.basename(filePath, ".md");
9556
9918
  } catch {
9557
9919
  return null;
9558
9920
  }
@@ -9571,9 +9933,9 @@ function validateChatScope(raw) {
9571
9933
 
9572
9934
  // ../../packages/node-runtime/src/ai/chats.ts
9573
9935
  import Database from "better-sqlite3";
9574
- import * as fs25 from "fs";
9575
- import * as path22 from "path";
9576
- var DEFAULT_GENERAL_ID = "general_cn";
9936
+ import * as fs26 from "fs";
9937
+ import * as path23 from "path";
9938
+ var DEFAULT_GENERAL_ID = DEFAULT_GENERAL_ASSISTANT_ID;
9577
9939
  var defaultLogger = {
9578
9940
  warn(_category, message, extra) {
9579
9941
  console.warn(`[AI Chats] ${message}`, extra ?? "");
@@ -9591,14 +9953,14 @@ var AIChatManager = class {
9591
9953
  this.nativeBinding = options2?.nativeBinding;
9592
9954
  }
9593
9955
  ensureDir(dir) {
9594
- if (!fs25.existsSync(dir)) {
9595
- fs25.mkdirSync(dir, { recursive: true });
9956
+ if (!fs26.existsSync(dir)) {
9957
+ fs26.mkdirSync(dir, { recursive: true });
9596
9958
  }
9597
9959
  }
9598
9960
  getDb() {
9599
9961
  if (this.db) return this.db;
9600
9962
  this.ensureDir(this.aiDataDir);
9601
- const dbPath = path22.join(this.aiDataDir, "conversations.db");
9963
+ const dbPath = path23.join(this.aiDataDir, "conversations.db");
9602
9964
  this.db = this.nativeBinding ? new Database(dbPath, { nativeBinding: this.nativeBinding }) : new Database(dbPath);
9603
9965
  this.db.pragma("journal_mode = WAL");
9604
9966
  this.db.exec(`
@@ -9841,16 +10203,16 @@ var AIChatManager = class {
9841
10203
  if (allRows.length === 0) return [];
9842
10204
  const rowMap = new Map(allRows.map((row) => [row.id, row]));
9843
10205
  let currentId = leafMessageId ?? this.getActiveMessageId(aiChatId);
9844
- const path31 = [];
10206
+ const path33 = [];
9845
10207
  const seen = /* @__PURE__ */ new Set();
9846
10208
  while (currentId && !seen.has(currentId)) {
9847
10209
  seen.add(currentId);
9848
10210
  const row = rowMap.get(currentId);
9849
10211
  if (!row) break;
9850
- path31.push(row);
10212
+ path33.push(row);
9851
10213
  currentId = row.parentId;
9852
10214
  }
9853
- return path31.length > 0 ? path31.reverse() : allRows;
10215
+ return path33.length > 0 ? path33.reverse() : allRows;
9854
10216
  }
9855
10217
  // ==================== 生命周期 ====================
9856
10218
  close() {
@@ -10420,21 +10782,21 @@ var SkillManagerCore = class {
10420
10782
  }
10421
10783
  // ==================== Init ====================
10422
10784
  init() {
10423
- const { fs: fs35, skillsDir } = this.deps;
10424
- fs35.ensureDir(skillsDir);
10785
+ const { fs: fs37, skillsDir } = this.deps;
10786
+ fs37.ensureDir(skillsDir);
10425
10787
  this.loadAll();
10426
10788
  this.initialized = true;
10427
10789
  this.deps.logger?.info("SkillManager", "Initialized", { total: this.cache.size });
10428
10790
  return { total: this.cache.size };
10429
10791
  }
10430
10792
  loadAll() {
10431
- const { fs: fs35, skillsDir } = this.deps;
10793
+ const { fs: fs37, skillsDir } = this.deps;
10432
10794
  this.cache.clear();
10433
- const files = fs35.listFiles(skillsDir, ".md");
10795
+ const files = fs37.listFiles(skillsDir, ".md");
10434
10796
  for (const file of files) {
10435
10797
  try {
10436
- const filePath = fs35.joinPath(skillsDir, file);
10437
- const content = fs35.readFile(filePath);
10798
+ const filePath = fs37.joinPath(skillsDir, file);
10799
+ const content = fs37.readFile(filePath);
10438
10800
  const def = parseSkillFile(content, filePath);
10439
10801
  if (def) {
10440
10802
  this.cache.set(def.id, def);
@@ -10586,8 +10948,8 @@ var SkillManagerCore = class {
10586
10948
  };
10587
10949
 
10588
10950
  // ../../packages/node-runtime/src/ai/skill-manager.ts
10589
- import * as fs26 from "fs";
10590
- import * as path23 from "path";
10951
+ import * as fs27 from "fs";
10952
+ import * as path24 from "path";
10591
10953
  var SKILLS_DIR_NAME = "skills";
10592
10954
  var defaultLogger2 = {
10593
10955
  info: () => {
@@ -10597,26 +10959,26 @@ var defaultLogger2 = {
10597
10959
  };
10598
10960
  var nodeFs = {
10599
10961
  ensureDir(dir) {
10600
- fs26.mkdirSync(dir, { recursive: true });
10962
+ fs27.mkdirSync(dir, { recursive: true });
10601
10963
  },
10602
10964
  listFiles(dir, ext) {
10603
- if (!fs26.existsSync(dir)) return [];
10604
- return fs26.readdirSync(dir).filter((file) => file.endsWith(ext));
10965
+ if (!fs27.existsSync(dir)) return [];
10966
+ return fs27.readdirSync(dir).filter((file) => file.endsWith(ext));
10605
10967
  },
10606
10968
  readFile(filePath) {
10607
- return fs26.readFileSync(filePath, "utf-8");
10969
+ return fs27.readFileSync(filePath, "utf-8");
10608
10970
  },
10609
10971
  writeFile(filePath, content) {
10610
- fs26.writeFileSync(filePath, content, "utf-8");
10972
+ fs27.writeFileSync(filePath, content, "utf-8");
10611
10973
  },
10612
10974
  deleteFile(filePath) {
10613
- fs26.unlinkSync(filePath);
10975
+ fs27.unlinkSync(filePath);
10614
10976
  },
10615
10977
  fileExists(filePath) {
10616
- return fs26.existsSync(filePath);
10978
+ return fs27.existsSync(filePath);
10617
10979
  },
10618
10980
  joinPath(...parts) {
10619
- return path23.join(...parts);
10981
+ return path24.join(...parts);
10620
10982
  }
10621
10983
  };
10622
10984
  var SkillManager = class {
@@ -10626,7 +10988,7 @@ var SkillManager = class {
10626
10988
  this.logger = logger ?? defaultLogger2;
10627
10989
  this.core = new SkillManagerCore({
10628
10990
  fs: nodeFs,
10629
- skillsDir: path23.join(aiDataDir, SKILLS_DIR_NAME),
10991
+ skillsDir: path24.join(aiDataDir, SKILLS_DIR_NAME),
10630
10992
  builtinRawSkills: [],
10631
10993
  logger: {
10632
10994
  info: () => {
@@ -13352,26 +13714,34 @@ var zh_CN_default = {
13352
13714
  - \u53EA\u6709\u5DE5\u5177\u8FD4\u56DE\u7684\u6D88\u606F\u3001\u7EDF\u8BA1\u6216\u6570\u636E\u5E93\u6982\u89C8\u53EF\u4EE5\u4F5C\u4E3A\u4E8B\u5B9E\u4F9D\u636E\uFF1B\u5DE5\u5177\u6CA1\u6709\u8FD4\u56DE\u8DB3\u591F\u8BC1\u636E\u65F6\uFF0C\u660E\u786E\u8BF4\u660E\u6570\u636E\u4E0D\u8DB3\uFF0C\u4E0D\u8981\u7F16\u9020\u4E0D\u5B58\u5728\u7684\u804A\u5929\u8BB0\u5F55\u3002`,
13353
13715
  currentTask: "\u5F53\u524D\u4EFB\u52A1",
13354
13716
  skillPriorityNote: "\u6CE8\u610F\uFF1A\u5728\u6267\u884C\u6B64\u4EFB\u52A1\u65F6\uFF0C\u8BF7\u4F18\u5148\u9075\u5FAA\u4EE5\u4E0B\u4EFB\u52A1\u7684\u8F93\u51FA\u683C\u5F0F\u8981\u6C42\uFF0C\u8FD9\u53EF\u4EE5\u8986\u76D6\u4F60\u7684\u5E38\u89C4\u56DE\u590D\u4E60\u60EF\u3002",
13355
- responseInstruction: "\u6839\u636E\u7528\u6237\u7684\u95EE\u9898\uFF0C\u9009\u62E9\u5408\u9002\u7684\u5DE5\u5177\u83B7\u53D6\u6570\u636E\uFF0C\u7136\u540E\u57FA\u4E8E\u6570\u636E\u7ED9\u51FA\u56DE\u7B54\u3002",
13717
+ responseInstruction: "\u6839\u636E\u7528\u6237\u7684\u95EE\u9898\uFF0C\u5728\u9700\u8981\u65F6\u9009\u62E9\u5408\u9002\u7684\u5DE5\u5177\u83B7\u53D6\u6570\u636E\uFF0C\u7136\u540E\u81EA\u7136\u3001\u76F4\u63A5\u5730\u7ED9\u51FA\u56DE\u7B54\u3002",
13356
13718
  fallbackRoleDefinition: {
13357
- group: `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u4F46\u98CE\u683C\u8F7B\u677E\u7684\u7FA4\u804A\u8BB0\u5F55\u5206\u6790\u52A9\u624B\u3002
13358
- \u4F60\u7684\u4EFB\u52A1\u662F\u5E2E\u52A9\u7528\u6237\u7406\u89E3\u548C\u5206\u6790\u4ED6\u4EEC\u7684\u7FA4\u804A\u8BB0\u5F55\u6570\u636E\uFF0C\u540C\u65F6\u53EF\u4EE5\u9002\u5EA6\u4F7F\u7528 B \u7AD9/\u7F51\u7EDC\u70ED\u6897\u548C\u8868\u60C5/\u989C\u6587\u5B57\u6D3B\u8DC3\u6C14\u6C1B\uFF0C\u4F46\u4E0D\u5F71\u54CD\u7ED3\u8BBA\u7684\u51C6\u786E\u6027\u3002
13359
-
13360
- ## \u56DE\u7B54\u8981\u6C42
13361
- 1. \u57FA\u4E8E\u5DE5\u5177\u8FD4\u56DE\u7684\u6570\u636E\u56DE\u7B54\uFF0C\u4E0D\u8981\u7F16\u9020\u4FE1\u606F
13362
- 2. \u5982\u679C\u6570\u636E\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u95EE\u9898\uFF0C\u8BF7\u8BF4\u660E
13363
- 3. \u56DE\u7B54\u8981\u7B80\u6D01\u660E\u4E86\uFF0C\u4F7F\u7528 Markdown \u683C\u5F0F
13364
- 4. \u53EF\u4EE5\u9002\u5EA6\u52A0\u5165 B \u7AD9/\u7F51\u7EDC\u70ED\u6897\u3001\u8868\u60C5/\u989C\u6587\u5B57\uFF08\u5F3A\u5EA6\u9002\u4E2D\uFF09
13365
- 5. \u73A9\u6897\u4E0D\u5F97\u5F71\u54CD\u4E8B\u5B9E\u51C6\u786E\u4E0E\u7ED3\u8BBA\u6E05\u6670\uFF0C\u907F\u514D\u4F4E\u4FD7\u6216\u5192\u72AF\u6027\u8868\u8FBE`,
13366
- private: `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u4F46\u98CE\u683C\u8F7B\u677E\u7684\u79C1\u804A\u8BB0\u5F55\u5206\u6790\u52A9\u624B\u3002
13367
- \u4F60\u7684\u4EFB\u52A1\u662F\u5E2E\u52A9\u7528\u6237\u7406\u89E3\u548C\u5206\u6790\u4ED6\u4EEC\u7684\u79C1\u804A\u8BB0\u5F55\u6570\u636E\uFF0C\u540C\u65F6\u53EF\u4EE5\u9002\u5EA6\u4F7F\u7528 B \u7AD9/\u7F51\u7EDC\u70ED\u6897\u548C\u8868\u60C5/\u989C\u6587\u5B57\u6D3B\u8DC3\u6C14\u6C1B\uFF0C\u4F46\u4E0D\u5F71\u54CD\u7ED3\u8BBA\u7684\u51C6\u786E\u6027\u3002
13368
-
13369
- ## \u56DE\u7B54\u8981\u6C42
13370
- 1. \u57FA\u4E8E\u5DE5\u5177\u8FD4\u56DE\u7684\u6570\u636E\u56DE\u7B54\uFF0C\u4E0D\u8981\u7F16\u9020\u4FE1\u606F
13371
- 2. \u5982\u679C\u6570\u636E\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u95EE\u9898\uFF0C\u8BF7\u8BF4\u660E
13372
- 3. \u56DE\u7B54\u8981\u7B80\u6D01\u660E\u4E86\uFF0C\u4F7F\u7528 Markdown \u683C\u5F0F
13373
- 4. \u53EF\u4EE5\u9002\u5EA6\u52A0\u5165 B \u7AD9/\u7F51\u7EDC\u70ED\u6897\u3001\u8868\u60C5/\u989C\u6587\u5B57\uFF08\u5F3A\u5EA6\u9002\u4E2D\uFF09
13374
- 5. \u73A9\u6897\u4E0D\u5F97\u5F71\u54CD\u4E8B\u5B9E\u51C6\u786E\u4E0E\u7ED3\u8BBA\u6E05\u6670\uFF0C\u907F\u514D\u4F4E\u4FD7\u6216\u5192\u72AF\u6027\u8868\u8FBE`
13719
+ group: `\u4F60\u662F ChatLab \u91CC\u7684\u7FA4\u804A\u8BB0\u5F55\u5206\u6790\u642D\u6863\uFF0C\u5E2E\u52A9\u7528\u6237\u4ECE\u804A\u5929\u8BB0\u5F55\u4E2D\u7406\u89E3\u4E8B\u5B9E\u3001\u53D8\u5316\u548C\u4E92\u52A8\u6A21\u5F0F\uFF0C\u800C\u4E0D\u662F\u673A\u68B0\u5730\u751F\u6210\u5206\u6790\u62A5\u544A\u3002
13720
+
13721
+ ## \u4EA4\u6D41\u65B9\u5F0F
13722
+ - \u8DDF\u968F\u7528\u6237\u7684\u8BED\u8A00\u548C\u4EA4\u6D41\u65B9\u5F0F\uFF0C\u8BF4\u81EA\u7136\u3001\u76F4\u63A5\u7684\u4EBA\u8BDD\uFF0C\u907F\u514D\u5BA2\u670D\u8154\u548C\u8FC7\u5EA6\u6B63\u5F0F\u7684\u8868\u8FBE\u3002
13723
+ - \u7B80\u5355\u95EE\u9898\u76F4\u63A5\u56DE\u7B54\uFF1B\u590D\u6742\u95EE\u9898\u518D\u5206\u5C42\u8BF4\u660E\u3002\u6807\u9898\u3001\u5217\u8868\u548C\u8868\u683C\u53EA\u5728\u6709\u52A9\u4E8E\u7406\u89E3\u65F6\u4F7F\u7528\u3002
13724
+ - \u5728\u8BC1\u636E\u5141\u8BB8\u65F6\u7ED9\u51FA\u660E\u786E\u5224\u65AD\uFF1B\u65E0\u6CD5\u786E\u8BA4\u7684\u90E8\u5206\u8981\u5766\u7387\u8BF4\u660E\u3002
13725
+ - \u53EF\u4EE5\u6709\u4E00\u70B9\u81EA\u7136\u7684\u5E7D\u9ED8\u611F\uFF0C\u4F46\u4E0D\u8981\u5F3A\u884C\u73A9\u6897\u3001\u5806\u8868\u60C5\u6216\u727A\u7272\u51C6\u786E\u6027\u3002
13726
+
13727
+ ## \u5206\u6790\u8FB9\u754C
13728
+ - \u533A\u5206\u80FD\u591F\u786E\u8BA4\u7684\u4E8B\u5B9E\u3001\u57FA\u4E8E\u8BC1\u636E\u7684\u63A8\u65AD\uFF0C\u4EE5\u53CA\u6682\u65F6\u65E0\u6CD5\u5224\u65AD\u7684\u90E8\u5206\u3002
13729
+ - \u6D89\u53CA\u6027\u683C\u3001\u60C5\u7EEA\u3001\u5173\u7CFB\u548C\u52A8\u673A\u65F6\u5C24\u5176\u8C28\u614E\uFF0C\u4E0D\u7F16\u9020\u5FC3\u7406\u6D3B\u52A8\uFF0C\u4E5F\u4E0D\u8F7B\u6613\u7ED9\u4EBA\u8D34\u6807\u7B7E\u3002
13730
+ - \u9002\u91CF\u5F15\u7528\u6709\u4EE3\u8868\u6027\u7684\u539F\u8BDD\u548C\u6570\u636E\uFF0C\u4E0D\u8981\u5927\u6BB5\u5806\u780C\u804A\u5929\u8BB0\u5F55\u3002
13731
+ - \u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\uFF0C\u4E0D\u8BF4\u6559\u3001\u4E0D\u64C5\u81EA\u7ED9\u4EBA\u751F\u5EFA\u8BAE\uFF0C\u4E5F\u4E0D\u628A\u6BCF\u6B21\u56DE\u7B54\u90FD\u5199\u6210\u603B\u7ED3\u62A5\u544A\u3002`,
13732
+ private: `\u4F60\u662F ChatLab \u91CC\u7684\u79C1\u804A\u8BB0\u5F55\u5206\u6790\u642D\u6863\uFF0C\u5E2E\u52A9\u7528\u6237\u4ECE\u804A\u5929\u8BB0\u5F55\u4E2D\u7406\u89E3\u4E8B\u5B9E\u3001\u53D8\u5316\u548C\u4E92\u52A8\u65B9\u5F0F\uFF0C\u800C\u4E0D\u662F\u673A\u68B0\u5730\u751F\u6210\u5206\u6790\u62A5\u544A\u3002
13733
+
13734
+ ## \u4EA4\u6D41\u65B9\u5F0F
13735
+ - \u8DDF\u968F\u7528\u6237\u7684\u8BED\u8A00\u548C\u4EA4\u6D41\u65B9\u5F0F\uFF0C\u8BF4\u81EA\u7136\u3001\u76F4\u63A5\u7684\u4EBA\u8BDD\uFF0C\u907F\u514D\u5BA2\u670D\u8154\u548C\u8FC7\u5EA6\u6B63\u5F0F\u7684\u8868\u8FBE\u3002
13736
+ - \u7B80\u5355\u95EE\u9898\u76F4\u63A5\u56DE\u7B54\uFF1B\u590D\u6742\u95EE\u9898\u518D\u5206\u5C42\u8BF4\u660E\u3002\u6807\u9898\u3001\u5217\u8868\u548C\u8868\u683C\u53EA\u5728\u6709\u52A9\u4E8E\u7406\u89E3\u65F6\u4F7F\u7528\u3002
13737
+ - \u5728\u8BC1\u636E\u5141\u8BB8\u65F6\u7ED9\u51FA\u660E\u786E\u5224\u65AD\uFF1B\u65E0\u6CD5\u786E\u8BA4\u7684\u90E8\u5206\u8981\u5766\u7387\u8BF4\u660E\u3002
13738
+ - \u53EF\u4EE5\u6709\u4E00\u70B9\u81EA\u7136\u7684\u5E7D\u9ED8\u611F\uFF0C\u4F46\u4E0D\u8981\u5F3A\u884C\u73A9\u6897\u3001\u5806\u8868\u60C5\u6216\u727A\u7272\u51C6\u786E\u6027\u3002
13739
+
13740
+ ## \u5206\u6790\u8FB9\u754C
13741
+ - \u533A\u5206\u80FD\u591F\u786E\u8BA4\u7684\u4E8B\u5B9E\u3001\u57FA\u4E8E\u8BC1\u636E\u7684\u63A8\u65AD\uFF0C\u4EE5\u53CA\u6682\u65F6\u65E0\u6CD5\u5224\u65AD\u7684\u90E8\u5206\u3002
13742
+ - \u6D89\u53CA\u6027\u683C\u3001\u60C5\u7EEA\u3001\u5173\u7CFB\u548C\u52A8\u673A\u65F6\u5C24\u5176\u8C28\u614E\uFF0C\u4E0D\u7F16\u9020\u5FC3\u7406\u6D3B\u52A8\uFF0C\u4E5F\u4E0D\u8F7B\u6613\u7ED9\u4EBA\u8D34\u6807\u7B7E\u3002
13743
+ - \u9002\u91CF\u5F15\u7528\u6709\u4EE3\u8868\u6027\u7684\u539F\u8BDD\u548C\u6570\u636E\uFF0C\u4E0D\u8981\u5927\u6BB5\u5806\u780C\u804A\u5929\u8BB0\u5F55\u3002
13744
+ - \u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\uFF0C\u4E0D\u8BF4\u6559\u3001\u4E0D\u64C5\u81EA\u7ED9\u4EBA\u751F\u5EFA\u8BAE\uFF0C\u4E5F\u4E0D\u628A\u6BCF\u6B21\u56DE\u7B54\u90FD\u5199\u6210\u603B\u7ED3\u62A5\u544A\u3002`
13375
13745
  }
13376
13746
  }
13377
13747
  },
@@ -13707,22 +14077,34 @@ Usage rules:
13707
14077
  - Only messages, statistics, or database overviews returned by tools may be used as factual basis. If tools do not return enough evidence, say the data is insufficient and do not fabricate nonexistent chat records.`,
13708
14078
  currentTask: "Current Task",
13709
14079
  skillPriorityNote: "Note: When executing this task, prioritize the output format requirements below. This can override your usual response style.",
13710
- responseInstruction: "Based on the user's question, select appropriate tools to retrieve data, then provide an answer based on the data.",
14080
+ responseInstruction: "Based on the user's question, use appropriate tools when needed, then answer naturally and directly.",
13711
14081
  fallbackRoleDefinition: {
13712
- group: `You are a professional group chat analysis assistant.
13713
- Your task is to help users understand and analyze their group chat data.
14082
+ group: `You are ChatLab's group chat analysis partner. Help users understand facts, changes, and interaction patterns in their chat records instead of mechanically producing analysis reports.
13714
14083
 
13715
- ## Response Requirements
13716
- 1. Answer based on data returned by tools, do not fabricate information
13717
- 2. If data is insufficient to answer, please state so
13718
- 3. Keep answers concise and clear, use Markdown format`,
13719
- private: `You are a professional private chat analysis assistant.
13720
- Your task is to help users understand and analyze their private chat data.
14084
+ ## How to Communicate
14085
+ - Match the user's language and conversational style. Sound natural and direct, not like customer support or a formal report.
14086
+ - Answer simple questions directly. Add structure only for complex questions, and use headings, lists, or tables only when they improve understanding.
14087
+ - Give a clear judgment when the evidence supports one, and be candid about anything that cannot be established.
14088
+ - Light, natural humor is welcome, but never force jokes, emojis, or entertainment at the expense of accuracy.
13721
14089
 
13722
- ## Response Requirements
13723
- 1. Answer based on data returned by tools, do not fabricate information
13724
- 2. If data is insufficient to answer, please state so
13725
- 3. Keep answers concise and clear, use Markdown format`
14090
+ ## Analysis Boundaries
14091
+ - Distinguish established facts, evidence-based inferences, and what remains unknown.
14092
+ - Be especially careful with personality, emotion, relationships, and motives. Do not invent inner states or casually label people.
14093
+ - Use a small number of representative quotes or data points, but do not dump large blocks of chat logs.
14094
+ - Unless the user asks, do not moralize, give unsolicited life advice, or turn every response into a summary report.`,
14095
+ private: `You are ChatLab's private chat analysis partner. Help users understand facts, changes, and interaction patterns in their chat records instead of mechanically producing analysis reports.
14096
+
14097
+ ## How to Communicate
14098
+ - Match the user's language and conversational style. Sound natural and direct, not like customer support or a formal report.
14099
+ - Answer simple questions directly. Add structure only for complex questions, and use headings, lists, or tables only when they improve understanding.
14100
+ - Give a clear judgment when the evidence supports one, and be candid about anything that cannot be established.
14101
+ - Light, natural humor is welcome, but never force jokes, emojis, or entertainment at the expense of accuracy.
14102
+
14103
+ ## Analysis Boundaries
14104
+ - Distinguish established facts, evidence-based inferences, and what remains unknown.
14105
+ - Be especially careful with personality, emotion, relationships, and motives. Do not invent inner states or casually label people.
14106
+ - Use a small number of representative quotes or data points, but do not dump large blocks of chat logs.
14107
+ - Unless the user asks, do not moralize, give unsolicited life advice, or turn every response into a summary report.`
13726
14108
  }
13727
14109
  }
13728
14110
  },
@@ -14054,26 +14436,34 @@ var ja_JP_default = {
14054
14436
  - \u30E6\u30FC\u30B6\u30FC\u304C\u30C1\u30E3\u30C3\u30C8\u5185\u5BB9\u3001\u6700\u8FD1\u306E\u8A71\u984C\u3001\u8AB0\u304B\u306E\u767A\u8A00\u3001\u30E9\u30F3\u30AD\u30F3\u30B0/\u7D71\u8A08\u3001\u3042\u308B\u8A71\u984C\u304C\u51FA\u305F\u304B\u3069\u3046\u304B\u3001\u307E\u305F\u306F\u539F\u6587\u5F15\u7528\u3092\u6C42\u3081\u305F\u5834\u5408\u306F\u3001\u5FC5\u305A\u5148\u306B\u9069\u5207\u306A\u30C7\u30FC\u30BF\u30C4\u30FC\u30EB\u3067\u73FE\u5728\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u691C\u7D22\u3059\u308B\u3002
14055
14437
  - \u65B0\u3057\u3044\u30C1\u30E3\u30C3\u30C8\u8A18\u9332\u304C\u8FFD\u52A0\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u73FE\u5728\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u53E4\u3044\u30A6\u30A3\u30F3\u30C9\u30A6\u5C65\u6B74\u3068\u7570\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308B\u3002\u6700\u65B0\u306E\u8A3C\u62E0\u53D6\u5F97\u306B\u306F get_chat_overview \u307E\u305F\u306F get_recent_messages/search_messages \u3092\u512A\u5148\u3059\u308B\u3002
14056
14438
  - \u4E8B\u5B9F\u6839\u62E0\u3068\u3057\u3066\u4F7F\u3048\u308B\u306E\u306F\u3001\u30C4\u30FC\u30EB\u304C\u8FD4\u3057\u305F\u30E1\u30C3\u30BB\u30FC\u30B8\u3001\u7D71\u8A08\u3001\u307E\u305F\u306F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u6982\u8981\u306E\u307F\u3002\u30C4\u30FC\u30EB\u304C\u5341\u5206\u306A\u8A3C\u62E0\u3092\u8FD4\u3055\u306A\u3044\u5834\u5408\u306F\u3001\u30C7\u30FC\u30BF\u4E0D\u8DB3\u3068\u660E\u793A\u3057\u3001\u5B58\u5728\u3057\u306A\u3044\u30C1\u30E3\u30C3\u30C8\u8A18\u9332\u3092\u4F5C\u3089\u306A\u3044\u3002`,
14057
- responseInstruction: "\u30E6\u30FC\u30B6\u30FC\u306E\u8CEA\u554F\u306B\u5FDC\u3058\u3066\u9069\u5207\u306A\u30C4\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u3001\u30C7\u30FC\u30BF\u306B\u57FA\u3065\u3044\u3066\u56DE\u7B54\u3059\u308B\u3002",
14439
+ responseInstruction: "\u30E6\u30FC\u30B6\u30FC\u306E\u8CEA\u554F\u306B\u5FDC\u3058\u3066\u5FC5\u8981\u306A\u5834\u5408\u306F\u9069\u5207\u306A\u30C4\u30FC\u30EB\u3067\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u3001\u81EA\u7136\u304B\u3064\u7387\u76F4\u306B\u56DE\u7B54\u3059\u308B\u3002",
14058
14440
  fallbackRoleDefinition: {
14059
- group: `\u3042\u306A\u305F\u306F\u30D7\u30ED\u30D5\u30A7\u30C3\u30B7\u30E7\u30CA\u30EB\u3060\u304C\u30AB\u30B8\u30E5\u30A2\u30EB\u306A\u30B9\u30BF\u30A4\u30EB\u306E\u30B0\u30EB\u30FC\u30D7\u30C1\u30E3\u30C3\u30C8\u5C65\u6B74\u5206\u6790\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3067\u3059\u3002
14060
- \u30E6\u30FC\u30B6\u30FC\u306E\u30B0\u30EB\u30FC\u30D7\u30C1\u30E3\u30C3\u30C8\u5C65\u6B74\u30C7\u30FC\u30BF\u306E\u7406\u89E3\u3068\u5206\u6790\u3092\u652F\u63F4\u3057\u3001\u9069\u5EA6\u306B\u30CD\u30C3\u30C8\u30B9\u30E9\u30F3\u30B0\u3084\u9854\u6587\u5B57\u3092\u4F7F\u3063\u3066\u96F0\u56F2\u6C17\u3092\u548C\u3089\u3052\u307E\u3059\u304C\u3001\u7D50\u8AD6\u306E\u6B63\u78BA\u6027\u306B\u5F71\u97FF\u3057\u306A\u3044\u3088\u3046\u306B\u3057\u307E\u3059\u3002
14061
-
14062
- ## \u56DE\u7B54\u8981\u4EF6
14063
- 1. \u30C4\u30FC\u30EB\u304B\u3089\u8FD4\u5374\u3055\u308C\u305F\u30C7\u30FC\u30BF\u306B\u57FA\u3065\u3044\u3066\u56DE\u7B54\u3057\u3001\u60C5\u5831\u3092\u634F\u9020\u3057\u306A\u3044
14064
- 2. \u30C7\u30FC\u30BF\u304C\u4E0D\u5341\u5206\u3067\u8CEA\u554F\u306B\u7B54\u3048\u3089\u308C\u306A\u3044\u5834\u5408\u306F\u3001\u305D\u306E\u65E8\u3092\u8AAC\u660E\u3059\u308B
14065
- 3. \u56DE\u7B54\u306F\u7C21\u6F54\u660E\u77AD\u306B\u3001Markdown \u5F62\u5F0F\u3092\u4F7F\u7528\u3059\u308B
14066
- 4. \u9069\u5EA6\u306B\u30CD\u30C3\u30C8\u30B9\u30E9\u30F3\u30B0\u3084\u9854\u6587\u5B57\u3092\u52A0\u3048\u3066\u3088\u3044\uFF08\u5F37\u5EA6\u306F\u63A7\u3048\u3081\u306B\uFF09
14067
- 5. \u30CD\u30BF\u306F\u4E8B\u5B9F\u306E\u6B63\u78BA\u3055\u3068\u7D50\u8AD6\u306E\u660E\u78BA\u3055\u306B\u5F71\u97FF\u3092\u4E0E\u3048\u3066\u306F\u306A\u3089\u305A\u3001\u4F4E\u4FD7\u307E\u305F\u306F\u4E0D\u5FEB\u306A\u8868\u73FE\u306F\u907F\u3051\u308B`,
14068
- private: `\u3042\u306A\u305F\u306F\u30D7\u30ED\u30D5\u30A7\u30C3\u30B7\u30E7\u30CA\u30EB\u3060\u304C\u30AB\u30B8\u30E5\u30A2\u30EB\u306A\u30B9\u30BF\u30A4\u30EB\u306E\u500B\u4EBA\u30C1\u30E3\u30C3\u30C8\u5C65\u6B74\u5206\u6790\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3067\u3059\u3002
14069
- \u30E6\u30FC\u30B6\u30FC\u306E\u500B\u4EBA\u30C1\u30E3\u30C3\u30C8\u5C65\u6B74\u30C7\u30FC\u30BF\u306E\u7406\u89E3\u3068\u5206\u6790\u3092\u652F\u63F4\u3057\u3001\u9069\u5EA6\u306B\u30CD\u30C3\u30C8\u30B9\u30E9\u30F3\u30B0\u3084\u9854\u6587\u5B57\u3092\u4F7F\u3063\u3066\u96F0\u56F2\u6C17\u3092\u548C\u3089\u3052\u307E\u3059\u304C\u3001\u7D50\u8AD6\u306E\u6B63\u78BA\u6027\u306B\u5F71\u97FF\u3057\u306A\u3044\u3088\u3046\u306B\u3057\u307E\u3059\u3002
14070
-
14071
- ## \u56DE\u7B54\u8981\u4EF6
14072
- 1. \u30C4\u30FC\u30EB\u304B\u3089\u8FD4\u5374\u3055\u308C\u305F\u30C7\u30FC\u30BF\u306B\u57FA\u3065\u3044\u3066\u56DE\u7B54\u3057\u3001\u60C5\u5831\u3092\u634F\u9020\u3057\u306A\u3044
14073
- 2. \u30C7\u30FC\u30BF\u304C\u4E0D\u5341\u5206\u3067\u8CEA\u554F\u306B\u7B54\u3048\u3089\u308C\u306A\u3044\u5834\u5408\u306F\u3001\u305D\u306E\u65E8\u3092\u8AAC\u660E\u3059\u308B
14074
- 3. \u56DE\u7B54\u306F\u7C21\u6F54\u660E\u77AD\u306B\u3001Markdown \u5F62\u5F0F\u3092\u4F7F\u7528\u3059\u308B
14075
- 4. \u9069\u5EA6\u306B\u30CD\u30C3\u30C8\u30B9\u30E9\u30F3\u30B0\u3084\u9854\u6587\u5B57\u3092\u52A0\u3048\u3066\u3088\u3044\uFF08\u5F37\u5EA6\u306F\u63A7\u3048\u3081\u306B\uFF09
14076
- 5. \u30CD\u30BF\u306F\u4E8B\u5B9F\u306E\u6B63\u78BA\u3055\u3068\u7D50\u8AD6\u306E\u660E\u78BA\u3055\u306B\u5F71\u97FF\u3092\u4E0E\u3048\u3066\u306F\u306A\u3089\u305A\u3001\u4F4E\u4FD7\u307E\u305F\u306F\u4E0D\u5FEB\u306A\u8868\u73FE\u306F\u907F\u3051\u308B`
14441
+ group: `\u3042\u306A\u305F\u306F ChatLab \u306E\u30B0\u30EB\u30FC\u30D7\u30C1\u30E3\u30C3\u30C8\u5206\u6790\u30D1\u30FC\u30C8\u30CA\u30FC\u3067\u3059\u3002\u6A5F\u68B0\u7684\u306A\u5206\u6790\u30EC\u30DD\u30FC\u30C8\u3067\u306F\u306A\u304F\u3001\u8A18\u9332\u306B\u3042\u308B\u4E8B\u5B9F\u3001\u5909\u5316\u3001\u3084\u308A\u53D6\u308A\u306E\u50BE\u5411\u3092\u30E6\u30FC\u30B6\u30FC\u304C\u7406\u89E3\u3067\u304D\u308B\u3088\u3046\u652F\u63F4\u3057\u307E\u3059\u3002
14442
+
14443
+ ## \u30B3\u30DF\u30E5\u30CB\u30B1\u30FC\u30B7\u30E7\u30F3
14444
+ - \u30E6\u30FC\u30B6\u30FC\u306E\u8A00\u8A9E\u3068\u8A71\u3057\u65B9\u306B\u5408\u308F\u305B\u3001\u30AB\u30B9\u30BF\u30DE\u30FC\u30B5\u30DD\u30FC\u30C8\u3084\u5805\u3044\u5831\u544A\u66F8\u306E\u3088\u3046\u3067\u306F\u306A\u304F\u3001\u81EA\u7136\u3067\u7387\u76F4\u306A\u8A00\u8449\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002
14445
+ - \u7C21\u5358\u306A\u8CEA\u554F\u306B\u306F\u7AEF\u7684\u306B\u7B54\u3048\u3001\u8907\u96D1\u306A\u8CEA\u554F\u3060\u3051\u3092\u6574\u7406\u3057\u3066\u8AAC\u660E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u898B\u51FA\u3057\u3001\u7B87\u6761\u66F8\u304D\u3001\u8868\u306F\u7406\u89E3\u3092\u52A9\u3051\u308B\u5834\u5408\u306B\u3060\u3051\u4F7F\u3044\u307E\u3059\u3002
14446
+ - \u6839\u62E0\u304C\u5341\u5206\u306A\u3089\u660E\u78BA\u306A\u5224\u65AD\u3092\u793A\u3057\u3001\u78BA\u8A8D\u3067\u304D\u306A\u3044\u3053\u3068\u306F\u7387\u76F4\u306B\u4F1D\u3048\u3066\u304F\u3060\u3055\u3044\u3002
14447
+ - \u8EFD\u304F\u81EA\u7136\u306A\u30E6\u30FC\u30E2\u30A2\u306F\u69CB\u3044\u307E\u305B\u3093\u304C\u3001\u7121\u7406\u306B\u5197\u8AC7\u3084\u7D75\u6587\u5B57\u3092\u5165\u308C\u305F\u308A\u3001\u6B63\u78BA\u3055\u3092\u640D\u306A\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
14448
+
14449
+ ## \u5206\u6790\u4E0A\u306E\u5883\u754C
14450
+ - \u78BA\u8A8D\u3067\u304D\u308B\u4E8B\u5B9F\u3001\u6839\u62E0\u306B\u57FA\u3065\u304F\u63A8\u6E2C\u3001\u73FE\u6642\u70B9\u3067\u306F\u5224\u65AD\u3067\u304D\u306A\u3044\u3053\u3068\u3092\u533A\u5225\u3057\u3066\u304F\u3060\u3055\u3044\u3002
14451
+ - \u6027\u683C\u3001\u611F\u60C5\u3001\u4EBA\u9593\u95A2\u4FC2\u3001\u52D5\u6A5F\u306F\u7279\u306B\u614E\u91CD\u306B\u6271\u3044\u3001\u5185\u9762\u3092\u4F5C\u308A\u4E0A\u3052\u305F\u308A\u3001\u5B89\u6613\u306B\u30EC\u30C3\u30C6\u30EB\u3092\u8CBC\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
14452
+ - \u4EE3\u8868\u7684\u306A\u767A\u8A00\u3084\u30C7\u30FC\u30BF\u306F\u5C11\u91CF\u5F15\u7528\u3067\u304D\u307E\u3059\u304C\u3001\u9577\u3044\u30C1\u30E3\u30C3\u30C8\u30ED\u30B0\u3092\u305D\u306E\u307E\u307E\u4E26\u3079\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
14453
+ - \u30E6\u30FC\u30B6\u30FC\u304C\u6C42\u3081\u306A\u3044\u9650\u308A\u3001\u8AAC\u6559\u3001\u983C\u307E\u308C\u3066\u3044\u306A\u3044\u4EBA\u751F\u76F8\u8AC7\u3001\u6BCE\u56DE\u306E\u30EC\u30DD\u30FC\u30C8\u5316\u306F\u907F\u3051\u3066\u304F\u3060\u3055\u3044\u3002`,
14454
+ private: `\u3042\u306A\u305F\u306F ChatLab \u306E\u500B\u4EBA\u30C1\u30E3\u30C3\u30C8\u5206\u6790\u30D1\u30FC\u30C8\u30CA\u30FC\u3067\u3059\u3002\u6A5F\u68B0\u7684\u306A\u5206\u6790\u30EC\u30DD\u30FC\u30C8\u3067\u306F\u306A\u304F\u3001\u8A18\u9332\u306B\u3042\u308B\u4E8B\u5B9F\u3001\u5909\u5316\u3001\u3084\u308A\u53D6\u308A\u306E\u50BE\u5411\u3092\u30E6\u30FC\u30B6\u30FC\u304C\u7406\u89E3\u3067\u304D\u308B\u3088\u3046\u652F\u63F4\u3057\u307E\u3059\u3002
14455
+
14456
+ ## \u30B3\u30DF\u30E5\u30CB\u30B1\u30FC\u30B7\u30E7\u30F3
14457
+ - \u30E6\u30FC\u30B6\u30FC\u306E\u8A00\u8A9E\u3068\u8A71\u3057\u65B9\u306B\u5408\u308F\u305B\u3001\u30AB\u30B9\u30BF\u30DE\u30FC\u30B5\u30DD\u30FC\u30C8\u3084\u5805\u3044\u5831\u544A\u66F8\u306E\u3088\u3046\u3067\u306F\u306A\u304F\u3001\u81EA\u7136\u3067\u7387\u76F4\u306A\u8A00\u8449\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002
14458
+ - \u7C21\u5358\u306A\u8CEA\u554F\u306B\u306F\u7AEF\u7684\u306B\u7B54\u3048\u3001\u8907\u96D1\u306A\u8CEA\u554F\u3060\u3051\u3092\u6574\u7406\u3057\u3066\u8AAC\u660E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u898B\u51FA\u3057\u3001\u7B87\u6761\u66F8\u304D\u3001\u8868\u306F\u7406\u89E3\u3092\u52A9\u3051\u308B\u5834\u5408\u306B\u3060\u3051\u4F7F\u3044\u307E\u3059\u3002
14459
+ - \u6839\u62E0\u304C\u5341\u5206\u306A\u3089\u660E\u78BA\u306A\u5224\u65AD\u3092\u793A\u3057\u3001\u78BA\u8A8D\u3067\u304D\u306A\u3044\u3053\u3068\u306F\u7387\u76F4\u306B\u4F1D\u3048\u3066\u304F\u3060\u3055\u3044\u3002
14460
+ - \u8EFD\u304F\u81EA\u7136\u306A\u30E6\u30FC\u30E2\u30A2\u306F\u69CB\u3044\u307E\u305B\u3093\u304C\u3001\u7121\u7406\u306B\u5197\u8AC7\u3084\u7D75\u6587\u5B57\u3092\u5165\u308C\u305F\u308A\u3001\u6B63\u78BA\u3055\u3092\u640D\u306A\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
14461
+
14462
+ ## \u5206\u6790\u4E0A\u306E\u5883\u754C
14463
+ - \u78BA\u8A8D\u3067\u304D\u308B\u4E8B\u5B9F\u3001\u6839\u62E0\u306B\u57FA\u3065\u304F\u63A8\u6E2C\u3001\u73FE\u6642\u70B9\u3067\u306F\u5224\u65AD\u3067\u304D\u306A\u3044\u3053\u3068\u3092\u533A\u5225\u3057\u3066\u304F\u3060\u3055\u3044\u3002
14464
+ - \u6027\u683C\u3001\u611F\u60C5\u3001\u4EBA\u9593\u95A2\u4FC2\u3001\u52D5\u6A5F\u306F\u7279\u306B\u614E\u91CD\u306B\u6271\u3044\u3001\u5185\u9762\u3092\u4F5C\u308A\u4E0A\u3052\u305F\u308A\u3001\u5B89\u6613\u306B\u30EC\u30C3\u30C6\u30EB\u3092\u8CBC\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
14465
+ - \u4EE3\u8868\u7684\u306A\u767A\u8A00\u3084\u30C7\u30FC\u30BF\u306F\u5C11\u91CF\u5F15\u7528\u3067\u304D\u307E\u3059\u304C\u3001\u9577\u3044\u30C1\u30E3\u30C3\u30C8\u30ED\u30B0\u3092\u305D\u306E\u307E\u307E\u4E26\u3079\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
14466
+ - \u30E6\u30FC\u30B6\u30FC\u304C\u6C42\u3081\u306A\u3044\u9650\u308A\u3001\u8AAC\u6559\u3001\u983C\u307E\u308C\u3066\u3044\u306A\u3044\u4EBA\u751F\u76F8\u8AC7\u3001\u6BCE\u56DE\u306E\u30EC\u30DD\u30FC\u30C8\u5316\u306F\u907F\u3051\u3066\u304F\u3060\u3055\u3044\u3002`
14077
14467
  }
14078
14468
  }
14079
14469
  },
@@ -14405,26 +14795,34 @@ var zh_TW_default = {
14405
14795
  - \u53EA\u8981\u4F7F\u7528\u8005\u8A62\u554F\u804A\u5929\u7D00\u9304\u5167\u5BB9\u3001\u6700\u8FD1\u804A\u4EC0\u9EBC\u3001\u67D0\u4EBA\u8AAA\u904E\u4EC0\u9EBC\u3001\u7D71\u8A08\u6392\u884C\u3001\u662F\u5426\u51FA\u73FE\u904E\u67D0\u8A71\u984C\u6216\u8981\u6C42\u5F15\u7528\u539F\u8A71\uFF0C\u5FC5\u9808\u5148\u547C\u53EB\u5408\u9069\u7684\u8CC7\u6599\u5DE5\u5177\u6AA2\u7D22\u76EE\u524D\u8CC7\u6599\u5EAB\u3002
14406
14796
  - \u5982\u679C\u5DF2\u8FFD\u52A0\u65B0\u804A\u5929\u7D00\u9304\uFF0C\u76EE\u524D\u8CC7\u6599\u5EAB\u53EF\u80FD\u4E0D\u540C\u65BC\u820A\u8996\u7A97\u6B77\u53F2\uFF1B\u512A\u5148\u4F7F\u7528 get_chat_overview \u6216 get_recent_messages/search_messages \u53D6\u5F97\u6700\u65B0\u8B49\u64DA\u3002
14407
14797
  - \u53EA\u6709\u5DE5\u5177\u56DE\u50B3\u7684\u8A0A\u606F\u3001\u7D71\u8A08\u6216\u8CC7\u6599\u5EAB\u6982\u89BD\u53EF\u4EE5\u4F5C\u70BA\u4E8B\u5BE6\u4F9D\u64DA\uFF1B\u5DE5\u5177\u6C92\u6709\u56DE\u50B3\u8DB3\u5920\u8B49\u64DA\u6642\uFF0C\u660E\u78BA\u8AAA\u660E\u8CC7\u6599\u4E0D\u8DB3\uFF0C\u4E0D\u8981\u7DE8\u9020\u4E0D\u5B58\u5728\u7684\u804A\u5929\u7D00\u9304\u3002`,
14408
- responseInstruction: "\u6839\u64DA\u4F7F\u7528\u8005\u7684\u554F\u984C\uFF0C\u9078\u64C7\u5408\u9069\u7684\u5DE5\u5177\u53D6\u5F97\u8CC7\u6599\uFF0C\u7136\u5F8C\u57FA\u65BC\u8CC7\u6599\u7D66\u51FA\u56DE\u7B54\u3002",
14798
+ responseInstruction: "\u6839\u64DA\u4F7F\u7528\u8005\u7684\u554F\u984C\uFF0C\u5728\u9700\u8981\u6642\u9078\u64C7\u5408\u9069\u7684\u5DE5\u5177\u53D6\u5F97\u8CC7\u6599\uFF0C\u7136\u5F8C\u81EA\u7136\u3001\u76F4\u63A5\u5730\u7D66\u51FA\u56DE\u7B54\u3002",
14409
14799
  fallbackRoleDefinition: {
14410
- group: `\u4F60\u662F\u4E00\u500B\u5C08\u696D\u4F46\u98A8\u683C\u8F15\u9B06\u7684\u7FA4\u804A\u7D00\u9304\u5206\u6790\u52A9\u624B\u3002
14411
- \u4F60\u7684\u4EFB\u52D9\u662F\u5E6B\u52A9\u4F7F\u7528\u8005\u7406\u89E3\u548C\u5206\u6790\u4ED6\u5011\u7684\u7FA4\u804A\u7D00\u9304\u8CC7\u6599\uFF0C\u540C\u6642\u53EF\u4EE5\u9069\u5EA6\u4F7F\u7528\u7DB2\u8DEF\u71B1\u6897\u548C\u8868\u60C5/\u984F\u6587\u5B57\u6D3B\u8E8D\u6C23\u6C1B\uFF0C\u4F46\u4E0D\u5F71\u97FF\u7D50\u8AD6\u7684\u6E96\u78BA\u6027\u3002
14412
-
14413
- ## \u56DE\u7B54\u8981\u6C42
14414
- 1. \u57FA\u65BC\u5DE5\u5177\u56DE\u50B3\u7684\u8CC7\u6599\u56DE\u7B54\uFF0C\u4E0D\u8981\u7DE8\u9020\u8CC7\u8A0A
14415
- 2. \u5982\u679C\u8CC7\u6599\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u554F\u984C\uFF0C\u8ACB\u8AAA\u660E
14416
- 3. \u56DE\u7B54\u8981\u7C21\u6F54\u660E\u77AD\uFF0C\u4F7F\u7528 Markdown \u683C\u5F0F
14417
- 4. \u53EF\u4EE5\u9069\u5EA6\u52A0\u5165\u7DB2\u8DEF\u71B1\u6897\u3001\u8868\u60C5/\u984F\u6587\u5B57\uFF08\u5F37\u5EA6\u9069\u4E2D\uFF09
14418
- 5. \u73A9\u6897\u4E0D\u5F97\u5F71\u97FF\u4E8B\u5BE6\u6E96\u78BA\u8207\u7D50\u8AD6\u6E05\u6670\uFF0C\u907F\u514D\u4F4E\u4FD7\u6216\u5192\u72AF\u6027\u8868\u9054`,
14419
- private: `\u4F60\u662F\u4E00\u500B\u5C08\u696D\u4F46\u98A8\u683C\u8F15\u9B06\u7684\u79C1\u804A\u7D00\u9304\u5206\u6790\u52A9\u624B\u3002
14420
- \u4F60\u7684\u4EFB\u52D9\u662F\u5E6B\u52A9\u4F7F\u7528\u8005\u7406\u89E3\u548C\u5206\u6790\u4ED6\u5011\u7684\u79C1\u804A\u7D00\u9304\u8CC7\u6599\uFF0C\u540C\u6642\u53EF\u4EE5\u9069\u5EA6\u4F7F\u7528\u7DB2\u8DEF\u71B1\u6897\u548C\u8868\u60C5/\u984F\u6587\u5B57\u6D3B\u8E8D\u6C23\u6C1B\uFF0C\u4F46\u4E0D\u5F71\u97FF\u7D50\u8AD6\u7684\u6E96\u78BA\u6027\u3002
14421
-
14422
- ## \u56DE\u7B54\u8981\u6C42
14423
- 1. \u57FA\u65BC\u5DE5\u5177\u56DE\u50B3\u7684\u8CC7\u6599\u56DE\u7B54\uFF0C\u4E0D\u8981\u7DE8\u9020\u8CC7\u8A0A
14424
- 2. \u5982\u679C\u8CC7\u6599\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u554F\u984C\uFF0C\u8ACB\u8AAA\u660E
14425
- 3. \u56DE\u7B54\u8981\u7C21\u6F54\u660E\u77AD\uFF0C\u4F7F\u7528 Markdown \u683C\u5F0F
14426
- 4. \u53EF\u4EE5\u9069\u5EA6\u52A0\u5165\u7DB2\u8DEF\u71B1\u6897\u3001\u8868\u60C5/\u984F\u6587\u5B57\uFF08\u5F37\u5EA6\u9069\u4E2D\uFF09
14427
- 5. \u73A9\u6897\u4E0D\u5F97\u5F71\u97FF\u4E8B\u5BE6\u6E96\u78BA\u8207\u7D50\u8AD6\u6E05\u6670\uFF0C\u907F\u514D\u4F4E\u4FD7\u6216\u5192\u72AF\u6027\u8868\u9054`
14800
+ group: `\u4F60\u662F ChatLab \u88E1\u7684\u7FA4\u804A\u8A18\u9304\u5206\u6790\u642D\u6A94\uFF0C\u5E6B\u52A9\u4F7F\u7528\u8005\u5F9E\u804A\u5929\u8A18\u9304\u4E2D\u7406\u89E3\u4E8B\u5BE6\u3001\u8B8A\u5316\u548C\u4E92\u52D5\u6A21\u5F0F\uFF0C\u800C\u4E0D\u662F\u6A5F\u68B0\u5730\u7522\u751F\u5206\u6790\u5831\u544A\u3002
14801
+
14802
+ ## \u4EA4\u6D41\u65B9\u5F0F
14803
+ - \u8DDF\u96A8\u4F7F\u7528\u8005\u7684\u8A9E\u8A00\u548C\u4EA4\u6D41\u65B9\u5F0F\uFF0C\u8AAA\u81EA\u7136\u3001\u76F4\u63A5\u7684\u4EBA\u8A71\uFF0C\u907F\u514D\u5BA2\u670D\u8154\u548C\u904E\u5EA6\u6B63\u5F0F\u7684\u8868\u9054\u3002
14804
+ - \u7C21\u55AE\u554F\u984C\u76F4\u63A5\u56DE\u7B54\uFF1B\u8907\u96DC\u554F\u984C\u518D\u5206\u5C64\u8AAA\u660E\u3002\u6A19\u984C\u3001\u5217\u8868\u548C\u8868\u683C\u53EA\u5728\u6709\u52A9\u65BC\u7406\u89E3\u6642\u4F7F\u7528\u3002
14805
+ - \u5728\u8B49\u64DA\u5141\u8A31\u6642\u7D66\u51FA\u660E\u78BA\u5224\u65B7\uFF1B\u7121\u6CD5\u78BA\u8A8D\u7684\u90E8\u5206\u8981\u5766\u7387\u8AAA\u660E\u3002
14806
+ - \u53EF\u4EE5\u6709\u4E00\u9EDE\u81EA\u7136\u7684\u5E7D\u9ED8\u611F\uFF0C\u4F46\u4E0D\u8981\u5F37\u884C\u73A9\u6897\u3001\u5806\u8868\u60C5\u6216\u72A7\u7272\u6E96\u78BA\u6027\u3002
14807
+
14808
+ ## \u5206\u6790\u908A\u754C
14809
+ - \u5340\u5206\u80FD\u5920\u78BA\u8A8D\u7684\u4E8B\u5BE6\u3001\u57FA\u65BC\u8B49\u64DA\u7684\u63A8\u8AD6\uFF0C\u4EE5\u53CA\u66AB\u6642\u7121\u6CD5\u5224\u65B7\u7684\u90E8\u5206\u3002
14810
+ - \u6D89\u53CA\u6027\u683C\u3001\u60C5\u7DD2\u3001\u95DC\u4FC2\u548C\u52D5\u6A5F\u6642\u5C24\u5176\u8B39\u614E\uFF0C\u4E0D\u7DE8\u9020\u5FC3\u7406\u6D3B\u52D5\uFF0C\u4E5F\u4E0D\u8F15\u6613\u7D66\u4EBA\u8CBC\u6A19\u7C64\u3002
14811
+ - \u9069\u91CF\u5F15\u7528\u6709\u4EE3\u8868\u6027\u7684\u539F\u8A71\u548C\u8CC7\u6599\uFF0C\u4E0D\u8981\u5927\u6BB5\u5806\u780C\u804A\u5929\u8A18\u9304\u3002
14812
+ - \u9664\u975E\u4F7F\u7528\u8005\u660E\u78BA\u8981\u6C42\uFF0C\u4E0D\u8AAA\u6559\u3001\u4E0D\u64C5\u81EA\u7D66\u4EBA\u751F\u5EFA\u8B70\uFF0C\u4E5F\u4E0D\u628A\u6BCF\u6B21\u56DE\u7B54\u90FD\u5BEB\u6210\u7E3D\u7D50\u5831\u544A\u3002`,
14813
+ private: `\u4F60\u662F ChatLab \u88E1\u7684\u79C1\u804A\u8A18\u9304\u5206\u6790\u642D\u6A94\uFF0C\u5E6B\u52A9\u4F7F\u7528\u8005\u5F9E\u804A\u5929\u8A18\u9304\u4E2D\u7406\u89E3\u4E8B\u5BE6\u3001\u8B8A\u5316\u548C\u4E92\u52D5\u65B9\u5F0F\uFF0C\u800C\u4E0D\u662F\u6A5F\u68B0\u5730\u7522\u751F\u5206\u6790\u5831\u544A\u3002
14814
+
14815
+ ## \u4EA4\u6D41\u65B9\u5F0F
14816
+ - \u8DDF\u96A8\u4F7F\u7528\u8005\u7684\u8A9E\u8A00\u548C\u4EA4\u6D41\u65B9\u5F0F\uFF0C\u8AAA\u81EA\u7136\u3001\u76F4\u63A5\u7684\u4EBA\u8A71\uFF0C\u907F\u514D\u5BA2\u670D\u8154\u548C\u904E\u5EA6\u6B63\u5F0F\u7684\u8868\u9054\u3002
14817
+ - \u7C21\u55AE\u554F\u984C\u76F4\u63A5\u56DE\u7B54\uFF1B\u8907\u96DC\u554F\u984C\u518D\u5206\u5C64\u8AAA\u660E\u3002\u6A19\u984C\u3001\u5217\u8868\u548C\u8868\u683C\u53EA\u5728\u6709\u52A9\u65BC\u7406\u89E3\u6642\u4F7F\u7528\u3002
14818
+ - \u5728\u8B49\u64DA\u5141\u8A31\u6642\u7D66\u51FA\u660E\u78BA\u5224\u65B7\uFF1B\u7121\u6CD5\u78BA\u8A8D\u7684\u90E8\u5206\u8981\u5766\u7387\u8AAA\u660E\u3002
14819
+ - \u53EF\u4EE5\u6709\u4E00\u9EDE\u81EA\u7136\u7684\u5E7D\u9ED8\u611F\uFF0C\u4F46\u4E0D\u8981\u5F37\u884C\u73A9\u6897\u3001\u5806\u8868\u60C5\u6216\u72A7\u7272\u6E96\u78BA\u6027\u3002
14820
+
14821
+ ## \u5206\u6790\u908A\u754C
14822
+ - \u5340\u5206\u80FD\u5920\u78BA\u8A8D\u7684\u4E8B\u5BE6\u3001\u57FA\u65BC\u8B49\u64DA\u7684\u63A8\u8AD6\uFF0C\u4EE5\u53CA\u66AB\u6642\u7121\u6CD5\u5224\u65B7\u7684\u90E8\u5206\u3002
14823
+ - \u6D89\u53CA\u6027\u683C\u3001\u60C5\u7DD2\u3001\u95DC\u4FC2\u548C\u52D5\u6A5F\u6642\u5C24\u5176\u8B39\u614E\uFF0C\u4E0D\u7DE8\u9020\u5FC3\u7406\u6D3B\u52D5\uFF0C\u4E5F\u4E0D\u8F15\u6613\u7D66\u4EBA\u8CBC\u6A19\u7C64\u3002
14824
+ - \u9069\u91CF\u5F15\u7528\u6709\u4EE3\u8868\u6027\u7684\u539F\u8A71\u548C\u8CC7\u6599\uFF0C\u4E0D\u8981\u5927\u6BB5\u5806\u780C\u804A\u5929\u8A18\u9304\u3002
14825
+ - \u9664\u975E\u4F7F\u7528\u8005\u660E\u78BA\u8981\u6C42\uFF0C\u4E0D\u8AAA\u6559\u3001\u4E0D\u64C5\u81EA\u7D66\u4EBA\u751F\u5EFA\u8B70\uFF0C\u4E5F\u4E0D\u628A\u6BCF\u6B21\u56DE\u7B54\u90FD\u5BEB\u6210\u7E3D\u7D50\u5831\u544A\u3002`
14428
14826
  }
14429
14827
  }
14430
14828
  },
@@ -14456,9 +14854,9 @@ var localeMap = {
14456
14854
  "ja-JP": ja_JP_default,
14457
14855
  "zh-TW": zh_TW_default
14458
14856
  };
14459
- function getNestedValue(obj, path31) {
14857
+ function getNestedValue(obj, path33) {
14460
14858
  let current = obj;
14461
- for (const segment2 of path31.split(".")) {
14859
+ for (const segment2 of path33.split(".")) {
14462
14860
  if (current == null || typeof current !== "object") return void 0;
14463
14861
  current = current[segment2];
14464
14862
  }
@@ -14971,6 +15369,49 @@ var LLMConfigStore = class {
14971
15369
  }
14972
15370
  };
14973
15371
 
15372
+ // ../../packages/node-runtime/src/ai/file-config-storage.ts
15373
+ import * as fs28 from "fs";
15374
+ import * as path25 from "path";
15375
+ function createFileConfigStorage(baseDir) {
15376
+ return {
15377
+ readJson(key) {
15378
+ try {
15379
+ return JSON.parse(fs28.readFileSync(path25.join(baseDir, `${key}.json`), "utf-8"));
15380
+ } catch {
15381
+ return null;
15382
+ }
15383
+ },
15384
+ writeJson(key, data) {
15385
+ fs28.mkdirSync(baseDir, { recursive: true });
15386
+ fs28.writeFileSync(path25.join(baseDir, `${key}.json`), JSON.stringify(data, null, 2), "utf-8");
15387
+ }
15388
+ };
15389
+ }
15390
+
15391
+ // ../../packages/node-runtime/src/ai/auth-profile-llm-config-store.ts
15392
+ var defaultDeps = {
15393
+ resolveApiKey: (provider, authProfile) => resolveApiKey(provider, authProfile) || void 0,
15394
+ writeAuthProfile,
15395
+ deleteAuthProfile
15396
+ };
15397
+ function getAuthProfile2(config) {
15398
+ return config.authProfile;
15399
+ }
15400
+ function createAuthProfileLlmConfigStore(storage, deps = defaultDeps) {
15401
+ return new LLMConfigStore(storage, {
15402
+ resolveApiKey: deps.resolveApiKey,
15403
+ onApiKeyCreated: (config, apiKey) => {
15404
+ const profileName = config.name?.toLowerCase().replace(/\s+/g, "-") || config.provider;
15405
+ deps.writeAuthProfile(profileName, { type: "api_key", provider: config.provider, key: apiKey });
15406
+ return profileName;
15407
+ },
15408
+ onApiKeyDeleted: (config) => {
15409
+ const profileName = getAuthProfile2(config);
15410
+ if (profileName) deps.deleteAuthProfile(profileName);
15411
+ }
15412
+ });
15413
+ }
15414
+
14974
15415
  // ../../packages/node-runtime/src/ai/custom-store.ts
14975
15416
  function generateCustomId() {
14976
15417
  return `custom:${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
@@ -15790,8 +16231,8 @@ function exportWithFormat(params, openDatabase) {
15790
16231
  }
15791
16232
 
15792
16233
  // ../../packages/node-runtime/src/merger/temp-db.ts
15793
- import * as fs27 from "fs";
15794
- import * as path24 from "path";
16234
+ import * as fs29 from "fs";
16235
+ import * as path26 from "path";
15795
16236
  var TEMP_DB_SCHEMA = `
15796
16237
  CREATE TABLE IF NOT EXISTS meta (
15797
16238
  name TEXT NOT NULL,
@@ -16036,21 +16477,21 @@ function exportSessionToJson(db) {
16036
16477
  }
16037
16478
  function deleteTempDatabase(dbPath) {
16038
16479
  try {
16039
- if (fs27.existsSync(dbPath)) fs27.unlinkSync(dbPath);
16480
+ if (fs29.existsSync(dbPath)) fs29.unlinkSync(dbPath);
16040
16481
  const walPath = dbPath + "-wal";
16041
16482
  const shmPath = dbPath + "-shm";
16042
- if (fs27.existsSync(walPath)) fs27.unlinkSync(walPath);
16043
- if (fs27.existsSync(shmPath)) fs27.unlinkSync(shmPath);
16483
+ if (fs29.existsSync(walPath)) fs29.unlinkSync(walPath);
16484
+ if (fs29.existsSync(shmPath)) fs29.unlinkSync(shmPath);
16044
16485
  } catch {
16045
16486
  }
16046
16487
  }
16047
16488
  function cleanupTempDatabases(tempDir) {
16048
16489
  try {
16049
- if (!fs27.existsSync(tempDir)) return;
16050
- const files = fs27.readdirSync(tempDir);
16490
+ if (!fs29.existsSync(tempDir)) return;
16491
+ const files = fs29.readdirSync(tempDir);
16051
16492
  for (const file of files) {
16052
16493
  if (file.startsWith("merge_") && file.endsWith(".db")) {
16053
- deleteTempDatabase(path24.join(tempDir, file));
16494
+ deleteTempDatabase(path26.join(tempDir, file));
16054
16495
  }
16055
16496
  }
16056
16497
  } catch {
@@ -16129,6 +16570,7 @@ function deleteSession(adapter, sessionId) {
16129
16570
  var member_service_exports = {};
16130
16571
  __export(member_service_exports, {
16131
16572
  deleteMember: () => deleteMember2,
16573
+ deleteMembers: () => deleteMembers2,
16132
16574
  getMemberNameHistory: () => getMemberNameHistory2,
16133
16575
  getMembers: () => getMembers,
16134
16576
  getMembersPaginated: () => getMembersPaginated2,
@@ -16162,6 +16604,10 @@ function deleteMember2(adapter, sessionId, memberId) {
16162
16604
  const db = adapter.ensureWritable(sessionId);
16163
16605
  return deleteMember(db, memberId);
16164
16606
  }
16607
+ function deleteMembers2(adapter, sessionId, memberIds) {
16608
+ const db = adapter.ensureWritable(sessionId);
16609
+ return deleteMembers(db, memberIds);
16610
+ }
16165
16611
  function getMemberNameHistory2(adapter, sessionId, memberId) {
16166
16612
  const db = adapter.ensureReadonly(sessionId);
16167
16613
  return getMemberNameHistory(db, memberId);
@@ -16430,8 +16876,8 @@ function clearSessionOwner(adapter, sessionId) {
16430
16876
  }
16431
16877
 
16432
16878
  // ../../packages/node-runtime/src/services/contacts/overrides.ts
16433
- import fs28 from "fs";
16434
- import path25 from "path";
16879
+ import fs30 from "fs";
16880
+ import path27 from "path";
16435
16881
  var CONTACT_OVERRIDES_FILE_NAME = "contact-overrides.json";
16436
16882
  var CONTACT_OVERRIDES_TMP_PREFIX = "contact-overrides.tmp-";
16437
16883
  var CONTACT_OVERRIDES_VERSION = 1;
@@ -16442,23 +16888,23 @@ function createEmptyContactOverridesFile() {
16442
16888
  };
16443
16889
  }
16444
16890
  function getContactOverridesPath(snapshotDir) {
16445
- return path25.join(snapshotDir, CONTACT_OVERRIDES_FILE_NAME);
16891
+ return path27.join(snapshotDir, CONTACT_OVERRIDES_FILE_NAME);
16446
16892
  }
16447
16893
  function readContactOverrides(snapshotDir) {
16448
16894
  const filePath = getContactOverridesPath(snapshotDir);
16449
- if (!fs28.existsSync(filePath)) return createEmptyContactOverridesFile();
16895
+ if (!fs30.existsSync(filePath)) return createEmptyContactOverridesFile();
16450
16896
  try {
16451
- return normalizeContactOverrides(JSON.parse(fs28.readFileSync(filePath, "utf-8")));
16897
+ return normalizeContactOverrides(JSON.parse(fs30.readFileSync(filePath, "utf-8")));
16452
16898
  } catch (error) {
16453
16899
  appLogger.warn("contacts", "contact overrides file is unreadable", error);
16454
16900
  return createEmptyContactOverridesFile();
16455
16901
  }
16456
16902
  }
16457
16903
  function writeContactOverrides(snapshotDir, overrides) {
16458
- if (!fs28.existsSync(snapshotDir)) fs28.mkdirSync(snapshotDir, { recursive: true });
16459
- const tmpPath = path25.join(snapshotDir, `${CONTACT_OVERRIDES_TMP_PREFIX}${process.pid}-${Date.now()}`);
16460
- fs28.writeFileSync(tmpPath, JSON.stringify(normalizeContactOverrides(overrides), null, 2), "utf-8");
16461
- fs28.renameSync(tmpPath, getContactOverridesPath(snapshotDir));
16904
+ if (!fs30.existsSync(snapshotDir)) fs30.mkdirSync(snapshotDir, { recursive: true });
16905
+ const tmpPath = path27.join(snapshotDir, `${CONTACT_OVERRIDES_TMP_PREFIX}${process.pid}-${Date.now()}`);
16906
+ fs30.writeFileSync(tmpPath, JSON.stringify(normalizeContactOverrides(overrides), null, 2), "utf-8");
16907
+ fs30.renameSync(tmpPath, getContactOverridesPath(snapshotDir));
16462
16908
  }
16463
16909
  function normalizeContactOverrides(value) {
16464
16910
  const input = isRecord2(value) ? value : {};
@@ -16493,23 +16939,23 @@ function buildContactsSignature(adapter, timeRangePreset) {
16493
16939
  }
16494
16940
 
16495
16941
  // ../../packages/node-runtime/src/services/contacts/snapshot.ts
16496
- import fs29 from "fs";
16497
- import path26 from "path";
16942
+ import fs31 from "fs";
16943
+ import path28 from "path";
16498
16944
  var CONTACTS_SNAPSHOT_TMP_PREFIX = "contacts-snapshot.tmp-";
16499
16945
  function getContactsSnapshotPath(snapshotDir, timeRangePreset) {
16500
16946
  const preset = normalizeContactsTimeRangePreset(timeRangePreset);
16501
- return path26.join(snapshotDir, `contacts-snapshot-${preset}.json`);
16947
+ return path28.join(snapshotDir, `contacts-snapshot-${preset}.json`);
16502
16948
  }
16503
16949
  function readContactsSnapshot(snapshotDir, timeRangePreset, options2 = {}) {
16504
16950
  const snapshotPath = getContactsSnapshotPath(snapshotDir, timeRangePreset);
16505
- if (!fs29.existsSync(snapshotPath)) return null;
16951
+ if (!fs31.existsSync(snapshotPath)) return null;
16506
16952
  try {
16507
- return JSON.parse(fs29.readFileSync(snapshotPath, "utf-8"));
16953
+ return JSON.parse(fs31.readFileSync(snapshotPath, "utf-8"));
16508
16954
  } catch (error) {
16509
16955
  const ts = options2.now?.() ?? Date.now();
16510
- const backupPath = path26.join(snapshotDir, `contacts-snapshot.corrupt-${ts}.json`);
16956
+ const backupPath = path28.join(snapshotDir, `contacts-snapshot.corrupt-${ts}.json`);
16511
16957
  try {
16512
- fs29.renameSync(snapshotPath, backupPath);
16958
+ fs31.renameSync(snapshotPath, backupPath);
16513
16959
  } catch (renameError) {
16514
16960
  appLogger.warn("contacts", "failed to backup corrupt contacts snapshot", renameError);
16515
16961
  }
@@ -16518,17 +16964,17 @@ function readContactsSnapshot(snapshotDir, timeRangePreset, options2 = {}) {
16518
16964
  }
16519
16965
  }
16520
16966
  function writeContactsSnapshot(snapshotDir, snapshot) {
16521
- if (!fs29.existsSync(snapshotDir)) fs29.mkdirSync(snapshotDir, { recursive: true });
16522
- const tmpPath = path26.join(snapshotDir, `${CONTACTS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
16523
- fs29.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
16524
- fs29.renameSync(tmpPath, getContactsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
16967
+ if (!fs31.existsSync(snapshotDir)) fs31.mkdirSync(snapshotDir, { recursive: true });
16968
+ const tmpPath = path28.join(snapshotDir, `${CONTACTS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
16969
+ fs31.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
16970
+ fs31.renameSync(tmpPath, getContactsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
16525
16971
  }
16526
16972
  function cleanupContactsSnapshotTempFiles(snapshotDir) {
16527
- if (!fs29.existsSync(snapshotDir)) return;
16528
- for (const name of fs29.readdirSync(snapshotDir)) {
16973
+ if (!fs31.existsSync(snapshotDir)) return;
16974
+ for (const name of fs31.readdirSync(snapshotDir)) {
16529
16975
  if (!name.startsWith(CONTACTS_SNAPSHOT_TMP_PREFIX)) continue;
16530
16976
  try {
16531
- fs29.rmSync(path26.join(snapshotDir, name), { force: true });
16977
+ fs31.rmSync(path28.join(snapshotDir, name), { force: true });
16532
16978
  } catch (error) {
16533
16979
  appLogger.warn("contacts", "failed to remove contacts snapshot temp file", error);
16534
16980
  }
@@ -16566,7 +17012,7 @@ function createWorker(workerData, entryUrlInput) {
16566
17012
  return new Worker(bootstrap, options2);
16567
17013
  }
16568
17014
  function createContactsWorkerRunner(options2) {
16569
- return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve2, reject) => {
17015
+ return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve4, reject) => {
16570
17016
  if (signal.aborted) {
16571
17017
  reject(createAbortError());
16572
17018
  return;
@@ -16597,7 +17043,7 @@ function createContactsWorkerRunner(options2) {
16597
17043
  if (message.type === "success" && message.snapshot) {
16598
17044
  settled = true;
16599
17045
  signal.removeEventListener("abort", abort);
16600
- resolve2(message.snapshot);
17046
+ resolve4(message.snapshot);
16601
17047
  void worker.terminate();
16602
17048
  return;
16603
17049
  }
@@ -17026,23 +17472,23 @@ function buildPeopleRelationshipsSignature(adapter, timeRangePreset) {
17026
17472
  }
17027
17473
 
17028
17474
  // ../../packages/node-runtime/src/services/people/relationships/snapshot.ts
17029
- import fs30 from "fs";
17030
- import path27 from "path";
17475
+ import fs32 from "fs";
17476
+ import path29 from "path";
17031
17477
  var PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX = "people-relationships-snapshot.tmp-";
17032
17478
  function getPeopleRelationshipsSnapshotPath(snapshotDir, timeRangePreset) {
17033
17479
  const preset = normalizePeopleRelationshipsTimeRangePreset(timeRangePreset);
17034
- return path27.join(snapshotDir, `graph-snapshot-${preset}.json`);
17480
+ return path29.join(snapshotDir, `graph-snapshot-${preset}.json`);
17035
17481
  }
17036
17482
  function readPeopleRelationshipsSnapshot(snapshotDir, timeRangePreset, options2 = {}) {
17037
17483
  const snapshotPath = getPeopleRelationshipsSnapshotPath(snapshotDir, timeRangePreset);
17038
- if (!fs30.existsSync(snapshotPath)) return null;
17484
+ if (!fs32.existsSync(snapshotPath)) return null;
17039
17485
  try {
17040
- return JSON.parse(fs30.readFileSync(snapshotPath, "utf-8"));
17486
+ return JSON.parse(fs32.readFileSync(snapshotPath, "utf-8"));
17041
17487
  } catch (error) {
17042
17488
  const ts = options2.now?.() ?? Date.now();
17043
- const backupPath = path27.join(snapshotDir, `graph-snapshot.corrupt-${ts}.json`);
17489
+ const backupPath = path29.join(snapshotDir, `graph-snapshot.corrupt-${ts}.json`);
17044
17490
  try {
17045
- fs30.renameSync(snapshotPath, backupPath);
17491
+ fs32.renameSync(snapshotPath, backupPath);
17046
17492
  } catch (renameError) {
17047
17493
  appLogger.warn("people-relationships", "failed to backup corrupt people relationships snapshot", renameError);
17048
17494
  }
@@ -17051,17 +17497,17 @@ function readPeopleRelationshipsSnapshot(snapshotDir, timeRangePreset, options2
17051
17497
  }
17052
17498
  }
17053
17499
  function writePeopleRelationshipsSnapshot(snapshotDir, snapshot) {
17054
- if (!fs30.existsSync(snapshotDir)) fs30.mkdirSync(snapshotDir, { recursive: true });
17055
- const tmpPath = path27.join(snapshotDir, `${PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
17056
- fs30.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
17057
- fs30.renameSync(tmpPath, getPeopleRelationshipsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
17500
+ if (!fs32.existsSync(snapshotDir)) fs32.mkdirSync(snapshotDir, { recursive: true });
17501
+ const tmpPath = path29.join(snapshotDir, `${PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
17502
+ fs32.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
17503
+ fs32.renameSync(tmpPath, getPeopleRelationshipsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
17058
17504
  }
17059
17505
  function cleanupPeopleRelationshipsSnapshotTempFiles(snapshotDir) {
17060
- if (!fs30.existsSync(snapshotDir)) return;
17061
- for (const name of fs30.readdirSync(snapshotDir)) {
17506
+ if (!fs32.existsSync(snapshotDir)) return;
17507
+ for (const name of fs32.readdirSync(snapshotDir)) {
17062
17508
  if (!name.startsWith(PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX)) continue;
17063
17509
  try {
17064
- fs30.rmSync(path27.join(snapshotDir, name), { force: true });
17510
+ fs32.rmSync(path29.join(snapshotDir, name), { force: true });
17065
17511
  } catch (error) {
17066
17512
  appLogger.warn("people-relationships", "failed to remove people relationships snapshot temp file", error);
17067
17513
  }
@@ -17099,7 +17545,7 @@ function createWorker2(workerData, entryUrlInput) {
17099
17545
  return new Worker2(bootstrap, options2);
17100
17546
  }
17101
17547
  function createPeopleRelationshipsWorkerRunner(options2) {
17102
- return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve2, reject) => {
17548
+ return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve4, reject) => {
17103
17549
  if (signal.aborted) {
17104
17550
  reject(createAbortError2());
17105
17551
  return;
@@ -17130,7 +17576,7 @@ function createPeopleRelationshipsWorkerRunner(options2) {
17130
17576
  if (message.type === "success" && message.snapshot) {
17131
17577
  settled = true;
17132
17578
  signal.removeEventListener("abort", abort);
17133
- resolve2(message.snapshot);
17579
+ resolve4(message.snapshot);
17134
17580
  void worker.terminate();
17135
17581
  return;
17136
17582
  }
@@ -17583,7 +18029,7 @@ __export(relationships_exports, {
17583
18029
  });
17584
18030
 
17585
18031
  // ../../packages/node-runtime/src/services/global-insight/service.ts
17586
- import fs31 from "fs";
18032
+ import fs33 from "fs";
17587
18033
 
17588
18034
  // ../../packages/node-runtime/src/services/global-insight/signature.ts
17589
18035
  function buildAnnualSummarySignature(adapter, range) {
@@ -17610,7 +18056,7 @@ function resolveDefaultAnnualSummaryWorkerEntryUrl(currentModuleUrl = import.met
17610
18056
  return entryExists(sibling) ? sibling : new URL("./global-insight-worker.js", moduleUrl);
17611
18057
  }
17612
18058
  function createAnnualSummaryWorkerRunner(options2) {
17613
- return ({ signature, range, signal, onProgress }) => new Promise((resolve2, reject) => {
18059
+ return ({ signature, range, signal, onProgress }) => new Promise((resolve4, reject) => {
17614
18060
  if (signal.aborted) {
17615
18061
  reject(new Error("annual summary worker aborted"));
17616
18062
  return;
@@ -17641,7 +18087,7 @@ function createAnnualSummaryWorkerRunner(options2) {
17641
18087
  if (message.type === "success" && message.snapshot) {
17642
18088
  settled = true;
17643
18089
  signal.removeEventListener("abort", abort);
17644
- resolve2(message.snapshot);
18090
+ resolve4(message.snapshot);
17645
18091
  void worker.terminate();
17646
18092
  return;
17647
18093
  }
@@ -17836,7 +18282,7 @@ var DefaultGlobalInsightService = class {
17836
18282
  }
17837
18283
  getSnapshot(range) {
17838
18284
  const key = toAnnualSummaryRangeKey(range);
17839
- if (this.snapshots.has(key) && !fs31.existsSync(getAnnualSummarySnapshotPath(this.snapshotDir, range))) {
18285
+ if (this.snapshots.has(key) && !fs33.existsSync(getAnnualSummarySnapshotPath(this.snapshotDir, range))) {
17840
18286
  this.snapshots.delete(key);
17841
18287
  }
17842
18288
  if (!this.snapshots.has(key)) {
@@ -17884,8 +18330,8 @@ __export(global_insight_exports, {
17884
18330
  });
17885
18331
 
17886
18332
  // ../../packages/node-runtime/src/semantic-index/config.ts
17887
- import fs32 from "fs";
17888
- import path28 from "path";
18333
+ import fs34 from "fs";
18334
+ import path30 from "path";
17889
18335
  var DEFAULT_SEMANTIC_INDEX_MODEL_DOWNLOAD_SOURCE = "huggingface";
17890
18336
  var SEMANTIC_INDEX_CONFIG_VERSION = 1;
17891
18337
  var SEARCH_MAX_RESULTS_DEFAULT = 10;
@@ -17974,9 +18420,9 @@ var SemanticIndexConfigStore = class {
17974
18420
  return this.set({ ...this.get(), enabled });
17975
18421
  }
17976
18422
  get() {
17977
- if (!fs32.existsSync(this.filePath)) return defaultSemanticIndexConfig();
18423
+ if (!fs34.existsSync(this.filePath)) return defaultSemanticIndexConfig();
17978
18424
  try {
17979
- const raw = JSON.parse(fs32.readFileSync(this.filePath, "utf-8"));
18425
+ const raw = JSON.parse(fs34.readFileSync(this.filePath, "utf-8"));
17980
18426
  return normalizeConfig(raw);
17981
18427
  } catch {
17982
18428
  return defaultSemanticIndexConfig();
@@ -17984,9 +18430,9 @@ var SemanticIndexConfigStore = class {
17984
18430
  }
17985
18431
  set(config) {
17986
18432
  const normalized = normalizeConfig(config);
17987
- const dir = path28.dirname(this.filePath);
17988
- if (!fs32.existsSync(dir)) fs32.mkdirSync(dir, { recursive: true });
17989
- fs32.writeFileSync(this.filePath, JSON.stringify(normalized, null, 2), "utf-8");
18433
+ const dir = path30.dirname(this.filePath);
18434
+ if (!fs34.existsSync(dir)) fs34.mkdirSync(dir, { recursive: true });
18435
+ fs34.writeFileSync(this.filePath, JSON.stringify(normalized, null, 2), "utf-8");
17990
18436
  return normalized;
17991
18437
  }
17992
18438
  resolveModelId() {
@@ -17995,7 +18441,7 @@ var SemanticIndexConfigStore = class {
17995
18441
  };
17996
18442
 
17997
18443
  // ../../packages/node-runtime/src/semantic-index/service.ts
17998
- import path29 from "path";
18444
+ import path31 from "path";
17999
18445
 
18000
18446
  // ../../packages/node-runtime/src/semantic-index/chunker-config.ts
18001
18447
  import { createHash as createHash2 } from "crypto";
@@ -18316,8 +18762,8 @@ function createEmbedder(config, deps = {}) {
18316
18762
  if (!config.api || !config.api.baseUrl || !config.api.model) {
18317
18763
  throw new Error("semantic index API config incomplete: baseUrl and model are required");
18318
18764
  }
18319
- const resolve2 = deps.resolveApiKey ?? resolveApiKey;
18320
- const apiKey = resolve2("", config.api.authProfile);
18765
+ const resolve4 = deps.resolveApiKey ?? resolveApiKey;
18766
+ const apiKey = resolve4("", config.api.authProfile);
18321
18767
  return new OpenAICompatibleEmbeddingProvider(
18322
18768
  { baseUrl: config.api.baseUrl, apiKey, model: config.api.model },
18323
18769
  { fetchFn: deps.fetchFn }
@@ -18354,8 +18800,8 @@ function extensionSuffix(platform2) {
18354
18800
  return "so";
18355
18801
  }
18356
18802
  function platformPackageName(platform2, arch2) {
18357
- const os2 = platform2 === "win32" ? "windows" : platform2;
18358
- return `${BASE_PACKAGE_NAME}-${os2}-${arch2}`;
18803
+ const os3 = platform2 === "win32" ? "windows" : platform2;
18804
+ return `${BASE_PACKAGE_NAME}-${os3}-${arch2}`;
18359
18805
  }
18360
18806
  function getLoadablePath() {
18361
18807
  if (!validPlatform(platform, arch)) {
@@ -18854,7 +19300,7 @@ var SemanticIndexJobQueue = class {
18854
19300
  /** 等待队列清空(含当前任务) */
18855
19301
  whenIdle() {
18856
19302
  if (!this.processing && this.pending.length === 0) return Promise.resolve();
18857
- return new Promise((resolve2) => this.idleResolvers.push(resolve2));
19303
+ return new Promise((resolve4) => this.idleResolvers.push(resolve4));
18858
19304
  }
18859
19305
  removePending(dbPathHash) {
18860
19306
  this.pending = this.pending.filter((j) => j.dbPathHash !== dbPathHash);
@@ -18876,7 +19322,7 @@ var SemanticIndexJobQueue = class {
18876
19322
  this.processing = false;
18877
19323
  const resolvers = this.idleResolvers;
18878
19324
  this.idleResolvers = [];
18879
- for (const resolve2 of resolvers) resolve2();
19325
+ for (const resolve4 of resolvers) resolve4();
18880
19326
  }
18881
19327
  };
18882
19328
 
@@ -19526,16 +19972,16 @@ function resolveSearchToolEvidenceTokens(maxResultTokens) {
19526
19972
  return maxResultTokens && maxResultTokens > 0 ? Math.min(SEARCH_TOOL_EVIDENCE_TOKENS, maxResultTokens) : SEARCH_TOOL_EVIDENCE_TOKENS;
19527
19973
  }
19528
19974
  function sessionIdFromDbPath(dbPath) {
19529
- return path29.basename(dbPath, ".db");
19975
+ return path31.basename(dbPath, ".db");
19530
19976
  }
19531
19977
  var SEMANTIC_INDEX_DB_FILE = "embedding_index.db";
19532
19978
  var SEMANTIC_INDEX_CONFIG_FILE = "semantic-index-config.json";
19533
19979
  function createSemanticIndexService(params) {
19534
19980
  const { pathProvider } = params;
19535
19981
  return new SemanticIndexService({
19536
- vectorDbPath: path29.join(pathProvider.getVectorDir(), SEMANTIC_INDEX_DB_FILE),
19537
- configPath: path29.join(pathProvider.getAiDataDir(), SEMANTIC_INDEX_CONFIG_FILE),
19538
- modelsCacheDir: path29.join(pathProvider.getAiDataDir(), "models", "semantic-index"),
19982
+ vectorDbPath: path31.join(pathProvider.getVectorDir(), SEMANTIC_INDEX_DB_FILE),
19983
+ configPath: path31.join(pathProvider.getAiDataDir(), SEMANTIC_INDEX_CONFIG_FILE),
19984
+ modelsCacheDir: path31.join(pathProvider.getAiDataDir(), "models", "semantic-index"),
19539
19985
  modelDownloadProxyUrl: params.modelDownloadProxyUrl,
19540
19986
  sessionAdapter: params.sessionAdapter,
19541
19987
  nativeBinding: params.nativeBinding,
@@ -20085,8 +20531,8 @@ ${text}`;
20085
20531
  };
20086
20532
 
20087
20533
  // ../../packages/node-runtime/src/services/merge-cache.ts
20088
- import * as fs33 from "fs";
20089
- import * as path30 from "path";
20534
+ import * as fs35 from "fs";
20535
+ import * as path32 from "path";
20090
20536
  import * as crypto from "crypto";
20091
20537
  var MergeSessionCache = class {
20092
20538
  cache = /* @__PURE__ */ new Map();
@@ -20095,15 +20541,15 @@ var MergeSessionCache = class {
20095
20541
  constructor(pathProvider, options2) {
20096
20542
  this.tempDir = pathProvider.getTempDir();
20097
20543
  this.nativeBinding = options2?.nativeBinding;
20098
- if (!fs33.existsSync(this.tempDir)) {
20099
- fs33.mkdirSync(this.tempDir, { recursive: true });
20544
+ if (!fs35.existsSync(this.tempDir)) {
20545
+ fs35.mkdirSync(this.tempDir, { recursive: true });
20100
20546
  }
20101
20547
  }
20102
20548
  generateTempDbPath(filename) {
20103
20549
  const ts = Date.now();
20104
20550
  const rand = Math.random().toString(36).slice(2, 8);
20105
20551
  const safeName = filename.replace(/[/\\?%*:|"<>]/g, "_").slice(0, 40);
20106
- return path30.join(this.tempDir, `merge_${safeName}_${ts}_${rand}.db`);
20552
+ return path32.join(this.tempDir, `merge_${safeName}_${ts}_${rand}.db`);
20107
20553
  }
20108
20554
  /** Store a parsed file's temp DB and return a handle for subsequent requests. */
20109
20555
  store(filename, tempDbPath) {
@@ -20114,7 +20560,7 @@ var MergeSessionCache = class {
20114
20560
  /** Open a TempDbReader for a given handle. Caller must close the reader. */
20115
20561
  openReader(handle) {
20116
20562
  const entry = this.cache.get(handle);
20117
- if (!entry || !fs33.existsSync(entry.tempDbPath)) return null;
20563
+ if (!entry || !fs35.existsSync(entry.tempDbPath)) return null;
20118
20564
  const adapter = openBetterSqliteDatabase(entry.tempDbPath, {
20119
20565
  readonly: true,
20120
20566
  nativeBinding: this.nativeBinding
@@ -20159,7 +20605,7 @@ var MergeSessionCache = class {
20159
20605
  };
20160
20606
 
20161
20607
  // ../../packages/node-runtime/src/services/push-importer.ts
20162
- import * as fs34 from "fs";
20608
+ import * as fs36 from "fs";
20163
20609
  var SYSTEM_SENDER_ID = "SYSTEM";
20164
20610
  var SYSTEM_MEMBER_NAME = "\u7CFB\u7EDF\u6D88\u606F";
20165
20611
  function isRecord3(value) {
@@ -20526,7 +20972,7 @@ async function executePushImportUnlocked(deps, sessionId, payload) {
20526
20972
  return { ok: false, reason: "invalid_payload", message: "sessionId contains invalid characters" };
20527
20973
  }
20528
20974
  const dbPath = deps.getDbPath(sessionId);
20529
- const isNew = !fs34.existsSync(dbPath);
20975
+ const isNew = !fs36.existsSync(dbPath);
20530
20976
  const validationError = validatePayload(payload, isNew);
20531
20977
  if (validationError) {
20532
20978
  return { ok: false, reason: "invalid_payload", message: validationError };
@@ -20626,6 +21072,12 @@ var ImportIdempotencyCache = class {
20626
21072
  };
20627
21073
 
20628
21074
  export {
21075
+ CHATLAB_TEMP_ROOT_ENV,
21076
+ resolveChatLabTempRoot,
21077
+ ensureChatLabTempRoot,
21078
+ getChatLabTempScopeDir,
21079
+ createChatLabTempDir,
21080
+ removeChatLabTempDir,
20629
21081
  writeParseResultToDb,
20630
21082
  detectFormat,
20631
21083
  detectAllFormats,
@@ -20679,6 +21131,9 @@ export {
20679
21131
  formatAIError,
20680
21132
  parseAssistantFile,
20681
21133
  serializeAssistant,
21134
+ DEFAULT_GENERAL_ASSISTANT_CONFIGS,
21135
+ DEFAULT_GENERAL_ASSISTANT_RAW_CONFIGS,
21136
+ LEGACY_GENERAL_ASSISTANT_DIGESTS,
20682
21137
  AssistantManager,
20683
21138
  parseSkillFile,
20684
21139
  extractSkillId,
@@ -20747,6 +21202,8 @@ export {
20747
21202
  checkSessionsCanGenerateSummary,
20748
21203
  MAX_CONFIG_COUNT,
20749
21204
  LLMConfigStore,
21205
+ createFileConfigStorage,
21206
+ createAuthProfileLlmConfigStore,
20750
21207
  CustomProviderStore,
20751
21208
  CustomModelStore,
20752
21209
  normalizeAnthropicBaseUrl,
@@ -20841,4 +21298,4 @@ export {
20841
21298
  hashImportBody,
20842
21299
  ImportIdempotencyCache
20843
21300
  };
20844
- //# sourceMappingURL=chunk-GYPBWKAU.mjs.map
21301
+ //# sourceMappingURL=chunk-75FZ26HM.mjs.map