chatlab-cli 0.27.2 → 0.28.0

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 (68) hide show
  1. package/README.md +1 -1
  2. package/dist/{chat-command-QVCZVDSB.mjs → chat-command-7WL5NMZ6.mjs} +5 -5
  3. package/dist/{chunk-B2VLK3FB.mjs → chunk-55WR6WKW.mjs} +50 -18
  4. package/dist/{chunk-B2VLK3FB.mjs.map → chunk-55WR6WKW.mjs.map} +1 -1
  5. package/dist/{chunk-K7UUN3HT.mjs → chunk-GFRG7TZQ.mjs} +27 -12
  6. package/dist/chunk-GFRG7TZQ.mjs.map +1 -0
  7. package/dist/{chunk-DHRSLYUM.mjs → chunk-GPF34WXV.mjs} +2470 -330
  8. package/dist/chunk-GPF34WXV.mjs.map +1 -0
  9. package/dist/{chunk-OD3YH23N.mjs → chunk-VASK54KT.mjs} +2 -2
  10. package/dist/{chunk-H22VDCPB.mjs → chunk-WGS33EWH.mjs} +2 -2
  11. package/dist/{chunk-PXWAYFII.mjs → chunk-XNU5X7EV.mjs} +3 -3
  12. package/dist/{chunk-JOXF6ROV.mjs → chunk-YQ2FJGBT.mjs} +137 -18
  13. package/dist/chunk-YQ2FJGBT.mjs.map +1 -0
  14. package/dist/{chunk-ST5APJB2.mjs → chunk-YZDEZ6UI.mjs} +3 -3
  15. package/dist/{chunk-MDDWX2MG.mjs → chunk-ZSFVX6FM.mjs} +3 -3
  16. package/dist/cli.mjs +4 -4
  17. package/dist/{http-LSCVGWCI.mjs → http-C2FBHNZG.mjs} +9 -9
  18. package/dist/{import-E6HBJMMT.mjs → import-ED6JCPSJ.mjs} +5 -5
  19. package/dist/index.mjs +9 -9
  20. package/dist/{mcp-I7JUC5JV.mjs → mcp-5JIBER4M.mjs} +5 -5
  21. package/dist/semantic-index-worker.mjs +1 -1
  22. package/dist/{src-HZILDI7C.mjs → src-WBNM42SL.mjs} +19 -3
  23. package/dist/{stream-import-IMRULRS2.mjs → stream-import-37U3SROO.mjs} +4 -4
  24. package/dist/{worker-runtime-WWQ7W74Q.mjs → worker-runtime-6DGYL4TF.mjs} +2 -2
  25. package/dist-web/assets/{DebugToolsPanel.vue_vue_type_script_setup_true_lang-Du1FDD8L.js → DebugToolsPanel.vue_vue_type_script_setup_true_lang-CCz0Syxo.js} +5 -5
  26. package/dist-web/assets/{MessageExportModal-4ehLHG4x.js → MessageExportModal-Dd6R-cX_.js} +1 -1
  27. package/dist-web/assets/electron-D9vE5t3H.js +1 -0
  28. package/dist-web/assets/{electron-B3AteJC8.js → electron-DjminAKK.js} +1 -1
  29. package/dist-web/assets/{fetch-BUcl-Frr.js → fetch-B_kLRm6-.js} +1 -1
  30. package/dist-web/assets/{fetch-DZFx8FA4.js → fetch-CURbMNJV.js} +1 -1
  31. package/dist-web/assets/fetch-Cle6QKmL.js +3 -0
  32. package/dist-web/assets/{fetch-BQxv_UGQ.js → fetch-DFCYOQe5.js} +1 -1
  33. package/dist-web/assets/{fetch-ChZEF_n3.js → fetch-DOhCQ5J8.js} +1 -1
  34. package/dist-web/assets/{fetch-BwQh9WUD.js → fetch-DV8A1dGB.js} +1 -1
  35. package/dist-web/assets/{fetch-DlJFgbum.js → fetch-Wad5mWVH.js} +1 -1
  36. package/dist-web/assets/{fetch-DCQN6wfR.js → fetch-r83wdzHy.js} +1 -1
  37. package/dist-web/assets/{fetch-CZDFhvxY.js → fetch-srCJzcWc.js} +1 -1
  38. package/dist-web/assets/{fetch-C2mSdG3h.js → fetch-uM3erGZm.js} +1 -1
  39. package/dist-web/assets/index-7E5GSvR2.css +1 -0
  40. package/dist-web/assets/index-BCRHSc1k.js +173 -0
  41. package/dist-web/assets/{index-DlkH2E7N.js → index-BIvLzdwg.js} +1 -1
  42. package/dist-web/assets/{index-qVTX1tLg.js → index-BpszRZ8V.js} +3 -3
  43. package/dist-web/assets/index-D5UgZUpS.js +12 -0
  44. package/dist-web/assets/{index-DTlfOd_u.js → index-hOsKRsp6.js} +2 -2
  45. package/dist-web/assets/{index-KAFPL6dl.js → index-tkbEq8av.js} +1 -1
  46. package/dist-web/assets/{web-CoKgy4Oo.js → web-D27K6zSX.js} +1 -1
  47. package/dist-web/index.html +2 -2
  48. package/package.json +1 -1
  49. package/dist/chunk-DHRSLYUM.mjs.map +0 -1
  50. package/dist/chunk-JOXF6ROV.mjs.map +0 -1
  51. package/dist/chunk-K7UUN3HT.mjs.map +0 -1
  52. package/dist-web/assets/electron-2m4Vdk2z.js +0 -1
  53. package/dist-web/assets/fetch-O8M5ZWsc.js +0 -3
  54. package/dist-web/assets/index-B_uZZGqi.js +0 -173
  55. package/dist-web/assets/index-CoX0L-A8.css +0 -1
  56. package/dist-web/assets/index-DR78oafF.js +0 -11
  57. /package/dist/{chat-command-QVCZVDSB.mjs.map → chat-command-7WL5NMZ6.mjs.map} +0 -0
  58. /package/dist/{chunk-OD3YH23N.mjs.map → chunk-VASK54KT.mjs.map} +0 -0
  59. /package/dist/{chunk-H22VDCPB.mjs.map → chunk-WGS33EWH.mjs.map} +0 -0
  60. /package/dist/{chunk-PXWAYFII.mjs.map → chunk-XNU5X7EV.mjs.map} +0 -0
  61. /package/dist/{chunk-ST5APJB2.mjs.map → chunk-YZDEZ6UI.mjs.map} +0 -0
  62. /package/dist/{chunk-MDDWX2MG.mjs.map → chunk-ZSFVX6FM.mjs.map} +0 -0
  63. /package/dist/{http-LSCVGWCI.mjs.map → http-C2FBHNZG.mjs.map} +0 -0
  64. /package/dist/{import-E6HBJMMT.mjs.map → import-ED6JCPSJ.mjs.map} +0 -0
  65. /package/dist/{mcp-I7JUC5JV.mjs.map → mcp-5JIBER4M.mjs.map} +0 -0
  66. /package/dist/{src-HZILDI7C.mjs.map → src-WBNM42SL.mjs.map} +0 -0
  67. /package/dist/{stream-import-IMRULRS2.mjs.map → stream-import-37U3SROO.mjs.map} +0 -0
  68. /package/dist/{worker-runtime-WWQ7W74Q.mjs.map → worker-runtime-6DGYL4TF.mjs.map} +0 -0
package/README.md CHANGED
@@ -14,7 +14,7 @@ English | [简体中文](./README.zh-CN.md)
14
14
 
15
15
  ChatLab is an open-source desktop app for understanding your social conversations. It combines a flexible SQL engine with AI agents so you can explore patterns, ask better questions, and extract insights from chat data, all on your own machine.
16
16
 
17
- Currently supported: **WhatsApp, LINE, QQ, Discord, Instagram, Telegram, and iMessage**. Coming next: **Messenger and KakaoTalk**.
17
+ Currently supported: **WhatsApp, LINE, QQ, Discord, Instagram, Telegram, iMessage, and Google Chat**. Coming next: **Messenger and KakaoTalk**.
18
18
 
19
19
  > New install? Start here: [Getting started](https://docs.chatlab.fun/usage/quick-start)
20
20
 
@@ -6,10 +6,10 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  createCliRunAgentStream
9
- } from "./chunk-PXWAYFII.mjs";
10
- import "./chunk-OD3YH23N.mjs";
11
- import "./chunk-DHRSLYUM.mjs";
12
- import "./chunk-B2VLK3FB.mjs";
9
+ } from "./chunk-XNU5X7EV.mjs";
10
+ import "./chunk-VASK54KT.mjs";
11
+ import "./chunk-GPF34WXV.mjs";
12
+ import "./chunk-55WR6WKW.mjs";
13
13
  import "./chunk-GFHSSCCR.mjs";
14
14
 
15
15
  // src/ai/chat-command.ts
@@ -302,4 +302,4 @@ export {
302
302
  runChatCommand,
303
303
  runChatTurn
304
304
  };
305
- //# sourceMappingURL=chat-command-QVCZVDSB.mjs.map
305
+ //# sourceMappingURL=chat-command-7WL5NMZ6.mjs.map
@@ -15315,7 +15315,7 @@ function normalizeConfig(raw) {
15315
15315
  mode,
15316
15316
  local: { modelId: raw.local?.modelId ?? base.local.modelId },
15317
15317
  api,
15318
- searchMaxResults: clampSearchMaxResults(raw.searchMaxResults)
15318
+ searchMaxResults: SEARCH_MAX_RESULTS_DEFAULT
15319
15319
  };
15320
15320
  }
15321
15321
  var SemanticIndexConfigStore = class {
@@ -15462,6 +15462,8 @@ var OpenAICompatibleEmbeddingProvider = class {
15462
15462
  const [vector] = await this.embedDocuments([text]);
15463
15463
  return vector;
15464
15464
  }
15465
+ async preload() {
15466
+ }
15465
15467
  };
15466
15468
 
15467
15469
  // ../../packages/node-runtime/src/semantic-index/embedding/text.ts
@@ -15541,6 +15543,9 @@ var LocalEmbeddingProvider = class {
15541
15543
  const [vector] = await this.embedDocuments([withInstruction]);
15542
15544
  return vector;
15543
15545
  }
15546
+ async preload() {
15547
+ await this.getExtractor();
15548
+ }
15544
15549
  };
15545
15550
 
15546
15551
  // ../../packages/node-runtime/src/semantic-index/embedding/profiles.ts
@@ -16077,7 +16082,7 @@ var SemanticIndexStateStore = class {
16077
16082
  return rows.map(rowToState);
16078
16083
  }
16079
16084
  remove(dbPathHash) {
16080
- this.db.prepare(`DELETE FROM semantic_index_session WHERE db_path_hash = ?`).run(dbPathHash);
16085
+ return this.db.prepare(`DELETE FROM semantic_index_session WHERE db_path_hash = ?`).run(dbPathHash).changes;
16081
16086
  }
16082
16087
  close() {
16083
16088
  this.db.close();
@@ -16158,6 +16163,7 @@ var KNOWN_PLATFORMS = {
16158
16163
  WHATSAPP: "whatsapp",
16159
16164
  TELEGRAM: "telegram",
16160
16165
  INSTAGRAM: "instagram",
16166
+ GOOGLE_CHAT: "google-chat",
16161
16167
  LINE: "line",
16162
16168
  UNKNOWN: "unknown"
16163
16169
  };
@@ -16796,7 +16802,7 @@ function createSemanticIndexService(params) {
16796
16802
  return new SemanticIndexService({
16797
16803
  vectorDbPath: path22.join(pathProvider.getVectorDir(), SEMANTIC_INDEX_DB_FILE),
16798
16804
  configPath: path22.join(pathProvider.getAiDataDir(), SEMANTIC_INDEX_CONFIG_FILE),
16799
- modelsCacheDir: path22.join(pathProvider.getCacheDir(), "models", "semantic-index"),
16805
+ modelsCacheDir: path22.join(pathProvider.getAiDataDir(), "models", "semantic-index"),
16800
16806
  sessionAdapter: params.sessionAdapter,
16801
16807
  nativeBinding: params.nativeBinding,
16802
16808
  loadSqliteVec: params.loadSqliteVec,
@@ -16812,6 +16818,7 @@ var SemanticIndexService = class {
16812
16818
  options;
16813
16819
  embedder = null;
16814
16820
  embedderModelId = null;
16821
+ modelPreloadStatus = "idle";
16815
16822
  /** 当前激活的 chunker 身份(version + 参数 hash),随索引记录用于重建判定 */
16816
16823
  chunkerVersion = CHUNKER_VERSION;
16817
16824
  chunkerConfigHash = computeChunkerConfigHash(DEFAULT_CHUNKER_CONFIG);
@@ -16852,6 +16859,9 @@ var SemanticIndexService = class {
16852
16859
  * 保存配置;模型身份变化会使已启用对话的索引在重建完成前不被检索使用。
16853
16860
  * 传入 apiKey 时写入固定 auth profile,config 内只保存引用,绝不持久化明文。
16854
16861
  */
16862
+ getModelStatus() {
16863
+ return this.modelPreloadStatus;
16864
+ }
16855
16865
  setConfig(config, options) {
16856
16866
  const saved = persistSemanticIndexConfig(this.configStore, config, {
16857
16867
  apiKey: options?.apiKey,
@@ -16859,9 +16869,18 @@ var SemanticIndexService = class {
16859
16869
  });
16860
16870
  this.embedder = null;
16861
16871
  this.embedderModelId = null;
16872
+ this.modelPreloadStatus = "idle";
16862
16873
  if (!saved.enabled) {
16863
16874
  for (const state of this.stateStore.listEnabled()) this.queue.pause(state.dbPathHash);
16864
16875
  }
16876
+ if (saved.enabled && isSemanticIndexConfigured(saved) && saved.mode === "local") {
16877
+ this.modelPreloadStatus = "downloading";
16878
+ void this.getEmbedder().preload?.().then(() => {
16879
+ this.modelPreloadStatus = "ready";
16880
+ }).catch(() => {
16881
+ this.modelPreloadStatus = "error";
16882
+ });
16883
+ }
16865
16884
  return saved;
16866
16885
  }
16867
16886
  currentModelId() {
@@ -16882,13 +16901,24 @@ var SemanticIndexService = class {
16882
16901
  hashFor(sessionId) {
16883
16902
  return computeDbPathHash(sessionId);
16884
16903
  }
16904
+ /**
16905
+ * 查找 sessionId 对应的实际 db_path_hash。
16906
+ * 优先用当前规则(computeDbPathHash(sessionId)),找不到时扫全表匹配 dbPath basename,
16907
+ * 兼容旧版本用完整 dbPath 计算 hash 存储的历史记录。
16908
+ */
16909
+ resolveHash(sessionId) {
16910
+ const hash = this.hashFor(sessionId);
16911
+ if (this.stateStore.getState(hash)) return hash;
16912
+ const legacy = this.stateStore.listAll().find((s) => sessionIdFromDbPath(s.dbPath) === sessionId);
16913
+ return legacy?.dbPathHash ?? hash;
16914
+ }
16885
16915
  /** 索引身份是否与当前运行时不一致(模型身份或 chunker 身份变化 => 需重建) */
16886
16916
  isStale(state, currentModelId) {
16887
16917
  return state.modelId !== currentModelId || state.chunkerVersion !== this.chunkerVersion || state.chunkerConfigHash !== this.chunkerConfigHash;
16888
16918
  }
16889
- enableParams(dbPath) {
16919
+ enableParams(dbPath, dbPathHash) {
16890
16920
  return {
16891
- dbPathHash: computeDbPathHash(sessionIdFromDbPath(dbPath)),
16921
+ dbPathHash: dbPathHash ?? computeDbPathHash(sessionIdFromDbPath(dbPath)),
16892
16922
  dbPath,
16893
16923
  modelId: this.currentModelId(),
16894
16924
  chunkerVersion: this.chunkerVersion,
@@ -16908,29 +16938,31 @@ var SemanticIndexService = class {
16908
16938
  this.stateStore.enable(this.enableParams(dbPath));
16909
16939
  }
16910
16940
  }
16911
- disable(sessionId) {
16912
- const hash = this.hashFor(sessionId);
16941
+ /** 彻底移除:取消队列、删除向量数据、删除状态记录,立即生效无需二次清理 */
16942
+ remove(sessionId) {
16943
+ const hash = this.resolveHash(sessionId);
16913
16944
  this.queue.cancel(hash);
16914
- this.stateStore.disable(hash);
16945
+ this.store.deleteByDbPathHash(hash);
16946
+ this.stateStore.remove(hash);
16915
16947
  }
16916
16948
  /** 建立 / 续跑索引(续跑从断点游标继续) */
16917
16949
  build(sessionId) {
16918
16950
  if (!this.canRun()) return;
16919
- this.queue.enqueue({ type: "build", dbPathHash: this.hashFor(sessionId) });
16951
+ this.queue.enqueue({ type: "build", dbPathHash: this.resolveHash(sessionId) });
16920
16952
  }
16921
16953
  pause(sessionId) {
16922
- this.queue.pause(this.hashFor(sessionId));
16954
+ this.queue.pause(this.resolveHash(sessionId));
16923
16955
  }
16924
16956
  cancel(sessionId) {
16925
- this.queue.cancel(this.hashFor(sessionId));
16957
+ this.queue.cancel(this.resolveHash(sessionId));
16926
16958
  }
16927
16959
  /** 重建:换模型身份或用户主动重建时清空旧索引后重新建立 */
16928
16960
  rebuild(sessionId) {
16929
16961
  if (!this.canRun()) return;
16930
16962
  const dbPath = this.sessionAdapter.getDbPath(sessionId);
16931
- const hash = computeDbPathHash(sessionId);
16963
+ const hash = this.resolveHash(sessionId);
16932
16964
  this.queue.cancel(hash);
16933
- this.stateStore.enable(this.enableParams(dbPath));
16965
+ this.stateStore.enable(this.enableParams(dbPath, hash));
16934
16966
  this.queue.enqueue({ type: "rebuild", dbPathHash: hash });
16935
16967
  }
16936
16968
  /** 为所有启用但未完成 / 需重建的对话入队("建立待处理索引") */
@@ -16978,7 +17010,7 @@ var SemanticIndexService = class {
16978
17010
  };
16979
17011
  }
16980
17012
  status(sessionId) {
16981
- const state = this.stateStore.getState(this.hashFor(sessionId));
17013
+ const state = this.stateStore.getState(this.resolveHash(sessionId));
16982
17014
  if (!state) return null;
16983
17015
  return this.toStatus(state, this.currentModelId());
16984
17016
  }
@@ -16987,7 +17019,7 @@ var SemanticIndexService = class {
16987
17019
  const modelId = this.currentModelId();
16988
17020
  const result = [];
16989
17021
  for (const sessionId of sessionIds) {
16990
- const state = this.stateStore.getState(this.hashFor(sessionId));
17022
+ const state = this.stateStore.getState(this.resolveHash(sessionId));
16991
17023
  if (state) result.push(this.toStatus(state, modelId));
16992
17024
  }
16993
17025
  return result;
@@ -17011,7 +17043,7 @@ var SemanticIndexService = class {
17011
17043
  async search(sessionId, query, options) {
17012
17044
  if (!this.canRun())
17013
17045
  return { available: false, reason: "disabled", blocks: [], coverage: 0, partial: false, hitCount: 0 };
17014
- const hash = this.hashFor(sessionId);
17046
+ const hash = this.resolveHash(sessionId);
17015
17047
  const state = this.stateStore.getState(hash);
17016
17048
  const modelId = this.currentModelId();
17017
17049
  if (!state || !state.enabled)
@@ -17069,7 +17101,7 @@ var SemanticIndexService = class {
17069
17101
  */
17070
17102
  canSearch(sessionId) {
17071
17103
  if (!this.canRun()) return false;
17072
- const hash = this.hashFor(sessionId);
17104
+ const hash = this.resolveHash(sessionId);
17073
17105
  const state = this.stateStore.getState(hash);
17074
17106
  if (!state || !state.enabled) return false;
17075
17107
  const modelId = this.currentModelId();
@@ -17718,4 +17750,4 @@ export {
17718
17750
  createDatabaseManagerAdapter,
17719
17751
  MergeSessionCache
17720
17752
  };
17721
- //# sourceMappingURL=chunk-B2VLK3FB.mjs.map
17753
+ //# sourceMappingURL=chunk-55WR6WKW.mjs.map