chatlab-cli 0.30.2 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/{chat-command-VBDMWOKL.mjs → chat-command-MOETAGU5.mjs} +9 -8
  2. package/dist/{chat-command-VBDMWOKL.mjs.map → chat-command-MOETAGU5.mjs.map} +1 -1
  3. package/dist/{chunk-M2PXDX4G.mjs → chunk-2IXPWPLR.mjs} +168 -77
  4. package/dist/chunk-2IXPWPLR.mjs.map +1 -0
  5. package/dist/{chunk-TCZHG3G7.mjs → chunk-3VMKS7PU.mjs} +44 -5
  6. package/dist/chunk-3VMKS7PU.mjs.map +1 -0
  7. package/dist/{chunk-TEX44HNL.mjs → chunk-7HBVGVOB.mjs} +5 -15
  8. package/dist/chunk-7HBVGVOB.mjs.map +1 -0
  9. package/dist/{chunk-LVEJHB3X.mjs → chunk-DQ45LDKZ.mjs} +512 -98
  10. package/dist/chunk-DQ45LDKZ.mjs.map +1 -0
  11. package/dist/{chunk-ULNRUS55.mjs → chunk-E6W2RURS.mjs} +3 -3
  12. package/dist/{chunk-36JGKW6K.mjs → chunk-KCPGEILH.mjs} +1503 -530
  13. package/dist/chunk-KCPGEILH.mjs.map +1 -0
  14. package/dist/{chunk-WV5GSRQM.mjs → chunk-LJXSUN25.mjs} +5 -15
  15. package/dist/chunk-LJXSUN25.mjs.map +1 -0
  16. package/dist/chunk-N5AGDT7I.mjs +268 -0
  17. package/dist/chunk-N5AGDT7I.mjs.map +1 -0
  18. package/dist/{chunk-D3DPCDII.mjs → chunk-SZEBCNBB.mjs} +193 -79
  19. package/dist/chunk-SZEBCNBB.mjs.map +1 -0
  20. package/dist/{chunk-5EE2EFPE.mjs → chunk-VOVLPSG6.mjs} +29 -52
  21. package/dist/chunk-VOVLPSG6.mjs.map +1 -0
  22. package/dist/chunk-YAQLYL52.mjs +14 -0
  23. package/dist/chunk-YAQLYL52.mjs.map +1 -0
  24. package/dist/{chunk-326OCJOT.mjs → chunk-ZVWUR7ET.mjs} +2 -2
  25. package/dist/cli.mjs +10 -7
  26. package/dist/contacts-worker.mjs +2 -2
  27. package/dist/global-insight-worker.mjs +179 -0
  28. package/dist/global-insight-worker.mjs.map +1 -0
  29. package/dist/{http-L4AMELPZ.mjs → http-M6NHWJZD.mjs} +12 -11
  30. package/dist/{import-WWCSXGVS.mjs → import-SEYHFXS5.mjs} +12 -7
  31. package/dist/index.mjs +13 -12
  32. package/dist/{mcp-A4M3LT5O.mjs → mcp-MIPFYRLV.mjs} +12 -11
  33. package/dist/{mcp-A4M3LT5O.mjs.map → mcp-MIPFYRLV.mjs.map} +1 -1
  34. package/dist/people-relationships-worker.mjs +2 -2
  35. package/dist/semantic-index-worker.mjs +1 -1
  36. package/dist/{src-MPNBTFOE.mjs → src-7OD6RD5V.mjs} +38 -6
  37. package/dist/{stream-import-HIE7PNL4.mjs → stream-import-AWEHGQJY.mjs} +12 -7
  38. package/dist/{worker-runtime-BJXO24XX.mjs → worker-runtime-TGYMASIE.mjs} +6 -5
  39. package/dist/{worker-runtime-BJXO24XX.mjs.map → worker-runtime-TGYMASIE.mjs.map} +1 -1
  40. package/dist-web/assets/ActionToolsPanel-fAio70bI.css +1 -0
  41. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-CkDGVRXe.js +110 -0
  42. package/dist-web/assets/{BufferResource-q3rzaWWd.js → BufferResource-CHI62pIA.js} +1 -1
  43. package/dist-web/assets/{CanvasRenderer-BRk1y8tp.js → CanvasRenderer-OZRoiF0j.js} +1 -1
  44. package/dist-web/assets/{EChartWordcloud-Clg60FMo.js → EChartWordcloud-DU3ZYdgz.js} +1 -1
  45. package/dist-web/assets/{Filter-BJwode73.js → Filter-DNb5VErW.js} +1 -1
  46. package/dist-web/assets/{LoadingState.vue_vue_type_script_setup_true_lang-D_dJuLWJ.js → LoadingState.vue_vue_type_script_setup_true_lang-DACMroOe.js} +1 -1
  47. package/dist-web/assets/MessageExportModal-CqP-w7HP.js +1 -0
  48. package/dist-web/assets/PageHeader-Ck8ULyZH.js +1 -0
  49. package/dist-web/assets/PageHeader-XIXMTomn.css +1 -0
  50. package/dist-web/assets/{RelationshipGalaxyCanvas-CORMD7vL.js → RelationshipGalaxyCanvas-ioRNObb5.js} +3 -3
  51. package/dist-web/assets/{RelationshipGalaxyThreeCanvas-B_w_P4ob.js → RelationshipGalaxyThreeCanvas-L1Y43p1A.js} +1 -1
  52. package/dist-web/assets/{RenderTargetSystem-CGhV9R9E.js → RenderTargetSystem-fJ7D7Chv.js} +1 -1
  53. package/dist-web/assets/ThemeCard.vue_vue_type_script_setup_true_lang-BoZyssJF.js +1 -0
  54. package/dist-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-7SEaCxDL.js +1 -0
  55. package/dist-web/assets/{WebGLRenderer-CAokTE5X.js → WebGLRenderer-BD3ZUtxH.js} +1 -1
  56. package/dist-web/assets/{WebGPURenderer-DzP4ggSy.js → WebGPURenderer-DZXYsT6D.js} +1 -1
  57. package/dist-web/assets/annual-summary-time-range-DVLXK1r4.js +1 -0
  58. package/dist-web/assets/base-DTElkJcC.js +1 -0
  59. package/dist-web/assets/{browserAll-CAZCK6dd.js → browserAll-ChT6N6a9.js} +1 -1
  60. package/dist-web/assets/dateFormat-D9WibwOu.js +1 -0
  61. package/dist-web/assets/{electron-CkPDbAaS.js → electron-CIzyGxH_.js} +1 -1
  62. package/dist-web/assets/electron-hcWiB7Gg.js +1 -0
  63. package/dist-web/assets/fetch-Avtnh8cJ.js +3 -0
  64. package/dist-web/assets/{fetch-DQ9UNNAy.js → fetch-BFnrBahy.js} +1 -1
  65. package/dist-web/assets/fetch-C9rx2isC.js +31 -0
  66. package/dist-web/assets/fetch-Ccq_0ecb.js +1 -0
  67. package/dist-web/assets/{fetch-BIEXkvDq.js → fetch-CuiQUcO_.js} +1 -1
  68. package/dist-web/assets/{fetch-LX9jrJCC.js → fetch-CyKILLnB.js} +1 -1
  69. package/dist-web/assets/fetch-Dd6t3p1r.js +6 -0
  70. package/dist-web/assets/{fetch--UbRoBT7.js → fetch-DnGx-1_t.js} +1 -1
  71. package/dist-web/assets/{fetch-wqMSiaK3.js → fetch-qC7om4QG.js} +1 -1
  72. package/dist-web/assets/fetch-wSSfDBdV.js +1 -0
  73. package/dist-web/assets/index-BH9jI5kV.js +173 -0
  74. package/dist-web/assets/index-BWtNqcYK.js +22 -0
  75. package/dist-web/assets/index-BfO_LpDv.css +1 -0
  76. package/dist-web/assets/index-Bkq7-GBp.js +1 -0
  77. package/dist-web/assets/index-Bqr-LkS1.css +1 -0
  78. package/dist-web/assets/index-ByUaiVQK.css +1 -0
  79. package/dist-web/assets/index-C6qtsaP7.js +1 -0
  80. package/dist-web/assets/index-C_0GHEcb.css +1 -0
  81. package/dist-web/assets/index-ChFGuu70.js +1 -0
  82. package/dist-web/assets/{index-S-YQRH1E.js → index-CiS20iAR.js} +1 -1
  83. package/dist-web/assets/index-CqD6u57u.js +1 -0
  84. package/dist-web/assets/index-CzDG8LVr.js +2 -0
  85. package/dist-web/assets/index-D0Euk-vQ.js +1 -0
  86. package/dist-web/assets/index-D26BWhHz.js +1 -0
  87. package/dist-web/assets/index-DXHYzIIj.js +1 -0
  88. package/dist-web/assets/index-Dq8u7gMb.js +2 -0
  89. package/dist-web/assets/index-ZsZwPLWy.css +1 -0
  90. package/dist-web/assets/index-u_UH6rDY.js +64 -0
  91. package/dist-web/assets/index-y7cxH1Et.css +1 -0
  92. package/dist-web/assets/{people-page-header-Mupn-U_b.js → people-page-header-BdKM1qhX.js} +1 -1
  93. package/dist-web/assets/types-CZnACqaB.js +1 -0
  94. package/dist-web/assets/{vendor-echarts-hJVnODyU.js → vendor-echarts-B-i_56Av.js} +1 -1
  95. package/dist-web/assets/{vendor-echarts-wordcloud-k5ih2Jl4.js → vendor-echarts-wordcloud-Ca8n6qS6.js} +1 -1
  96. package/dist-web/assets/{vendor-nuxt-ui-DaLxYaC4.js → vendor-nuxt-ui-CS1uxE9C.js} +2 -2
  97. package/dist-web/assets/{vendor-reka-ui-CzM4kDQ7.js → vendor-reka-ui-Cta6JPvN.js} +1 -1
  98. package/dist-web/assets/{web-DbKs6-1b.js → web-BDBdpdK7.js} +1 -1
  99. package/dist-web/assets/{webworkerAll-Bhv-hBqR.js → webworkerAll-C3dAOQj4.js} +1 -1
  100. package/dist-web/index.html +4 -4
  101. package/package.json +1 -1
  102. package/dist/chunk-36JGKW6K.mjs.map +0 -1
  103. package/dist/chunk-5EE2EFPE.mjs.map +0 -1
  104. package/dist/chunk-D3DPCDII.mjs.map +0 -1
  105. package/dist/chunk-KBSAVUFV.mjs +0 -161
  106. package/dist/chunk-KBSAVUFV.mjs.map +0 -1
  107. package/dist/chunk-LVEJHB3X.mjs.map +0 -1
  108. package/dist/chunk-M2PXDX4G.mjs.map +0 -1
  109. package/dist/chunk-TCZHG3G7.mjs.map +0 -1
  110. package/dist/chunk-TEX44HNL.mjs.map +0 -1
  111. package/dist/chunk-WV5GSRQM.mjs.map +0 -1
  112. package/dist-web/assets/DebugToolsPanel-D_lFIW6j.css +0 -1
  113. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-F4n0zNX2.js +0 -110
  114. package/dist-web/assets/MessageExportModal-CGcdMOyw.js +0 -1
  115. package/dist-web/assets/PageHeader-Bbn87QZS.css +0 -1
  116. package/dist-web/assets/PageHeader-CZaqOdBQ.js +0 -1
  117. package/dist-web/assets/electron-D9vE5t3H.js +0 -1
  118. package/dist-web/assets/fetch-1pB-HbYw.js +0 -3
  119. package/dist-web/assets/fetch-Apd5OLJw.js +0 -5
  120. package/dist-web/assets/fetch-B8rik0TM.js +0 -17
  121. package/dist-web/assets/fetch-CF_3ZqRa.js +0 -1
  122. package/dist-web/assets/fetch-FSNxSnAp.js +0 -1
  123. package/dist-web/assets/index---rXG1hZ.css +0 -1
  124. package/dist-web/assets/index-B01uUoHE.js +0 -1
  125. package/dist-web/assets/index-B4l3rHie.css +0 -1
  126. package/dist-web/assets/index-BSIyyt0z.js +0 -1
  127. package/dist-web/assets/index-Bh8z441f.js +0 -2
  128. package/dist-web/assets/index-C0rya8v4.js +0 -1
  129. package/dist-web/assets/index-C1p9CbmN.css +0 -1
  130. package/dist-web/assets/index-COpza1A4.css +0 -1
  131. package/dist-web/assets/index-CZbZv2fh.js +0 -64
  132. package/dist-web/assets/index-CqUuHQBQ.js +0 -22
  133. package/dist-web/assets/index-CzeTP5MJ.js +0 -173
  134. package/dist-web/assets/index-DgNxTM_8.js +0 -2
  135. package/dist-web/assets/index-DosG7LmJ.css +0 -1
  136. /package/dist/{chunk-ULNRUS55.mjs.map → chunk-E6W2RURS.mjs.map} +0 -0
  137. /package/dist/{chunk-326OCJOT.mjs.map → chunk-ZVWUR7ET.mjs.map} +0 -0
  138. /package/dist/{http-L4AMELPZ.mjs.map → http-M6NHWJZD.mjs.map} +0 -0
  139. /package/dist/{import-WWCSXGVS.mjs.map → import-SEYHFXS5.mjs.map} +0 -0
  140. /package/dist/{src-MPNBTFOE.mjs.map → src-7OD6RD5V.mjs.map} +0 -0
  141. /package/dist/{stream-import-HIE7PNL4.mjs.map → stream-import-AWEHGQJY.mjs.map} +0 -0
@@ -4,31 +4,29 @@ import { fileURLToPath as __fileURLToPath } from 'url';
4
4
  const require = __createRequire(import.meta.url);
5
5
  const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
- import {
8
- analyzeIncrementalImport,
9
- analyzeNewImport,
10
- incrementalImport,
11
- streamImport
12
- } from "./chunk-KBSAVUFV.mjs";
13
7
  import {
14
8
  closeServerAiLogger,
15
9
  createCliRunAgentStream,
16
10
  getServerAiLogger,
17
11
  initServerAiLogger
18
- } from "./chunk-5EE2EFPE.mjs";
12
+ } from "./chunk-VOVLPSG6.mjs";
19
13
  import {
20
14
  AGENT_TOOL_REGISTRY,
21
15
  CoreDataProvider
22
- } from "./chunk-TCZHG3G7.mjs";
16
+ } from "./chunk-3VMKS7PU.mjs";
17
+ import {
18
+ analyzeIncrementalImport,
19
+ analyzeNewImport,
20
+ autoImport,
21
+ incrementalImport,
22
+ streamImport
23
+ } from "./chunk-N5AGDT7I.mjs";
23
24
  import {
24
25
  assertCliDataDirCompatible
25
- } from "./chunk-326OCJOT.mjs";
26
+ } from "./chunk-ZVWUR7ET.mjs";
26
27
  import {
27
28
  getVersion
28
29
  } from "./chunk-5ADKYYNA.mjs";
29
- import {
30
- resolveCliPath
31
- } from "./chunk-FJ35V3TE.mjs";
32
30
  import {
33
31
  AnalyticsService,
34
32
  NodePathProvider,
@@ -43,7 +41,7 @@ import {
43
41
  getPendingNodeDataDirMigration,
44
42
  hasPendingElectronDataWarning,
45
43
  serializeChatLabToJsonl
46
- } from "./chunk-ULNRUS55.mjs";
44
+ } from "./chunk-E6W2RURS.mjs";
47
45
  import {
48
46
  AIChatManager,
49
47
  ArchiveImportError,
@@ -51,6 +49,9 @@ import {
51
49
  AssistantManager,
52
50
  CustomModelStore,
53
51
  CustomProviderStore,
52
+ IMPORT_IN_PROGRESS_ERROR_KEY,
53
+ ImportIdempotencyCache,
54
+ ImportInProgressError,
54
55
  LLMConfigStore,
55
56
  MergeSessionCache,
56
57
  SEMANTIC_INDEX_CONFIG_FILE,
@@ -61,6 +62,7 @@ import {
61
62
  computeWordFrequency,
62
63
  countMessagesTokens,
63
64
  createContactsService,
65
+ createGlobalInsightService,
64
66
  createPeopleRelationshipsService,
65
67
  deleteDict,
66
68
  detectAllFormats,
@@ -74,6 +76,7 @@ import {
74
76
  getDefaultRulesForLocale,
75
77
  getDictList,
76
78
  getSupportedFormats,
79
+ hashImportBody,
77
80
  isDictDownloaded,
78
81
  isSemanticIndexConfigured,
79
82
  logNativeParserStatus,
@@ -91,7 +94,10 @@ import {
91
94
  streamParseFileInfo,
92
95
  summary_service_exports,
93
96
  validateApiKey
94
- } from "./chunk-36JGKW6K.mjs";
97
+ } from "./chunk-KCPGEILH.mjs";
98
+ import {
99
+ resolveCliPath
100
+ } from "./chunk-FJ35V3TE.mjs";
95
101
  import {
96
102
  ALL_MIGRATIONS,
97
103
  BUILTIN_MODELS,
@@ -154,7 +160,7 @@ import {
154
160
  verifyCliDataPath,
155
161
  writeAuthProfile,
156
162
  writeConfigField
157
- } from "./chunk-LVEJHB3X.mjs";
163
+ } from "./chunk-DQ45LDKZ.mjs";
158
164
 
159
165
  // src/http/index.ts
160
166
  import * as fs12 from "fs";
@@ -174,6 +180,8 @@ var HTTP_STATUS = {
174
180
  ["EXPORT_TOO_LARGE" /* EXPORT_TOO_LARGE */]: 400,
175
181
  ["BODY_TOO_LARGE" /* BODY_TOO_LARGE */]: 413,
176
182
  ["IMPORT_IN_PROGRESS" /* IMPORT_IN_PROGRESS */]: 409,
183
+ ["IDEMPOTENCY_CONFLICT" /* IDEMPOTENCY_CONFLICT */]: 409,
184
+ ["IDEMPOTENCY_PENDING" /* IDEMPOTENCY_PENDING */]: 409,
177
185
  ["IMPORT_FAILED" /* IMPORT_FAILED */]: 500,
178
186
  ["DATA_DIR_INCOMPATIBLE" /* DATA_DIR_INCOMPATIBLE */]: 409,
179
187
  ["SERVER_ERROR" /* SERVER_ERROR */]: 500
@@ -212,6 +220,15 @@ function serverError(message = "Internal server error") {
212
220
  function importInProgress() {
213
221
  return new ApiError("IMPORT_IN_PROGRESS" /* IMPORT_IN_PROGRESS */, "Another import is already in progress");
214
222
  }
223
+ function idempotencyConflict() {
224
+ return new ApiError("IDEMPOTENCY_CONFLICT" /* IDEMPOTENCY_CONFLICT */, "Same Idempotency-Key with different request body hash");
225
+ }
226
+ function idempotencyPending() {
227
+ return new ApiError(
228
+ "IDEMPOTENCY_PENDING" /* IDEMPOTENCY_PENDING */,
229
+ "A request with this Idempotency-Key is still in progress. Please retry later."
230
+ );
231
+ }
215
232
  function importFailed(message) {
216
233
  return new ApiError("IMPORT_FAILED" /* IMPORT_FAILED */, message);
217
234
  }
@@ -220,6 +237,7 @@ function dataDirIncompatible(message) {
220
237
  }
221
238
  function apiErrorFromUnknown(error) {
222
239
  if (error instanceof ApiError) return error;
240
+ if (error instanceof ImportInProgressError) return importInProgress();
223
241
  if (error instanceof DataDirCompatibilityError) return dataDirIncompatible(error.message);
224
242
  return null;
225
243
  }
@@ -488,6 +506,7 @@ function registerRestSessionRoutes(server2, ctx) {
488
506
 
489
507
  // ../../packages/http-routes/src/routes/imports.ts
490
508
  function registerImportRoutes(server2, ctx) {
509
+ const idempotencyCache = new ImportIdempotencyCache();
491
510
  server2.post(
492
511
  "/api/v1/imports/:sessionId",
493
512
  async (request, reply) => {
@@ -501,20 +520,42 @@ function registerImportRoutes(server2, ctx) {
501
520
  const err = invalidPayload("X-Dry-Run is not yet supported");
502
521
  return reply.code(err.statusCode).send(errorResponse(err));
503
522
  }
504
- const outcome = await pushImport(ctx.dbManager, sessionId, request.body ?? {});
505
- if (!outcome.ok) {
506
- if (outcome.reason === "import_in_progress") {
507
- const err2 = importInProgress();
508
- return reply.code(err2.statusCode).send(errorResponse(err2));
523
+ const idempotencyKey = request.headers["idempotency-key"];
524
+ const cacheKey = typeof idempotencyKey === "string" && idempotencyKey ? `${idempotencyKey}:${sessionId}` : null;
525
+ if (cacheKey) {
526
+ const start = idempotencyCache.start(cacheKey, hashImportBody(request.body));
527
+ if (start.status === "conflict") {
528
+ const err = idempotencyConflict();
529
+ return reply.code(err.statusCode).send(errorResponse(err));
509
530
  }
510
- if (outcome.reason === "invalid_payload") {
511
- const err2 = invalidPayload(outcome.message);
512
- return reply.code(err2.statusCode).send(errorResponse(err2));
531
+ if (start.status === "pending") {
532
+ const err = idempotencyPending();
533
+ return reply.code(err.statusCode).send(errorResponse(err));
513
534
  }
514
- const err = importFailed(outcome.message);
515
- return reply.code(err.statusCode).send(errorResponse(err));
535
+ if (start.status === "success") return start.response;
536
+ }
537
+ try {
538
+ const outcome = await pushImport(ctx.dbManager, sessionId, request.body ?? {});
539
+ if (!outcome.ok) {
540
+ if (cacheKey) idempotencyCache.fail(cacheKey);
541
+ if (outcome.reason === "import_in_progress") {
542
+ const err2 = importInProgress();
543
+ return reply.code(err2.statusCode).send(errorResponse(err2));
544
+ }
545
+ if (outcome.reason === "invalid_payload") {
546
+ const err2 = invalidPayload(outcome.message);
547
+ return reply.code(err2.statusCode).send(errorResponse(err2));
548
+ }
549
+ const err = importFailed(outcome.message);
550
+ return reply.code(err.statusCode).send(errorResponse(err));
551
+ }
552
+ const response = successResponse(outcome.result);
553
+ if (cacheKey) idempotencyCache.success(cacheKey, response);
554
+ return response;
555
+ } catch (error) {
556
+ if (cacheKey) idempotencyCache.fail(cacheKey);
557
+ throw error;
516
558
  }
517
- return successResponse(outcome.result);
518
559
  }
519
560
  );
520
561
  }
@@ -748,6 +789,43 @@ function parsePeopleRelationshipsGraphScope(value) {
748
789
  return value === "close" || value === "friends" ? value : "panorama";
749
790
  }
750
791
 
792
+ // ../../packages/http-routes/src/routes/web/global-insight.ts
793
+ function registerGlobalInsightRoutes(server2, ctx) {
794
+ const service = ctx.globalInsightService ?? createGlobalInsightService({
795
+ adapter: ctx.sessionAdapter,
796
+ pathProvider: ctx.pathProvider,
797
+ runtimeIdentity: ctx.runtimeIdentity,
798
+ nativeBinding: ctx.nativeBinding
799
+ });
800
+ server2.addHook("onClose", async () => service.close());
801
+ server2.get("/_web/global-insight/annual-summary", async (request) => {
802
+ return service.getAnnualSummary({
803
+ ...parseRange(request.query),
804
+ acceptStale: isTruthy3(request.query.acceptStale)
805
+ });
806
+ });
807
+ server2.post(
808
+ "/_web/global-insight/annual-summary/recompute",
809
+ async (request) => service.startRecompute(parseRange(request.query))
810
+ );
811
+ }
812
+ function parseRange(query) {
813
+ const mode = query.mode === "recent" ? "recent" : "year";
814
+ return {
815
+ mode,
816
+ year: parseInteger(query.year),
817
+ days: query.days === "365" ? 365 : void 0
818
+ };
819
+ }
820
+ function parseInteger(value) {
821
+ if (!value) return void 0;
822
+ const parsed = Number(value);
823
+ return Number.isInteger(parsed) ? parsed : void 0;
824
+ }
825
+ function isTruthy3(value) {
826
+ return value === "1" || value === "true" || value === "yes";
827
+ }
828
+
751
829
  // ../../packages/http-routes/src/routes/web/preferences.ts
752
830
  function registerPreferencesRoutes(server2, ctx) {
753
831
  const prefManager = ctx.preferencesManager ?? new PreferencesManager(ctx.pathProvider.getSystemDir());
@@ -1570,8 +1648,55 @@ data: ${JSON.stringify(data)}
1570
1648
  });
1571
1649
  }
1572
1650
 
1573
- // ../../packages/http-routes/src/routes/web/ai-tools.ts
1651
+ // ../../packages/http-routes/src/ai/tool-executor.ts
1574
1652
  var MAX_RESULT_CHARS = 5e5;
1653
+ async function executeRegistryTool(params, deps) {
1654
+ const { toolName, params: toolParams, abortSignal } = params;
1655
+ const entry = AGENT_TOOL_REGISTRY.find((tool) => tool.name === toolName);
1656
+ if (!entry) {
1657
+ return { success: false, error: `Tool not found: ${toolName}` };
1658
+ }
1659
+ try {
1660
+ if (abortSignal.aborted) return { success: false, error: "cancelled" };
1661
+ const execCtx = {
1662
+ sessionId: params.sessionId,
1663
+ abortSignal,
1664
+ db: deps.db,
1665
+ dataProvider: deps.dataProvider,
1666
+ semanticIndexService: deps.semanticIndexService,
1667
+ segmentText: deps.segmentText,
1668
+ translateTemplate: deps.translateTemplate
1669
+ };
1670
+ const startTime = Date.now();
1671
+ const result = await entry.handler(toolParams, execCtx);
1672
+ const elapsed = Date.now() - startTime;
1673
+ if (abortSignal.aborted) return { success: false, error: "cancelled" };
1674
+ let details = result.data ?? void 0;
1675
+ let truncated = false;
1676
+ if (details) {
1677
+ stripAvatarFields(details);
1678
+ const raw = JSON.stringify(details);
1679
+ if (raw.length > MAX_RESULT_CHARS) {
1680
+ truncated = true;
1681
+ details = { _truncated: true, _originalSize: raw.length, _preview: raw.slice(0, MAX_RESULT_CHARS) };
1682
+ }
1683
+ }
1684
+ return {
1685
+ success: true,
1686
+ elapsed,
1687
+ content: [{ type: "text", text: result.content }],
1688
+ details,
1689
+ truncated
1690
+ };
1691
+ } catch (error) {
1692
+ if (abortSignal.aborted) {
1693
+ return { success: false, error: "cancelled" };
1694
+ }
1695
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
1696
+ }
1697
+ }
1698
+
1699
+ // ../../packages/http-routes/src/routes/web/ai-tools.ts
1575
1700
  var activeToolTests = /* @__PURE__ */ new Map();
1576
1701
  function registerAiToolRoutes(server2, ctx) {
1577
1702
  server2.get("/_web/ai/tools/full-catalog", async () => {
@@ -1598,40 +1723,22 @@ function registerAiToolRoutes(server2, ctx) {
1598
1723
  if (!db) {
1599
1724
  return reply.code(404).send({ success: false, error: `Session not found: ${sessionId}` });
1600
1725
  }
1601
- const execCtx = {
1602
- sessionId,
1603
- db,
1604
- dataProvider: new CoreDataProvider(db),
1605
- abortSignal: abortController.signal
1606
- };
1607
- const startTime = Date.now();
1608
- const result = await entry.handler(params, execCtx);
1609
- const elapsed = Date.now() - startTime;
1610
- if (abortController.signal.aborted) {
1611
- return { success: false, error: "cancelled" };
1612
- }
1613
- let details = result.data ?? void 0;
1614
- let truncated = false;
1615
- if (details) {
1616
- stripAvatarFields(details);
1617
- const raw = JSON.stringify(details);
1618
- if (raw.length > MAX_RESULT_CHARS) {
1619
- truncated = true;
1620
- details = { _truncated: true, _originalSize: raw.length, _preview: raw.slice(0, MAX_RESULT_CHARS) };
1726
+ const result = await executeRegistryTool(
1727
+ { testId, toolName, params, sessionId, abortSignal: abortController.signal },
1728
+ {
1729
+ db,
1730
+ dataProvider: new CoreDataProvider(db)
1621
1731
  }
1732
+ );
1733
+ if (!result.success && result.error !== "cancelled") {
1734
+ appLogger.error("ai-tools", `Failed to execute tool ${toolName}`, { error: result.error });
1622
1735
  }
1623
- return {
1624
- success: true,
1625
- elapsed,
1626
- content: [{ type: "text", text: result.content }],
1627
- details,
1628
- truncated
1629
- };
1736
+ return result;
1630
1737
  } catch (error) {
1631
1738
  if (abortController.signal.aborted) {
1632
1739
  return { success: false, error: "cancelled" };
1633
1740
  }
1634
- console.error(`Failed to execute tool ${toolName}:`, error);
1741
+ appLogger.error("ai-tools", `Failed to execute tool ${toolName}`, error);
1635
1742
  return { success: false, error: String(error) };
1636
1743
  } finally {
1637
1744
  activeToolTests.delete(testId);
@@ -2416,6 +2523,7 @@ function registerSharedRoutes(server2, ctx, options) {
2416
2523
  registerMemberRoutes(server2, resolvedCtx);
2417
2524
  registerContactsRoutes(server2, resolvedCtx);
2418
2525
  registerPeopleRelationshipsRoutes(server2, resolvedCtx);
2526
+ registerGlobalInsightRoutes(server2, resolvedCtx);
2419
2527
  registerPreferencesRoutes(server2, resolvedCtx);
2420
2528
  registerAnalyticsRoutes(server2, resolvedCtx);
2421
2529
  registerSqlRoutes(server2, resolvedCtx);
@@ -2710,19 +2818,14 @@ function registerImportRoutes2(server2, dbManager2, options = {}) {
2710
2818
  const sourceManager = options.sourceManager ?? new ArchiveImportSourceManager({
2711
2819
  tempRoot: fs7.mkdtempSync(path8.join(os2.tmpdir(), "chatlab-import-sources-"))
2712
2820
  });
2821
+ const runAutoImport = options.runAutoImport ?? autoImport.bind(null, dbManager2);
2713
2822
  const runPreparedImport = options.runPreparedImport ?? (async (manifestPath, onProgress) => {
2714
- const result = await streamImport(dbManager2, manifestPath, {
2823
+ const result = await runAutoImport(manifestPath, {
2715
2824
  formatId: "google-chat-takeout",
2716
2825
  nativeBinding: resolveNativeBinding(),
2717
2826
  onProgress
2718
2827
  });
2719
- return {
2720
- success: result.success,
2721
- sessionId: result.sessionId,
2722
- error: result.error,
2723
- messageCount: result.diagnostics?.messagesWritten ?? 0,
2724
- memberCount: 0
2725
- };
2828
+ return result;
2726
2829
  });
2727
2830
  server2.addHook("onClose", async () => {
2728
2831
  await sourceManager.close();
@@ -2857,19 +2960,14 @@ data: ${JSON.stringify(eventData)}
2857
2960
  }
2858
2961
  try {
2859
2962
  const nativeBinding = resolveNativeBinding();
2860
- const result = await streamImport(dbManager2, tmpPath, {
2963
+ const result = await runAutoImport(tmpPath, {
2861
2964
  formatId,
2862
2965
  chatIndex,
2863
2966
  nativeBinding,
2864
2967
  onProgress: (p) => sendEvent("progress", p)
2865
2968
  });
2866
2969
  if (result.success) {
2867
- sendEvent("done", {
2868
- success: true,
2869
- sessionId: result.sessionId,
2870
- messageCount: result.diagnostics?.messagesWritten ?? 0,
2871
- memberCount: 0
2872
- });
2970
+ sendEvent("done", result);
2873
2971
  } else {
2874
2972
  sendEvent("error", { success: false, error: result.error });
2875
2973
  }
@@ -2926,17 +3024,12 @@ data: ${JSON.stringify(eventData)}
2926
3024
  Connection: "keep-alive"
2927
3025
  });
2928
3026
  const nativeBinding = resolveNativeBinding();
2929
- const result = await streamImport(dbManager2, entryPath, {
3027
+ const result = await runAutoImport(entryPath, {
2930
3028
  nativeBinding,
2931
3029
  onProgress: (p) => sendEvent2("progress", p)
2932
3030
  });
2933
3031
  if (result.success) {
2934
- sendEvent2("done", {
2935
- success: true,
2936
- sessionId: result.sessionId,
2937
- messageCount: result.diagnostics?.messagesWritten ?? 0,
2938
- memberCount: 0
2939
- });
3032
+ sendEvent2("done", result);
2940
3033
  } else {
2941
3034
  sendEvent2("error", { success: false, error: result.error });
2942
3035
  }
@@ -3157,8 +3250,13 @@ function registerWebRoutes(server2, dbManager2, options) {
3157
3250
  const resolvedPathProvider = options?.pathProvider ?? fallbackPathProvider;
3158
3251
  const ai = options?.aiContext;
3159
3252
  const cliStreamImport = async (dm, filePath) => {
3160
- const { streamImport: streamImport2 } = await import("./stream-import-HIE7PNL4.mjs");
3253
+ const { streamImport: streamImport2 } = await import("./stream-import-AWEHGQJY.mjs");
3161
3254
  const result = await streamImport2(dm, filePath);
3255
+ if (!result.success) {
3256
+ const { IMPORT_IN_PROGRESS_ERROR_KEY: IMPORT_IN_PROGRESS_ERROR_KEY2, ImportInProgressError: ImportInProgressError2 } = await import("./src-7OD6RD5V.mjs");
3257
+ if (result.error === IMPORT_IN_PROGRESS_ERROR_KEY2) throw new ImportInProgressError2();
3258
+ throw new Error(result.error || "Import failed");
3259
+ }
3162
3260
  if (!result.sessionId) throw new Error("Import succeeded but no sessionId returned");
3163
3261
  return { sessionId: result.sessionId };
3164
3262
  };
@@ -3652,6 +3750,12 @@ var PullEngine = class {
3652
3750
  const externalId = deriveLocalSessionId(baseUrl, sess.remoteSessionId);
3653
3751
  return this.importer.importFile(tempFile, targetId || void 0, externalId);
3654
3752
  }
3753
+ deferRetryableImport(sess, error) {
3754
+ const errMsg = error || "Import deferred";
3755
+ this.logger.info(`[Pull] Deferring "${sess.name}": ${errMsg}`);
3756
+ this.markProgressDone(sess.id);
3757
+ return { success: false, newMessageCount: 0, error: errMsg };
3758
+ }
3655
3759
  async executePullSession(sourceId, ds, sess) {
3656
3760
  const currentDs = this.dsManager.get(sourceId);
3657
3761
  if (!currentDs || !currentDs.sessions.some((s) => s.id === sess.id)) {
@@ -3737,6 +3841,7 @@ var PullEngine = class {
3737
3841
  return { success: false, newMessageCount: 0, error: errMsg };
3738
3842
  }
3739
3843
  if (!retryResult.success) {
3844
+ if (retryResult.retryable) return this.deferRetryableImport(sess, retryResult.error);
3740
3845
  const errMsg = retryResult.error || "Import failed";
3741
3846
  this.dsManager.updateSession(sourceId, sess.id, {
3742
3847
  lastPullAt: Math.floor(Date.now() / 1e3),
@@ -3809,6 +3914,7 @@ var PullEngine = class {
3809
3914
  return { success: false, newMessageCount: 0, error: errMsg };
3810
3915
  }
3811
3916
  if (!result.success) {
3917
+ if (result.retryable) return this.deferRetryableImport(sess, result.error);
3812
3918
  const errMsg = result.error || "Import failed";
3813
3919
  this.dsManager.updateSession(sourceId, sess.id, {
3814
3920
  lastPullAt: Math.floor(Date.now() / 1e3),
@@ -4132,6 +4238,10 @@ var DirectImporter = class {
4132
4238
  if (result.error === "error.session_not_found" || result.error?.includes("no such table")) {
4133
4239
  return { success: false, newMessageCount: 0, sessionId, needFullResync: true };
4134
4240
  }
4241
+ if (result.error === IMPORT_IN_PROGRESS_ERROR_KEY) {
4242
+ this.logger.info(`[DirectImporter] Incremental import deferred: another import is in progress`);
4243
+ return { success: false, newMessageCount: 0, sessionId, error: result.error, retryable: true };
4244
+ }
4135
4245
  return { success: false, newMessageCount: 0, sessionId, error: result.error };
4136
4246
  } catch (err) {
4137
4247
  this.logger.error(`[DirectImporter] Incremental import failed`, err);
@@ -4146,6 +4256,10 @@ var DirectImporter = class {
4146
4256
  this.logger.info(`[DirectImporter] Full import OK: +${newMessageCount} messages`);
4147
4257
  return { success: true, newMessageCount, sessionId: result.sessionId ?? externalId };
4148
4258
  }
4259
+ if (result.error === IMPORT_IN_PROGRESS_ERROR_KEY) {
4260
+ this.logger.info(`[DirectImporter] Full import deferred: another import is in progress`);
4261
+ return { success: false, newMessageCount: 0, error: result.error, retryable: true };
4262
+ }
4149
4263
  return { success: false, newMessageCount: 0, error: result.error };
4150
4264
  } catch (err) {
4151
4265
  this.logger.error(`[DirectImporter] Full import failed`, err);
@@ -4383,4 +4497,4 @@ export {
4383
4497
  startHttpServer,
4384
4498
  stopHttpServer
4385
4499
  };
4386
- //# sourceMappingURL=chunk-D3DPCDII.mjs.map
4500
+ //# sourceMappingURL=chunk-SZEBCNBB.mjs.map