chatlab-cli 0.34.2 → 0.35.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.
- package/dist/{chat-command-6IOH2QRF.mjs → chat-command-24RYGJAS.mjs} +8 -8
- package/dist/{chunk-INBJ7SND.mjs → chunk-22YJOBA3.mjs} +589 -513
- package/dist/chunk-22YJOBA3.mjs.map +1 -0
- package/dist/{chunk-4LW6443F.mjs → chunk-4GWWKHWA.mjs} +833 -886
- package/dist/chunk-4GWWKHWA.mjs.map +1 -0
- package/dist/{chunk-MENKFEPC.mjs → chunk-7IGBPZMI.mjs} +56 -48
- package/dist/chunk-7IGBPZMI.mjs.map +1 -0
- package/dist/{chunk-72RWABYJ.mjs → chunk-BRZ6YIBR.mjs} +3 -3
- package/dist/chunk-BRZ6YIBR.mjs.map +1 -0
- package/dist/{chunk-2XCNTG4O.mjs → chunk-DC7IUDNV.mjs} +677 -69
- package/dist/chunk-DC7IUDNV.mjs.map +1 -0
- package/dist/{chunk-H6D4DZOC.mjs → chunk-DEFEU567.mjs} +12 -18
- package/dist/chunk-DEFEU567.mjs.map +1 -0
- package/dist/{chunk-4RLZFGO5.mjs → chunk-GQMCDWZQ.mjs} +2 -2
- package/dist/{chunk-52P5ZRBD.mjs → chunk-KIMJXKZO.mjs} +2 -2
- package/dist/{chunk-652KEAX3.mjs → chunk-KXDJ7N6N.mjs} +2 -2
- package/dist/{chunk-U6MVJSXX.mjs → chunk-QKEARRFH.mjs} +15 -9
- package/dist/chunk-QKEARRFH.mjs.map +1 -0
- package/dist/{chunk-UMBEHBIZ.mjs → chunk-U36TQMAF.mjs} +2 -2
- package/dist/{chunk-JX6MFS6F.mjs → chunk-ZBPPLXM4.mjs} +15 -15
- package/dist/cli.mjs +9 -9
- package/dist/contacts-worker.mjs +2 -2
- package/dist/global-insight-worker.mjs +1 -1
- package/dist/{http-HSK46XEU.mjs → http-3K4YMWDE.mjs} +12 -12
- package/dist/{import-DF2WD2HE.mjs → import-D4LV565A.mjs} +7 -7
- package/dist/index.mjs +12 -12
- package/dist/{mcp-A2RND7KN.mjs → mcp-KL22FKQ2.mjs} +8 -8
- package/dist/people-relationships-worker.mjs +2 -2
- package/dist/semantic-index-worker.mjs +1 -1
- package/dist/{src-SHFHW2QB.mjs → src-COIB6Z4P.mjs} +24 -38
- package/dist/{stream-import-GZ2QDE3Z.mjs → stream-import-FSXCFG4M.mjs} +7 -7
- package/dist/{worker-runtime-OWN56GG5.mjs → worker-runtime-DPS2LURI.mjs} +5 -5
- package/dist-cli-web/assets/AISettingsTab-rQC2ocFH.js +1 -0
- package/dist-cli-web/assets/AboutTab-DMPziKjj.js +1 -0
- package/dist-cli-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-CnRLt_1j.js +110 -0
- package/dist-cli-web/assets/Alert--bTQXRcZ.js +1 -0
- package/dist-cli-web/assets/ApiSettingsTab-CtXl4I28.js +2 -0
- package/dist-cli-web/assets/BatchManageTab-1KaCPweN.js +1 -0
- package/dist-cli-web/assets/{BufferResource-BdKXeRZS.js → BufferResource-BXSJADxx.js} +1 -1
- package/dist-cli-web/assets/CanvasRenderer-Cq--8UQ_.js +1 -0
- package/dist-cli-web/assets/ChatRecordDrawer-BC0F7ok1.js +11 -0
- package/dist-cli-web/assets/ChatRecordDrawer-Tt6UduRC.css +1 -0
- package/dist-cli-web/assets/Checkbox-CwajNPGF.js +1 -0
- package/dist-cli-web/assets/DataDirCleanupNotice-D0Oruka2.js +1 -0
- package/dist-cli-web/assets/DatePicker.vue_vue_type_script_setup_true_lang-C4CsoIlq.js +1 -0
- package/dist-cli-web/assets/DebugToolsPanel-DVDwS-wz.js +1 -0
- package/dist-cli-web/assets/EChartWordcloud-KV0MdsDE.js +1 -0
- package/dist-cli-web/assets/{Filter-B2eEAPxI.js → Filter-DVaqcFmI.js} +1 -1
- package/dist-cli-web/assets/GlobalTaskBar-COW_uBX6.css +1 -0
- package/dist-cli-web/assets/GlobalTaskBar-DpPMX0jx.js +1 -0
- package/dist-cli-web/assets/GroupRelationshipGalaxyView-CLnO3phW.js +1 -0
- package/dist-cli-web/assets/Label-Bt2U4lGy.js +1 -0
- package/dist-cli-web/assets/LoadingState.vue_vue_type_script_setup_true_lang-Cnshyn0f.js +1 -0
- package/dist-cli-web/assets/MessageExportModal-BozaR9UZ.js +1 -0
- package/dist-cli-web/assets/PageHeader-CEe0xTl3.js +1 -0
- package/dist-cli-web/assets/PageTabs.vue_vue_type_script_setup_true_lang-D2DZrrnv.js +1 -0
- package/dist-cli-web/assets/{RelationshipGalaxyCanvas-CwQ63TPi.js → RelationshipGalaxyCanvas-6EamagxG.js} +3 -3
- package/dist-cli-web/assets/{RelationshipGalaxyThreeCanvas-BLqISQe5.js → RelationshipGalaxyThreeCanvas-B6GB4PWS.js} +166 -166
- package/dist-cli-web/assets/{RelationshipGalaxyThreeCanvas-CMuibfiA.css → RelationshipGalaxyThreeCanvas-TYGOUDiv.css} +1 -1
- package/dist-cli-web/assets/{RenderTargetSystem-eC_VrDAr.js → RenderTargetSystem-mYuj4uBS.js} +1 -1
- package/dist-cli-web/assets/RovingFocusItem-B2y6BG1a.js +1 -0
- package/dist-cli-web/assets/ScreenCaptureModal-BvAtSNNR.js +1 -0
- package/dist-cli-web/assets/SectionTabs.vue_vue_type_script_setup_true_lang-ueEF4zHE.js +1 -0
- package/dist-cli-web/assets/Select-Cm4I8u9n.js +1 -0
- package/dist-cli-web/assets/SettingsModal-CjVax3I6.css +1 -0
- package/dist-cli-web/assets/SettingsModal-Cwshzj7i.js +2 -0
- package/dist-cli-web/assets/StorageTab-D7HzH16Y.js +1 -0
- package/dist-cli-web/assets/Switch-BVw4e_19.js +1 -0
- package/dist-cli-web/assets/Tabs-Dqwkh3Ea.js +1 -0
- package/dist-cli-web/assets/Tabs-OrJkANIA.js +1 -0
- package/dist-cli-web/assets/ThemeCard.vue_vue_type_script_setup_true_lang-DPIvbq75.js +1 -0
- package/dist-cli-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-dEdo6CqM.js +1 -0
- package/dist-cli-web/assets/VisuallyHiddenInput-BOdkR_GC.js +1 -0
- package/dist-cli-web/assets/{WebGLRenderer-CRp_HC84.js → WebGLRenderer-BB8ukBI_.js} +2 -2
- package/dist-cli-web/assets/{WebGPURenderer-WIUnEhpi.js → WebGPURenderer-DDOzF1Kc.js} +2 -2
- package/dist-cli-web/assets/aiChat-CzFSFuOJ.js +8 -0
- package/dist-cli-web/assets/annual-summary-time-range-CmrAqcuj.js +1 -0
- package/dist-cli-web/assets/base-CawUl6ET.js +1 -0
- package/dist-cli-web/assets/{browserAll-B29Ox2in.js → browserAll-BRqlnNxq.js} +2 -2
- package/dist-cli-web/assets/chatlabSiteLocale-CrCNb8QP.js +1 -0
- package/dist-cli-web/assets/clamp-jFYhBC76.js +1 -0
- package/dist-cli-web/assets/cli-web-ClAJ6Tao.js +1 -0
- package/dist-cli-web/assets/{dateFormat-T7kMS5IP.js → dateFormat-DXuDxIye.js} +1 -1
- package/dist-cli-web/assets/fetch-3_xX8Yi8.js +1 -0
- package/dist-cli-web/assets/{fetch-DsHf-61a.js → fetch-Bcy2T8Fe.js} +1 -1
- package/dist-cli-web/assets/{fetch-DvrVGAzR.js → fetch-CGu53cxT.js} +1 -1
- package/dist-cli-web/assets/{fetch-BBgZQob_.js → fetch-CP1afnT0.js} +1 -1
- package/dist-cli-web/assets/{fetch-D9sn99zX.js → fetch-DWAIk_6_.js} +1 -1
- package/dist-cli-web/assets/{fetch-BKBlpBl4.js → fetch-DijSOvop.js} +1 -1
- package/dist-cli-web/assets/{fetch-CYaGyohV.js → fetch-Dy38lkAa.js} +1 -1
- package/dist-cli-web/assets/{fetch-L6PKD8-N.js → fetch-DzKlTaLz.js} +1 -1
- package/dist-cli-web/assets/{fetch-D8hJZa8o.js → fetch-LY-yerw1.js} +1 -1
- package/dist-cli-web/assets/{fetch-BLi6Jsjg.js → fetch-q480XYZQ.js} +1 -1
- package/dist-cli-web/assets/index-0dp58uL4.css +1 -0
- package/dist-cli-web/assets/index-1X7zdLgJ.css +1 -0
- package/dist-cli-web/assets/index-4enwdBcq.css +1 -0
- package/dist-cli-web/assets/index-AudHHbMs.js +1 -0
- package/dist-cli-web/assets/{index-0qcENyvH.js → index-BRV_D8dv.js} +3 -3
- package/dist-cli-web/assets/index-CF4DTbvD.js +1 -0
- package/dist-cli-web/assets/index-CMLoht5R.js +1 -0
- package/dist-cli-web/assets/index-CMPHZH6B.css +1 -0
- package/dist-cli-web/assets/index-CNzv7aBW.js +1 -0
- package/dist-cli-web/assets/index-CXUTiy-V.js +1 -0
- package/dist-cli-web/assets/index-D5m0P4ss.js +36 -0
- package/dist-cli-web/assets/index-Di6FmCdk.js +64 -0
- package/dist-cli-web/assets/index-DkOrt7_X.js +2 -0
- package/dist-cli-web/assets/index-Dlb6fC68.js +1 -0
- package/dist-cli-web/assets/index-IA7YUjQX.js +2 -0
- package/dist-cli-web/assets/index-kzU381y1.js +1 -0
- package/dist-cli-web/assets/index-z8Vogc-b.js +137 -0
- package/dist-cli-web/assets/lazy-overlay-visibility-Bd9ZFOgR.js +1 -0
- package/dist-cli-web/assets/member-select-utils-BXZ3oHct.js +1 -0
- package/dist-cli-web/assets/people-page-header-Bh3KXD4g.js +1 -0
- package/dist-cli-web/assets/prompt-DcAcgQiB.js +1 -0
- package/dist-cli-web/assets/relationship-galaxy-connections-Cg4G5yYE.js +1 -0
- package/dist-cli-web/assets/semantic-index-config-builder-CK6v64Y1.js +1 -0
- package/dist-cli-web/assets/service-YZnJyEMq.js +1 -0
- package/dist-cli-web/assets/useFormControl-B-aXrJZN.js +1 -0
- package/dist-cli-web/assets/useTable-DPEMaGby.js +1 -0
- package/dist-cli-web/assets/useToast-B36MzFFy.js +1 -0
- package/dist-cli-web/assets/vendor-echarts-DfAMQxdr.js +11 -0
- package/dist-cli-web/assets/{vendor-echarts-wordcloud-Ca8n6qS6.js → vendor-echarts-wordcloud-BsaEJTPY.js} +1 -1
- package/dist-cli-web/assets/vendor-zrender-PFmZe1EY.js +8 -0
- package/dist-cli-web/assets/{webworkerAll-B2qvP2qR.js → webworkerAll-Dwqmy_YO.js} +1 -1
- package/dist-cli-web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-2XCNTG4O.mjs.map +0 -1
- package/dist/chunk-4LW6443F.mjs.map +0 -1
- package/dist/chunk-72RWABYJ.mjs.map +0 -1
- package/dist/chunk-H6D4DZOC.mjs.map +0 -1
- package/dist/chunk-INBJ7SND.mjs.map +0 -1
- package/dist/chunk-MENKFEPC.mjs.map +0 -1
- package/dist/chunk-U6MVJSXX.mjs.map +0 -1
- package/dist-cli-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-B06LYYS9.js +0 -110
- package/dist-cli-web/assets/CanvasRenderer-DDRdIyZ8.js +0 -1
- package/dist-cli-web/assets/DataDirCleanupNotice-CP8P1lsL.js +0 -1
- package/dist-cli-web/assets/EChartWordcloud-CqknPGui.js +0 -1
- package/dist-cli-web/assets/LoadingState.vue_vue_type_script_setup_true_lang-BFaXTz1c.js +0 -1
- package/dist-cli-web/assets/MessageExportModal-CZge6qub.js +0 -1
- package/dist-cli-web/assets/PageHeader-CxKbcLDc.js +0 -1
- package/dist-cli-web/assets/ThemeCard.vue_vue_type_script_setup_true_lang-DVmpDz05.js +0 -1
- package/dist-cli-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-CCH1UQGc.js +0 -1
- package/dist-cli-web/assets/annual-summary-time-range-R3pLPEuN.js +0 -1
- package/dist-cli-web/assets/base-CLwWn3Rs.js +0 -1
- package/dist-cli-web/assets/cli-web-CVLb5Pkq.js +0 -1
- package/dist-cli-web/assets/fetch-Cm2WR2Cv.js +0 -1
- package/dist-cli-web/assets/index-AkF_KqVI.js +0 -1
- package/dist-cli-web/assets/index-BVOFyB9E.js +0 -137
- package/dist-cli-web/assets/index-BkdOH41D.js +0 -1
- package/dist-cli-web/assets/index-C4TuoOLM.js +0 -2
- package/dist-cli-web/assets/index-C6Mk-Xqt.js +0 -1
- package/dist-cli-web/assets/index-CkgUsaeX.js +0 -1
- package/dist-cli-web/assets/index-CuAy1Xmt.js +0 -64
- package/dist-cli-web/assets/index-D_0qeKKc.js +0 -53
- package/dist-cli-web/assets/index-DeR0Vukh.js +0 -1
- package/dist-cli-web/assets/index-DrjoMv9s.css +0 -1
- package/dist-cli-web/assets/index-Dx-XvfIK.js +0 -2
- package/dist-cli-web/assets/index-Jhwca9kg.css +0 -1
- package/dist-cli-web/assets/index-_DrviTnP.js +0 -1
- package/dist-cli-web/assets/index-vtF05fh7.css +0 -1
- package/dist-cli-web/assets/index-xN0sjOLK.js +0 -1
- package/dist-cli-web/assets/people-page-header-CCNJOrmK.js +0 -1
- package/dist-cli-web/assets/vendor-echarts-B-i_56Av.js +0 -11
- package/dist-cli-web/assets/vendor-zrender-5DcYjSZk.js +0 -8
- /package/dist/{chat-command-6IOH2QRF.mjs.map → chat-command-24RYGJAS.mjs.map} +0 -0
- /package/dist/{chunk-4RLZFGO5.mjs.map → chunk-GQMCDWZQ.mjs.map} +0 -0
- /package/dist/{chunk-52P5ZRBD.mjs.map → chunk-KIMJXKZO.mjs.map} +0 -0
- /package/dist/{chunk-652KEAX3.mjs.map → chunk-KXDJ7N6N.mjs.map} +0 -0
- /package/dist/{chunk-UMBEHBIZ.mjs.map → chunk-U36TQMAF.mjs.map} +0 -0
- /package/dist/{chunk-JX6MFS6F.mjs.map → chunk-ZBPPLXM4.mjs.map} +0 -0
- /package/dist/{http-HSK46XEU.mjs.map → http-3K4YMWDE.mjs.map} +0 -0
- /package/dist/{import-DF2WD2HE.mjs.map → import-D4LV565A.mjs.map} +0 -0
- /package/dist/{mcp-A2RND7KN.mjs.map → mcp-KL22FKQ2.mjs.map} +0 -0
- /package/dist/{src-SHFHW2QB.mjs.map → src-COIB6Z4P.mjs.map} +0 -0
- /package/dist/{stream-import-GZ2QDE3Z.mjs.map → stream-import-FSXCFG4M.mjs.map} +0 -0
- /package/dist/{worker-runtime-OWN56GG5.mjs.map → worker-runtime-DPS2LURI.mjs.map} +0 -0
|
@@ -40,46 +40,49 @@ import {
|
|
|
40
40
|
composeChunkId,
|
|
41
41
|
computeChunkerConfigHash,
|
|
42
42
|
computeDbPathHash,
|
|
43
|
-
createChatDbFtsSearcher,
|
|
44
43
|
createChatDbMessageRangeReader,
|
|
45
44
|
createChatDbMessageSource,
|
|
46
45
|
createChatLabTempDir,
|
|
47
46
|
createEmbedder,
|
|
48
47
|
createLocalEmbeddingRuntimeManager,
|
|
48
|
+
createMessageDedupState,
|
|
49
49
|
createSemanticIndexService,
|
|
50
50
|
defaultSemanticIndexConfig,
|
|
51
51
|
deriveParentId,
|
|
52
52
|
estimateTokens,
|
|
53
|
-
extractFtsKeywords,
|
|
54
53
|
formatEvidenceMessages,
|
|
54
|
+
generateFallbackMessageKey,
|
|
55
55
|
getChatLabTempScopeDir,
|
|
56
56
|
getLocalProfileByModelId,
|
|
57
57
|
getLocalProfilesForLocale,
|
|
58
|
-
hybridSearch,
|
|
59
58
|
isKeylessSemanticIndexApiBaseUrl,
|
|
60
59
|
isSemanticIndexConfigured,
|
|
61
60
|
isSemanticVoid,
|
|
62
61
|
parseParentBounds,
|
|
63
62
|
persistSemanticIndexConfig,
|
|
64
63
|
rebaseChatLabDemoDocuments,
|
|
65
|
-
|
|
64
|
+
registerMessageAndCheckDuplicate,
|
|
66
65
|
removeChatLabTempDir,
|
|
67
66
|
resolveModelId,
|
|
68
67
|
resolveSemanticIndexApiKeySet,
|
|
69
68
|
runWarmup,
|
|
69
|
+
semanticSearch,
|
|
70
70
|
vecTableName,
|
|
71
71
|
vecTableSchema
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-4GWWKHWA.mjs";
|
|
73
73
|
import {
|
|
74
74
|
CHATLAB_FORMAT_VERSION,
|
|
75
75
|
MEANINGFUL_POS_TAGS,
|
|
76
|
+
POS_TAG_DEFINITIONS,
|
|
76
77
|
StaticPathProvider,
|
|
77
78
|
appLogger,
|
|
79
|
+
buildExcludeKeywordsConditions,
|
|
80
|
+
cleanText,
|
|
78
81
|
detectConflictsInMessages,
|
|
79
|
-
generateMessageKey,
|
|
80
82
|
getCollidingPlatformIds,
|
|
81
|
-
|
|
83
|
+
getCollidingPlatformIdsFromMessages,
|
|
82
84
|
isStopword,
|
|
85
|
+
isValidWord,
|
|
83
86
|
loadConfig,
|
|
84
87
|
mergeMembers2 as mergeMembers,
|
|
85
88
|
migrateFromElectronIfNeeded,
|
|
@@ -90,7 +93,7 @@ import {
|
|
|
90
93
|
withFileLock,
|
|
91
94
|
writeConfigField,
|
|
92
95
|
writeJsonFileAtomically
|
|
93
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-22YJOBA3.mjs";
|
|
94
97
|
import {
|
|
95
98
|
__export
|
|
96
99
|
} from "./chunk-VSOWNKPA.mjs";
|
|
@@ -556,6 +559,220 @@ function expandHome(filePath) {
|
|
|
556
559
|
return filePath;
|
|
557
560
|
}
|
|
558
561
|
|
|
562
|
+
// ../../packages/node-runtime/src/nlp/segmenter.ts
|
|
563
|
+
import * as fs3 from "fs";
|
|
564
|
+
import * as path3 from "path";
|
|
565
|
+
import { createRequire } from "module";
|
|
566
|
+
var _nlpDir = null;
|
|
567
|
+
var jiebaInstances = /* @__PURE__ */ new Map();
|
|
568
|
+
var require2 = createRequire(import.meta.url);
|
|
569
|
+
function initNlpDir(nlpDir) {
|
|
570
|
+
_nlpDir = nlpDir;
|
|
571
|
+
}
|
|
572
|
+
function getNlpDir() {
|
|
573
|
+
return _nlpDir;
|
|
574
|
+
}
|
|
575
|
+
function existsDictOnDisk(dictId) {
|
|
576
|
+
if (!_nlpDir) return false;
|
|
577
|
+
return fs3.existsSync(path3.join(_nlpDir, `${dictId}.dict`));
|
|
578
|
+
}
|
|
579
|
+
function tryLoadDictFromDisk(dictId) {
|
|
580
|
+
if (!_nlpDir) return null;
|
|
581
|
+
const dictPath = path3.join(_nlpDir, `${dictId}.dict`);
|
|
582
|
+
if (!fs3.existsSync(dictPath)) return null;
|
|
583
|
+
try {
|
|
584
|
+
return fs3.readFileSync(dictPath);
|
|
585
|
+
} catch {
|
|
586
|
+
return null;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
function getJieba(dictType = "default") {
|
|
590
|
+
const effectiveType = dictType === "default" ? "zh-CN" : dictType;
|
|
591
|
+
const cached = jiebaInstances.get(effectiveType);
|
|
592
|
+
if (cached) {
|
|
593
|
+
if (cached.fromDiskDict === existsDictOnDisk(effectiveType)) return cached.instance;
|
|
594
|
+
jiebaInstances.delete(effectiveType);
|
|
595
|
+
console.error(`[NLP] jieba cache invalidated (dict ${cached.fromDiskDict ? "removed" : "added"}): ${effectiveType}`);
|
|
596
|
+
}
|
|
597
|
+
try {
|
|
598
|
+
const { Jieba } = require2("@node-rs/jieba");
|
|
599
|
+
let instance;
|
|
600
|
+
const diskDict = tryLoadDictFromDisk(effectiveType);
|
|
601
|
+
if (diskDict) {
|
|
602
|
+
instance = Jieba.withDict(diskDict);
|
|
603
|
+
console.error(`[NLP] jieba dict loaded: ${effectiveType} (${diskDict.length} bytes)`);
|
|
604
|
+
} else {
|
|
605
|
+
instance = new Jieba();
|
|
606
|
+
console.warn(`[NLP] jieba dict missing: ${effectiveType}, fallback to built-in tokenizer`);
|
|
607
|
+
}
|
|
608
|
+
jiebaInstances.set(effectiveType, { instance, fromDiskDict: !!diskDict });
|
|
609
|
+
return instance;
|
|
610
|
+
} catch (error) {
|
|
611
|
+
console.error(`[NLP] Failed to load jieba module (dict=${effectiveType}):`, error);
|
|
612
|
+
throw new Error(`jieba \u6A21\u5757\u52A0\u8F7D\u5931\u8D25 (${effectiveType})`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function clearJiebaInstance(dictType) {
|
|
616
|
+
jiebaInstances.delete(dictType);
|
|
617
|
+
console.error(`[NLP] jieba instance cleared: ${dictType}`);
|
|
618
|
+
}
|
|
619
|
+
function segmentChinese(text, options = {}) {
|
|
620
|
+
const { posFilterMode = "meaningful", customPosTags, dictType = "default" } = options;
|
|
621
|
+
const cleaned = cleanText(text);
|
|
622
|
+
if (!cleaned) return [];
|
|
623
|
+
try {
|
|
624
|
+
const jieba = getJieba(dictType);
|
|
625
|
+
if (posFilterMode === "all") return jieba.cut(cleaned, false);
|
|
626
|
+
const tagged = jieba.tag(cleaned);
|
|
627
|
+
const allowedTags = posFilterMode === "custom" && customPosTags ? new Set(customPosTags) : MEANINGFUL_POS_TAGS;
|
|
628
|
+
return tagged.filter((item) => allowedTags.has(item.tag)).map((item) => item.word);
|
|
629
|
+
} catch (error) {
|
|
630
|
+
console.error("[NLP] Chinese segmentation failed:", error);
|
|
631
|
+
try {
|
|
632
|
+
return getJieba("default").cut(cleanText(text), false);
|
|
633
|
+
} catch {
|
|
634
|
+
return cleaned.split("");
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function segmentEnglish(text) {
|
|
639
|
+
const cleaned = cleanText(text);
|
|
640
|
+
if (!cleaned) return [];
|
|
641
|
+
try {
|
|
642
|
+
const segmenter = new Intl.Segmenter("en", { granularity: "word" });
|
|
643
|
+
return [...segmenter.segment(cleaned)].filter((s) => s.isWordLike).map((s) => s.segment.toLowerCase());
|
|
644
|
+
} catch {
|
|
645
|
+
return cleaned.toLowerCase().split(/\s+/).filter((w) => w.length > 0);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function segmentJapanese(text) {
|
|
649
|
+
const cleaned = cleanText(text);
|
|
650
|
+
if (!cleaned) return [];
|
|
651
|
+
try {
|
|
652
|
+
const segmenter = new Intl.Segmenter("ja", { granularity: "word" });
|
|
653
|
+
return [...segmenter.segment(cleaned)].filter((s) => s.isWordLike).map((s) => s.segment);
|
|
654
|
+
} catch {
|
|
655
|
+
return cleaned.split("").filter((ch) => ch.trim().length > 0);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
function segment(text, locale, options = {}) {
|
|
659
|
+
const {
|
|
660
|
+
minLength,
|
|
661
|
+
posFilterMode = "meaningful",
|
|
662
|
+
customPosTags,
|
|
663
|
+
enableStopwords = true,
|
|
664
|
+
dictType = "default"
|
|
665
|
+
} = options;
|
|
666
|
+
const isChinese = locale.startsWith("zh");
|
|
667
|
+
const isJapanese = locale === "ja-JP";
|
|
668
|
+
const defaultMinLength = isChinese || isJapanese ? 2 : 3;
|
|
669
|
+
const effectiveMinLength = minLength ?? defaultMinLength;
|
|
670
|
+
let words;
|
|
671
|
+
if (isChinese) {
|
|
672
|
+
words = segmentChinese(text, { posFilterMode, customPosTags, dictType });
|
|
673
|
+
} else if (isJapanese) {
|
|
674
|
+
words = segmentJapanese(text);
|
|
675
|
+
} else {
|
|
676
|
+
words = segmentEnglish(text);
|
|
677
|
+
}
|
|
678
|
+
return words.filter((word) => isValidWord(word, locale, effectiveMinLength, enableStopwords, isStopword));
|
|
679
|
+
}
|
|
680
|
+
function batchSegmentWithFrequency(texts, locale, options = {}) {
|
|
681
|
+
const {
|
|
682
|
+
minLength,
|
|
683
|
+
minCount = 2,
|
|
684
|
+
topN = 100,
|
|
685
|
+
posFilterMode,
|
|
686
|
+
customPosTags,
|
|
687
|
+
enableStopwords,
|
|
688
|
+
dictType,
|
|
689
|
+
excludeWords
|
|
690
|
+
} = options;
|
|
691
|
+
const wordFrequency = /* @__PURE__ */ new Map();
|
|
692
|
+
const excludeSet = excludeWords?.length ? new Set(excludeWords.map((w) => w.toLowerCase())) : null;
|
|
693
|
+
for (const text of texts) {
|
|
694
|
+
const words = segment(text, locale, { minLength, posFilterMode, customPosTags, enableStopwords, dictType });
|
|
695
|
+
for (const word of words) {
|
|
696
|
+
if (excludeSet && excludeSet.has(word.toLowerCase())) continue;
|
|
697
|
+
wordFrequency.set(word, (wordFrequency.get(word) || 0) + 1);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
701
|
+
let totalWords = 0;
|
|
702
|
+
for (const [word, count] of wordFrequency) {
|
|
703
|
+
if (count >= minCount) {
|
|
704
|
+
filtered.set(word, count);
|
|
705
|
+
totalWords += count;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
const sorted = [...filtered.entries()].sort((a, b) => b[1] - a[1]).slice(0, topN);
|
|
709
|
+
return { words: new Map(sorted), uniqueWords: filtered.size, totalWords };
|
|
710
|
+
}
|
|
711
|
+
function batchSegmentChineseWithStats(texts, locale, options = {}) {
|
|
712
|
+
const {
|
|
713
|
+
minLength,
|
|
714
|
+
minCount = 2,
|
|
715
|
+
topN = 100,
|
|
716
|
+
posFilterMode = "meaningful",
|
|
717
|
+
customPosTags,
|
|
718
|
+
enableStopwords = true,
|
|
719
|
+
dictType = "default",
|
|
720
|
+
excludeWords
|
|
721
|
+
} = options;
|
|
722
|
+
const effectiveMinLength = minLength ?? 2;
|
|
723
|
+
const allowedTags = posFilterMode === "custom" && customPosTags ? new Set(customPosTags) : MEANINGFUL_POS_TAGS;
|
|
724
|
+
const excludeSet = excludeWords?.length ? new Set(excludeWords.map((w) => w.toLowerCase())) : null;
|
|
725
|
+
const wordFrequency = /* @__PURE__ */ new Map();
|
|
726
|
+
const posTagStats = /* @__PURE__ */ new Map();
|
|
727
|
+
try {
|
|
728
|
+
const jieba = getJieba(dictType);
|
|
729
|
+
for (const text of texts) {
|
|
730
|
+
const cleaned = cleanText(text);
|
|
731
|
+
if (!cleaned) continue;
|
|
732
|
+
for (const { tag, word } of jieba.tag(cleaned)) {
|
|
733
|
+
if (!isValidWord(word, locale, effectiveMinLength, enableStopwords, isStopword)) continue;
|
|
734
|
+
posTagStats.set(tag, (posTagStats.get(tag) || 0) + 1);
|
|
735
|
+
if (!allowedTags.has(tag)) continue;
|
|
736
|
+
if (excludeSet && excludeSet.has(word.toLowerCase())) continue;
|
|
737
|
+
wordFrequency.set(word, (wordFrequency.get(word) || 0) + 1);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
} catch (error) {
|
|
741
|
+
console.error("[NLP] Chinese single-pass segmentation failed:", error);
|
|
742
|
+
}
|
|
743
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
744
|
+
let totalWords = 0;
|
|
745
|
+
for (const [word, count] of wordFrequency) {
|
|
746
|
+
if (count >= minCount) {
|
|
747
|
+
filtered.set(word, count);
|
|
748
|
+
totalWords += count;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
const sorted = [...filtered.entries()].sort((a, b) => b[1] - a[1]).slice(0, topN);
|
|
752
|
+
return { words: new Map(sorted), uniqueWords: filtered.size, totalWords, posTagStats };
|
|
753
|
+
}
|
|
754
|
+
function collectPosTagStats(texts, minWordLength = 2, enableStopwords = true, dictType = "default") {
|
|
755
|
+
const posStats = /* @__PURE__ */ new Map();
|
|
756
|
+
try {
|
|
757
|
+
const jieba = getJieba(dictType);
|
|
758
|
+
for (const text of texts) {
|
|
759
|
+
const cleaned = cleanText(text);
|
|
760
|
+
if (!cleaned) continue;
|
|
761
|
+
const tagged = jieba.tag(cleaned);
|
|
762
|
+
for (const item of tagged) {
|
|
763
|
+
if (!isValidWord(item.word, "zh-CN", minWordLength, enableStopwords, isStopword)) continue;
|
|
764
|
+
posStats.set(item.tag, (posStats.get(item.tag) || 0) + 1);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
} catch (error) {
|
|
768
|
+
console.error("[NLP] Failed to collect POS stats:", error);
|
|
769
|
+
}
|
|
770
|
+
return posStats;
|
|
771
|
+
}
|
|
772
|
+
function getPosTagDefinitions() {
|
|
773
|
+
return POS_TAG_DEFINITIONS;
|
|
774
|
+
}
|
|
775
|
+
|
|
559
776
|
// ../../packages/node-runtime/src/jieba-nlp-provider.ts
|
|
560
777
|
function createJiebaNlpProvider(dictType = "default") {
|
|
561
778
|
return {
|
|
@@ -567,9 +784,233 @@ function createJiebaNlpProvider(dictType = "default") {
|
|
|
567
784
|
};
|
|
568
785
|
}
|
|
569
786
|
|
|
787
|
+
// ../../packages/node-runtime/src/nlp/word-frequency.ts
|
|
788
|
+
function buildMessageQuery(timeFilter, memberId, excludeKeywords) {
|
|
789
|
+
const conditions = [];
|
|
790
|
+
const params = [];
|
|
791
|
+
if (timeFilter?.startTs !== void 0) {
|
|
792
|
+
conditions.push("msg.ts >= ?");
|
|
793
|
+
params.push(timeFilter.startTs);
|
|
794
|
+
}
|
|
795
|
+
if (timeFilter?.endTs !== void 0) {
|
|
796
|
+
conditions.push("msg.ts <= ?");
|
|
797
|
+
params.push(timeFilter.endTs);
|
|
798
|
+
}
|
|
799
|
+
if (memberId !== void 0 && memberId !== null) {
|
|
800
|
+
conditions.push("msg.sender_id = ?");
|
|
801
|
+
params.push(memberId);
|
|
802
|
+
}
|
|
803
|
+
if (excludeKeywords && excludeKeywords.length > 0) {
|
|
804
|
+
const exclude = buildExcludeKeywordsConditions(excludeKeywords);
|
|
805
|
+
conditions.push(...exclude.conditions);
|
|
806
|
+
params.push(...exclude.params);
|
|
807
|
+
}
|
|
808
|
+
conditions.push("COALESCE(m.account_name, '') != '\u7CFB\u7EDF\u6D88\u606F'");
|
|
809
|
+
conditions.push("msg.type = 0");
|
|
810
|
+
conditions.push("msg.content IS NOT NULL");
|
|
811
|
+
conditions.push("TRIM(msg.content) != ''");
|
|
812
|
+
return {
|
|
813
|
+
clause: ` WHERE ${conditions.join(" AND ")}`,
|
|
814
|
+
params
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
function computeWordFrequency(db, params) {
|
|
818
|
+
const {
|
|
819
|
+
locale,
|
|
820
|
+
timeFilter,
|
|
821
|
+
memberId,
|
|
822
|
+
topN = 100,
|
|
823
|
+
minWordLength,
|
|
824
|
+
minCount = 2,
|
|
825
|
+
posFilterMode = "meaningful",
|
|
826
|
+
customPosTags,
|
|
827
|
+
enableStopwords = true,
|
|
828
|
+
dictType = "default",
|
|
829
|
+
excludeWords,
|
|
830
|
+
excludeKeywords
|
|
831
|
+
} = params;
|
|
832
|
+
const { clause, params: filterParams } = buildMessageQuery(timeFilter, memberId, excludeKeywords);
|
|
833
|
+
const messages = db.prepare(`SELECT msg.content FROM message msg JOIN member m ON msg.sender_id = m.id${clause}`).all(...filterParams);
|
|
834
|
+
if (messages.length === 0) {
|
|
835
|
+
return { words: [], totalWords: 0, totalMessages: 0, uniqueWords: 0 };
|
|
836
|
+
}
|
|
837
|
+
const texts = messages.map((m) => m.content);
|
|
838
|
+
const segmentOptions = {
|
|
839
|
+
minLength: minWordLength,
|
|
840
|
+
minCount,
|
|
841
|
+
topN,
|
|
842
|
+
posFilterMode,
|
|
843
|
+
customPosTags,
|
|
844
|
+
enableStopwords,
|
|
845
|
+
dictType,
|
|
846
|
+
excludeWords
|
|
847
|
+
};
|
|
848
|
+
let posTagStats;
|
|
849
|
+
let result;
|
|
850
|
+
if (locale.startsWith("zh") && posFilterMode !== "all") {
|
|
851
|
+
const combined = batchSegmentChineseWithStats(texts, locale, segmentOptions);
|
|
852
|
+
result = { words: combined.words, uniqueWords: combined.uniqueWords, totalWords: combined.totalWords };
|
|
853
|
+
posTagStats = [...combined.posTagStats.entries()].map(([tag, count]) => ({ tag, count }));
|
|
854
|
+
} else {
|
|
855
|
+
if (locale.startsWith("zh")) {
|
|
856
|
+
const posStatsMap = collectPosTagStats(texts, minWordLength ?? 2, enableStopwords, dictType);
|
|
857
|
+
posTagStats = [...posStatsMap.entries()].map(([tag, count]) => ({ tag, count }));
|
|
858
|
+
}
|
|
859
|
+
result = batchSegmentWithFrequency(texts, locale, segmentOptions);
|
|
860
|
+
}
|
|
861
|
+
let topNTotalWords = 0;
|
|
862
|
+
for (const count of result.words.values()) topNTotalWords += count;
|
|
863
|
+
const words = [...result.words.entries()].map(([word, count]) => ({
|
|
864
|
+
word,
|
|
865
|
+
count,
|
|
866
|
+
percentage: topNTotalWords > 0 ? Math.round(count / topNTotalWords * 1e4) / 100 : 0
|
|
867
|
+
}));
|
|
868
|
+
return {
|
|
869
|
+
words,
|
|
870
|
+
totalWords: result.totalWords,
|
|
871
|
+
totalMessages: messages.length,
|
|
872
|
+
uniqueWords: result.uniqueWords,
|
|
873
|
+
posTagStats
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
function segmentText(text, locale, minLength) {
|
|
877
|
+
return segment(text, locale, { minLength });
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// ../../packages/node-runtime/src/nlp/dict-manager.ts
|
|
881
|
+
import * as fs4 from "fs";
|
|
882
|
+
import * as path4 from "path";
|
|
883
|
+
import { createHash } from "crypto";
|
|
884
|
+
var DICT_DOWNLOAD_URL_BASE = "https://chatlab.fun/assets/nlp";
|
|
885
|
+
var DICT_SHA256 = {
|
|
886
|
+
"zh-CN": "139519822fe8ab9e10d9d07e68ea0451045380aedaf54ecc51e2a28c6b42a13f",
|
|
887
|
+
"zh-TW": "a63ec7e388f16f1b486dcd948a9f1a3b492be5d9b6bdab786a95e59966786dfd"
|
|
888
|
+
};
|
|
889
|
+
var AVAILABLE_DICTS = [
|
|
890
|
+
{ id: "zh-CN", label: "\u7B80\u4F53\u4E2D\u6587", locale: "zh-CN" },
|
|
891
|
+
{ id: "zh-TW", label: "\u7E41\u9AD4\u4E2D\u6587", locale: "zh-TW" }
|
|
892
|
+
];
|
|
893
|
+
function getDictFilePath(nlpDir, dictId) {
|
|
894
|
+
return path4.join(nlpDir, `${dictId}.dict`);
|
|
895
|
+
}
|
|
896
|
+
function isDictDownloaded(nlpDir, dictId) {
|
|
897
|
+
return fs4.existsSync(getDictFilePath(nlpDir, dictId));
|
|
898
|
+
}
|
|
899
|
+
function getDictList(nlpDir) {
|
|
900
|
+
return AVAILABLE_DICTS.map((d) => {
|
|
901
|
+
const filePath = getDictFilePath(nlpDir, d.id);
|
|
902
|
+
const downloaded = fs4.existsSync(filePath);
|
|
903
|
+
let fileSize;
|
|
904
|
+
if (downloaded) {
|
|
905
|
+
try {
|
|
906
|
+
fileSize = fs4.statSync(filePath).size;
|
|
907
|
+
} catch {
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return { ...d, downloaded, fileSize };
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
function loadDictBuffer(nlpDir, dictId) {
|
|
914
|
+
const filePath = getDictFilePath(nlpDir, dictId);
|
|
915
|
+
if (!fs4.existsSync(filePath)) return null;
|
|
916
|
+
try {
|
|
917
|
+
return fs4.readFileSync(filePath);
|
|
918
|
+
} catch (error) {
|
|
919
|
+
console.error(`[NLP DictManager] Failed to read dict file: ${filePath}`, error);
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
async function downloadDict(nlpDir, dictId, onProgress) {
|
|
924
|
+
if (!AVAILABLE_DICTS.find((d) => d.id === dictId)) {
|
|
925
|
+
return { success: false, error: `Unknown dict: ${dictId}` };
|
|
926
|
+
}
|
|
927
|
+
fs4.mkdirSync(nlpDir, { recursive: true });
|
|
928
|
+
const url = `${DICT_DOWNLOAD_URL_BASE}/${dictId}.dict`;
|
|
929
|
+
const filePath = getDictFilePath(nlpDir, dictId);
|
|
930
|
+
const tmpPath = filePath + ".tmp";
|
|
931
|
+
try {
|
|
932
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(12e4) });
|
|
933
|
+
if (!response.ok) throw new Error(`Download failed: HTTP ${response.status}`);
|
|
934
|
+
const total = Number(response.headers.get("content-length") || 0);
|
|
935
|
+
let buffer;
|
|
936
|
+
if (!response.body) {
|
|
937
|
+
buffer = Buffer.from(await response.arrayBuffer());
|
|
938
|
+
} else {
|
|
939
|
+
const reader = response.body.getReader();
|
|
940
|
+
const chunks = [];
|
|
941
|
+
let loaded = 0;
|
|
942
|
+
while (true) {
|
|
943
|
+
const { done, value } = await reader.read();
|
|
944
|
+
if (done) break;
|
|
945
|
+
const chunk = Buffer.from(value);
|
|
946
|
+
chunks.push(chunk);
|
|
947
|
+
loaded += chunk.length;
|
|
948
|
+
if (total > 0 && onProgress) onProgress(Math.round(loaded / total * 100));
|
|
949
|
+
}
|
|
950
|
+
buffer = Buffer.concat(chunks);
|
|
951
|
+
}
|
|
952
|
+
const MIN_DICT_SIZE = 1e6;
|
|
953
|
+
if (buffer.length < MIN_DICT_SIZE) {
|
|
954
|
+
return { success: false, error: `Downloaded file is invalid (${buffer.length} bytes)` };
|
|
955
|
+
}
|
|
956
|
+
const head = buffer.subarray(0, 50).toString("utf-8").trim();
|
|
957
|
+
if (head.startsWith("<!") || head.startsWith("<html")) {
|
|
958
|
+
return { success: false, error: "Downloaded file is HTML, not a dictionary file" };
|
|
959
|
+
}
|
|
960
|
+
const expectedSha256 = DICT_SHA256[dictId];
|
|
961
|
+
if (!expectedSha256) {
|
|
962
|
+
return { success: false, error: `Missing SHA256 checksum for dict: ${dictId}` };
|
|
963
|
+
}
|
|
964
|
+
const actualSha256 = createHash("sha256").update(buffer).digest("hex");
|
|
965
|
+
if (actualSha256 !== expectedSha256) {
|
|
966
|
+
return { success: false, error: "Dictionary integrity check failed (SHA256 mismatch)" };
|
|
967
|
+
}
|
|
968
|
+
fs4.writeFileSync(tmpPath, buffer);
|
|
969
|
+
if (fs4.existsSync(filePath)) fs4.unlinkSync(filePath);
|
|
970
|
+
fs4.renameSync(tmpPath, filePath);
|
|
971
|
+
clearJiebaInstance(dictId);
|
|
972
|
+
console.log(`[NLP DictManager] Dict downloaded: ${dictId} (${fs4.statSync(filePath).size} bytes)`);
|
|
973
|
+
return { success: true };
|
|
974
|
+
} catch (error) {
|
|
975
|
+
if (fs4.existsSync(tmpPath)) {
|
|
976
|
+
try {
|
|
977
|
+
fs4.unlinkSync(tmpPath);
|
|
978
|
+
} catch {
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
982
|
+
console.error(`[NLP DictManager] Download failed for ${dictId}:`, msg);
|
|
983
|
+
return { success: false, error: msg };
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
function deleteDict(nlpDir, dictId) {
|
|
987
|
+
const filePath = getDictFilePath(nlpDir, dictId);
|
|
988
|
+
if (!fs4.existsSync(filePath)) return { success: true };
|
|
989
|
+
try {
|
|
990
|
+
fs4.unlinkSync(filePath);
|
|
991
|
+
clearJiebaInstance(dictId);
|
|
992
|
+
console.log(`[NLP DictManager] Dict deleted: ${dictId}`);
|
|
993
|
+
return { success: true };
|
|
994
|
+
} catch (error) {
|
|
995
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
996
|
+
console.error(`[NLP DictManager] Delete failed for ${dictId}:`, msg);
|
|
997
|
+
return { success: false, error: msg };
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
async function ensureDefaultDict(nlpDir) {
|
|
1001
|
+
if (isDictDownloaded(nlpDir, "zh-CN")) return;
|
|
1002
|
+
console.log("[NLP DictManager] zh-CN dict not found, starting background download...");
|
|
1003
|
+
const result = await downloadDict(nlpDir, "zh-CN");
|
|
1004
|
+
if (result.success) {
|
|
1005
|
+
console.log("[NLP DictManager] zh-CN dict auto-downloaded successfully");
|
|
1006
|
+
} else {
|
|
1007
|
+
console.warn("[NLP DictManager] zh-CN dict auto-download failed:", result.error);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
570
1011
|
// ../../packages/node-runtime/src/preferences.ts
|
|
571
|
-
import * as
|
|
572
|
-
import * as
|
|
1012
|
+
import * as fs5 from "fs";
|
|
1013
|
+
import * as path5 from "path";
|
|
573
1014
|
var DEFAULTS = {
|
|
574
1015
|
pinnedSessionIds: [],
|
|
575
1016
|
assistantUpgradeSkippedVersions: {},
|
|
@@ -592,13 +1033,7 @@ var DEFAULTS = {
|
|
|
592
1033
|
enableAutoSkill: true,
|
|
593
1034
|
chartAutoMode: "suggest",
|
|
594
1035
|
searchContextBefore: 2,
|
|
595
|
-
searchContextAfter: 2
|
|
596
|
-
contextCompression: {
|
|
597
|
-
enabled: true,
|
|
598
|
-
tokenThresholdPercent: 75,
|
|
599
|
-
bufferSizePercent: 20,
|
|
600
|
-
maxToolResultPercent: 50
|
|
601
|
-
}
|
|
1036
|
+
searchContextAfter: 2
|
|
602
1037
|
},
|
|
603
1038
|
customKeywordTemplates: [],
|
|
604
1039
|
deletedPresetTemplateIds: [],
|
|
@@ -616,13 +1051,13 @@ var PreferencesManager = class {
|
|
|
616
1051
|
filePath;
|
|
617
1052
|
cache = null;
|
|
618
1053
|
constructor(systemDir) {
|
|
619
|
-
this.filePath =
|
|
1054
|
+
this.filePath = path5.join(systemDir, "preferences.json");
|
|
620
1055
|
}
|
|
621
1056
|
load() {
|
|
622
1057
|
if (this.cache) return this.cache;
|
|
623
1058
|
try {
|
|
624
|
-
if (
|
|
625
|
-
const raw =
|
|
1059
|
+
if (fs5.existsSync(this.filePath)) {
|
|
1060
|
+
const raw = fs5.readFileSync(this.filePath, "utf-8");
|
|
626
1061
|
const parsed = JSON.parse(raw);
|
|
627
1062
|
const migrated = this.migrateLegacyDesensitizeRules(parsed, raw);
|
|
628
1063
|
this.cache = this.mergeDefaults(migrated.preferences);
|
|
@@ -668,14 +1103,7 @@ var PreferencesManager = class {
|
|
|
668
1103
|
pinnedSessionIds: partial.pinnedSessionIds ?? DEFAULTS.pinnedSessionIds,
|
|
669
1104
|
assistantUpgradeSkippedVersions: this.normalizePositiveIntegerMap(partial.assistantUpgradeSkippedVersions),
|
|
670
1105
|
aiPreprocessConfig: partial.aiPreprocessConfig ? this.normalizeAiPreprocessConfig(partial.aiPreprocessConfig) : { ...DEFAULTS.aiPreprocessConfig },
|
|
671
|
-
aiGlobalSettings: partial.aiGlobalSettings
|
|
672
|
-
...DEFAULTS.aiGlobalSettings,
|
|
673
|
-
...partial.aiGlobalSettings,
|
|
674
|
-
contextCompression: {
|
|
675
|
-
...DEFAULTS.aiGlobalSettings.contextCompression,
|
|
676
|
-
...partial.aiGlobalSettings.contextCompression ?? {}
|
|
677
|
-
}
|
|
678
|
-
} : { ...DEFAULTS.aiGlobalSettings },
|
|
1106
|
+
aiGlobalSettings: this.normalizeAiGlobalSettings(partial.aiGlobalSettings),
|
|
679
1107
|
customKeywordTemplates: partial.customKeywordTemplates ?? DEFAULTS.customKeywordTemplates,
|
|
680
1108
|
deletedPresetTemplateIds: partial.deletedPresetTemplateIds ?? DEFAULTS.deletedPresetTemplateIds,
|
|
681
1109
|
wordFilter: partial.wordFilter ? { ...DEFAULTS.wordFilter, ...partial.wordFilter } : { ...DEFAULTS.wordFilter },
|
|
@@ -685,6 +1113,11 @@ var PreferencesManager = class {
|
|
|
685
1113
|
ownerPromptDismissedSessionIds: partial.ownerPromptDismissedSessionIds ?? DEFAULTS.ownerPromptDismissedSessionIds
|
|
686
1114
|
};
|
|
687
1115
|
}
|
|
1116
|
+
normalizeAiGlobalSettings(partial) {
|
|
1117
|
+
const normalized = { ...partial ?? {} };
|
|
1118
|
+
delete normalized.contextCompression;
|
|
1119
|
+
return { ...DEFAULTS.aiGlobalSettings, ...normalized };
|
|
1120
|
+
}
|
|
688
1121
|
normalizeAiPreprocessConfig(partial) {
|
|
689
1122
|
const defaults = DEFAULTS.aiPreprocessConfig;
|
|
690
1123
|
const rules = Array.isArray(partial?.desensitizeRules) ? partial.desensitizeRules : [];
|
|
@@ -748,21 +1181,21 @@ var PreferencesManager = class {
|
|
|
748
1181
|
};
|
|
749
1182
|
}
|
|
750
1183
|
backupLegacyPreferences(rawContent) {
|
|
751
|
-
const backupDir =
|
|
752
|
-
if (!
|
|
753
|
-
|
|
1184
|
+
const backupDir = path5.join(path5.dirname(this.filePath), "backups");
|
|
1185
|
+
if (!fs5.existsSync(backupDir)) {
|
|
1186
|
+
fs5.mkdirSync(backupDir, { recursive: true });
|
|
754
1187
|
}
|
|
755
1188
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
756
|
-
const backupPath =
|
|
757
|
-
|
|
1189
|
+
const backupPath = path5.join(backupDir, `preferences-pre-desensitize-groups-${timestamp}.json`);
|
|
1190
|
+
fs5.writeFileSync(backupPath, rawContent, "utf-8");
|
|
758
1191
|
console.info(`[Preferences] Backed up legacy desensitize rules to ${backupPath}`);
|
|
759
1192
|
}
|
|
760
1193
|
writePreferences(preferences) {
|
|
761
|
-
const dir =
|
|
762
|
-
if (!
|
|
763
|
-
|
|
1194
|
+
const dir = path5.dirname(this.filePath);
|
|
1195
|
+
if (!fs5.existsSync(dir)) {
|
|
1196
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
764
1197
|
}
|
|
765
|
-
|
|
1198
|
+
fs5.writeFileSync(this.filePath, JSON.stringify(preferences, null, 2), "utf-8");
|
|
766
1199
|
}
|
|
767
1200
|
/**
|
|
768
1201
|
* Deep merge: arrays are replaced (not concatenated), objects are merged.
|
|
@@ -782,26 +1215,146 @@ var PreferencesManager = class {
|
|
|
782
1215
|
};
|
|
783
1216
|
|
|
784
1217
|
// ../../packages/node-runtime/src/merger/index.ts
|
|
1218
|
+
function createMessageScope(meta, members, sourceIndex) {
|
|
1219
|
+
const platform = meta?.platform || "unknown";
|
|
1220
|
+
const type = meta?.type || "unknown";
|
|
1221
|
+
if (meta?.groupId) return JSON.stringify([platform, type, "group", meta.groupId]);
|
|
1222
|
+
if (type === "group") return JSON.stringify([platform, type, "source", sourceIndex]);
|
|
1223
|
+
const memberIds = [...new Set(members.map((member) => member.platformId))].sort();
|
|
1224
|
+
if (memberIds.length > 0) {
|
|
1225
|
+
if (type === "private") {
|
|
1226
|
+
if (memberIds.length >= 2) return JSON.stringify([platform, type, "members", memberIds]);
|
|
1227
|
+
} else {
|
|
1228
|
+
return JSON.stringify([platform, type, "name-members", meta?.name || "", memberIds]);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return JSON.stringify([platform, type, "source", sourceIndex]);
|
|
1232
|
+
}
|
|
1233
|
+
function createMessageBridgeFamily(meta) {
|
|
1234
|
+
if (!meta || meta.groupId || meta.type !== "group" && meta.type !== "private") return void 0;
|
|
1235
|
+
return JSON.stringify([meta.platform || "unknown", meta.type]);
|
|
1236
|
+
}
|
|
1237
|
+
function createMessageIdNormalizer(scopes) {
|
|
1238
|
+
const uniqueScopes = [...new Set(scopes)];
|
|
1239
|
+
const scopeIndexes = new Map(uniqueScopes.map((scope, index) => [scope, index]));
|
|
1240
|
+
const namespaceMessageIds = uniqueScopes.length > 1;
|
|
1241
|
+
return (id, scope) => {
|
|
1242
|
+
if (!id || !namespaceMessageIds) return id;
|
|
1243
|
+
return `__chatlab_message_scope__${scopeIndexes.get(scope) ?? 0}__${encodeURIComponent(id)}`;
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
function createMessageScopeResolver(contexts) {
|
|
1247
|
+
const contextBySource = /* @__PURE__ */ new Map();
|
|
1248
|
+
const parents = /* @__PURE__ */ new Map();
|
|
1249
|
+
const firstSourceBySignature = /* @__PURE__ */ new Map();
|
|
1250
|
+
for (const context of contexts) {
|
|
1251
|
+
contextBySource.set(context.sourceIndex, context);
|
|
1252
|
+
parents.set(context.sourceIndex, context.sourceIndex);
|
|
1253
|
+
}
|
|
1254
|
+
const find = (sourceIndex) => {
|
|
1255
|
+
const parent = parents.get(sourceIndex) ?? sourceIndex;
|
|
1256
|
+
if (parent === sourceIndex) return sourceIndex;
|
|
1257
|
+
const root = find(parent);
|
|
1258
|
+
parents.set(sourceIndex, root);
|
|
1259
|
+
return root;
|
|
1260
|
+
};
|
|
1261
|
+
const union = (firstSourceIndex, secondSourceIndex) => {
|
|
1262
|
+
const firstRoot = find(firstSourceIndex);
|
|
1263
|
+
const secondRoot = find(secondSourceIndex);
|
|
1264
|
+
if (firstRoot === secondRoot) return;
|
|
1265
|
+
const root = Math.min(firstRoot, secondRoot);
|
|
1266
|
+
parents.set(firstRoot === root ? secondRoot : firstRoot, root);
|
|
1267
|
+
};
|
|
1268
|
+
return {
|
|
1269
|
+
addMessage(message, context) {
|
|
1270
|
+
if (!context.messageBridgeFamily || !message.platformMessageId) return;
|
|
1271
|
+
const fallbackKey = generateFallbackMessageKey({
|
|
1272
|
+
timestamp: message.timestamp,
|
|
1273
|
+
senderPlatformId: message.senderPlatformId,
|
|
1274
|
+
type: message.type,
|
|
1275
|
+
content: message.content ?? null,
|
|
1276
|
+
replyToMessageId: message.replyToMessageId
|
|
1277
|
+
});
|
|
1278
|
+
const signature = JSON.stringify([context.messageBridgeFamily, message.platformMessageId, fallbackKey]);
|
|
1279
|
+
const firstSourceIndex = firstSourceBySignature.get(signature);
|
|
1280
|
+
if (firstSourceIndex === void 0) {
|
|
1281
|
+
firstSourceBySignature.set(signature, context.sourceIndex);
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
union(firstSourceIndex, context.sourceIndex);
|
|
1285
|
+
},
|
|
1286
|
+
complete() {
|
|
1287
|
+
firstSourceBySignature.clear();
|
|
1288
|
+
},
|
|
1289
|
+
resolve(sourceIndex) {
|
|
1290
|
+
const rootContext = contextBySource.get(find(sourceIndex));
|
|
1291
|
+
return rootContext?.messageScope ?? JSON.stringify(["unknown", "source", sourceIndex]);
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
785
1295
|
function checkConflictsFromSources(dataSources) {
|
|
786
|
-
const
|
|
787
|
-
for (const { source, filename } of dataSources) {
|
|
1296
|
+
const preparedSources = dataSources.map(({ source, filename }, sourceIndex) => {
|
|
788
1297
|
const meta = source.getMeta();
|
|
789
|
-
const
|
|
1298
|
+
const members = source.getMembers();
|
|
1299
|
+
return {
|
|
1300
|
+
source,
|
|
1301
|
+
filename,
|
|
1302
|
+
sourceIndex,
|
|
1303
|
+
platform: meta?.platform || "unknown",
|
|
1304
|
+
messageScope: createMessageScope(meta, members, sourceIndex),
|
|
1305
|
+
messageBridgeFamily: createMessageBridgeFamily(meta)
|
|
1306
|
+
};
|
|
1307
|
+
});
|
|
1308
|
+
const allMessages = [];
|
|
1309
|
+
for (const { source, filename, sourceIndex, platform, messageScope, messageBridgeFamily } of preparedSources) {
|
|
790
1310
|
source.streamMessages(1e4, (messages) => {
|
|
791
1311
|
for (const msg of messages) {
|
|
792
|
-
allMessages.push({ msg, source: filename, platform });
|
|
1312
|
+
allMessages.push({ msg, source: filename, sourceIndex, platform, messageScope, messageBridgeFamily });
|
|
793
1313
|
}
|
|
794
1314
|
});
|
|
795
1315
|
}
|
|
796
|
-
|
|
1316
|
+
const result = detectConflictsInMessages(allMessages);
|
|
1317
|
+
const collidingIds = getCollidingPlatformIdsFromMessages(allMessages);
|
|
1318
|
+
const scopeResolver = createMessageScopeResolver(preparedSources);
|
|
1319
|
+
for (const message of allMessages) scopeResolver.addMessage(message.msg, message);
|
|
1320
|
+
scopeResolver.complete();
|
|
1321
|
+
const normalizeMessageId = createMessageIdNormalizer(
|
|
1322
|
+
preparedSources.map(({ sourceIndex }) => scopeResolver.resolve(sourceIndex))
|
|
1323
|
+
);
|
|
1324
|
+
const dedupState = createMessageDedupState();
|
|
1325
|
+
let totalMessages = 0;
|
|
1326
|
+
for (const { msg, sourceIndex, platform } of allMessages) {
|
|
1327
|
+
const messageScope = scopeResolver.resolve(sourceIndex);
|
|
1328
|
+
const senderPlatformId = normalizePlatformId(msg.senderPlatformId, platform, collidingIds);
|
|
1329
|
+
const duplicate = registerMessageAndCheckDuplicate(
|
|
1330
|
+
{
|
|
1331
|
+
platformMessageId: normalizeMessageId(msg.platformMessageId, messageScope),
|
|
1332
|
+
timestamp: msg.timestamp,
|
|
1333
|
+
senderPlatformId,
|
|
1334
|
+
type: msg.type,
|
|
1335
|
+
content: msg.content ?? null,
|
|
1336
|
+
replyToMessageId: normalizeMessageId(msg.replyToMessageId, messageScope)
|
|
1337
|
+
},
|
|
1338
|
+
dedupState
|
|
1339
|
+
);
|
|
1340
|
+
if (!duplicate) totalMessages++;
|
|
1341
|
+
}
|
|
1342
|
+
return { ...result, totalMessages };
|
|
797
1343
|
}
|
|
798
1344
|
function buildMergedOutput(dataSources, outputName) {
|
|
799
|
-
const metas = dataSources.map(({ source, filename }) =>
|
|
800
|
-
meta
|
|
801
|
-
members
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
1345
|
+
const metas = dataSources.map(({ source, filename }, sourceIndex) => {
|
|
1346
|
+
const meta = source.getMeta();
|
|
1347
|
+
const members = source.getMembers();
|
|
1348
|
+
return {
|
|
1349
|
+
meta,
|
|
1350
|
+
members,
|
|
1351
|
+
filename,
|
|
1352
|
+
source,
|
|
1353
|
+
sourceIndex,
|
|
1354
|
+
messageScope: createMessageScope(meta, members, sourceIndex),
|
|
1355
|
+
messageBridgeFamily: createMessageBridgeFamily(meta)
|
|
1356
|
+
};
|
|
1357
|
+
});
|
|
805
1358
|
const collidingIds = getCollidingPlatformIds(
|
|
806
1359
|
metas.map(({ meta, members }) => ({
|
|
807
1360
|
platform: meta?.platform || "unknown",
|
|
@@ -815,24 +1368,63 @@ function buildMergedOutput(dataSources, outputName) {
|
|
|
815
1368
|
})),
|
|
816
1369
|
collidingIds
|
|
817
1370
|
);
|
|
818
|
-
const
|
|
1371
|
+
const uniquePlatforms = [...new Set(metas.map(({ meta }) => meta?.platform || "unknown"))];
|
|
1372
|
+
const scopeResolver = createMessageScopeResolver(metas);
|
|
1373
|
+
for (const context of metas) {
|
|
1374
|
+
if (!context.messageBridgeFamily) continue;
|
|
1375
|
+
context.source.streamMessages(1e4, (messages) => {
|
|
1376
|
+
for (const message of messages) scopeResolver.addMessage(message, context);
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
scopeResolver.complete();
|
|
1380
|
+
const normalizeMessageId = createMessageIdNormalizer(
|
|
1381
|
+
metas.map(({ sourceIndex }) => scopeResolver.resolve(sourceIndex))
|
|
1382
|
+
);
|
|
1383
|
+
const dedupState = createMessageDedupState();
|
|
1384
|
+
const fallbackOnlyMessageIndexes = /* @__PURE__ */ new Map();
|
|
819
1385
|
const mergedMessages = [];
|
|
820
|
-
for (const { source, meta } of metas) {
|
|
1386
|
+
for (const { source, meta, sourceIndex } of metas) {
|
|
821
1387
|
const platform2 = meta?.platform || "unknown";
|
|
1388
|
+
const messageScope = scopeResolver.resolve(sourceIndex);
|
|
822
1389
|
source.streamMessages(1e4, (messages) => {
|
|
823
1390
|
for (const msg of messages) {
|
|
824
1391
|
const nid = normalizePlatformId(msg.senderPlatformId, platform2, collidingIds);
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
-
|
|
1392
|
+
const platformMessageId = normalizeMessageId(msg.platformMessageId, messageScope);
|
|
1393
|
+
const replyToMessageId = normalizeMessageId(msg.replyToMessageId, messageScope);
|
|
1394
|
+
const dedupMessage = {
|
|
1395
|
+
platformMessageId,
|
|
1396
|
+
timestamp: msg.timestamp,
|
|
1397
|
+
senderPlatformId: nid,
|
|
1398
|
+
type: msg.type,
|
|
1399
|
+
content: msg.content ?? null,
|
|
1400
|
+
replyToMessageId
|
|
1401
|
+
};
|
|
1402
|
+
const fallbackKey = generateFallbackMessageKey(dedupMessage);
|
|
1403
|
+
const shouldBackfillId = Boolean(
|
|
1404
|
+
platformMessageId && !dedupState.platformMessageIds.has(platformMessageId) && dedupState.fallbackOnlyKeys.has(fallbackKey)
|
|
1405
|
+
);
|
|
1406
|
+
if (registerMessageAndCheckDuplicate(dedupMessage, dedupState)) {
|
|
1407
|
+
if (shouldBackfillId) {
|
|
1408
|
+
const retainedIndex2 = fallbackOnlyMessageIndexes.get(fallbackKey);
|
|
1409
|
+
if (retainedIndex2 !== void 0) {
|
|
1410
|
+
mergedMessages[retainedIndex2].platformMessageId = platformMessageId;
|
|
1411
|
+
fallbackOnlyMessageIndexes.delete(fallbackKey);
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
continue;
|
|
1415
|
+
}
|
|
1416
|
+
const retainedIndex = mergedMessages.length;
|
|
828
1417
|
mergedMessages.push({
|
|
1418
|
+
platformMessageId,
|
|
829
1419
|
sender: nid,
|
|
830
1420
|
accountName: msg.senderAccountName,
|
|
831
1421
|
groupNickname: msg.senderGroupNickname,
|
|
832
1422
|
timestamp: msg.timestamp,
|
|
833
1423
|
type: msg.type,
|
|
834
|
-
content: msg.content
|
|
1424
|
+
content: msg.content,
|
|
1425
|
+
replyToMessageId
|
|
835
1426
|
});
|
|
1427
|
+
if (!platformMessageId) fallbackOnlyMessageIndexes.set(fallbackKey, retainedIndex);
|
|
836
1428
|
}
|
|
837
1429
|
});
|
|
838
1430
|
}
|
|
@@ -842,11 +1434,13 @@ function buildMergedOutput(dataSources, outputName) {
|
|
|
842
1434
|
platform: source.getMeta()?.platform || "unknown",
|
|
843
1435
|
messageCount: source.getMessageCount()
|
|
844
1436
|
}));
|
|
845
|
-
const uniquePlatforms = [...new Set(metas.map(({ meta }) => meta?.platform || "unknown"))];
|
|
846
1437
|
const platform = uniquePlatforms.length === 1 ? uniquePlatforms[0] : "mixed";
|
|
847
1438
|
const groupIds = new Set(metas.map(({ meta }) => meta?.groupId).filter(Boolean));
|
|
848
1439
|
const groupId = groupIds.size === 1 ? metas.find(({ meta }) => meta?.groupId)?.meta?.groupId : void 0;
|
|
849
1440
|
const groupAvatar = groupId ? metas.filter(({ meta }) => meta?.groupId === groupId).pop()?.meta?.groupAvatar : void 0;
|
|
1441
|
+
const ownerIds = new Set(metas.map(({ meta }) => meta?.ownerId).filter((id) => Boolean(id)));
|
|
1442
|
+
const ownerCandidate = uniquePlatforms.length === 1 && ownerIds.size === 1 ? [...ownerIds][0] : void 0;
|
|
1443
|
+
const ownerId = ownerCandidate && memberMap.has(ownerCandidate) ? ownerCandidate : void 0;
|
|
850
1444
|
const chatLabData = {
|
|
851
1445
|
chatlab: {
|
|
852
1446
|
version: CHATLAB_FORMAT_VERSION,
|
|
@@ -860,7 +1454,8 @@ function buildMergedOutput(dataSources, outputName) {
|
|
|
860
1454
|
type: metas[0]?.meta?.type || "group",
|
|
861
1455
|
sources,
|
|
862
1456
|
groupId,
|
|
863
|
-
groupAvatar
|
|
1457
|
+
groupAvatar,
|
|
1458
|
+
ownerId
|
|
864
1459
|
},
|
|
865
1460
|
members: Array.from(memberMap.values()),
|
|
866
1461
|
messages: mergedMessages
|
|
@@ -882,7 +1477,7 @@ function* serializeChatLabToJsonl(data) {
|
|
|
882
1477
|
}
|
|
883
1478
|
|
|
884
1479
|
// ../../packages/node-runtime/src/services/analytics.ts
|
|
885
|
-
import * as
|
|
1480
|
+
import * as path6 from "path";
|
|
886
1481
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
887
1482
|
var DEFAULT_DATA = {
|
|
888
1483
|
lastReportDate: null,
|
|
@@ -994,7 +1589,7 @@ var AnalyticsService = class {
|
|
|
994
1589
|
// Daily-active deduplication is intentionally process-local unless concurrent runtimes become supported.
|
|
995
1590
|
dailyActivePromise = null;
|
|
996
1591
|
constructor(systemDir, options) {
|
|
997
|
-
this.dataPath =
|
|
1592
|
+
this.dataPath = path6.join(systemDir, "analytics.json");
|
|
998
1593
|
this.options = {
|
|
999
1594
|
...options,
|
|
1000
1595
|
umami: options.umami ?? getUmamiConfigFromEnv()
|
|
@@ -1156,8 +1751,8 @@ var AnalyticsService = class {
|
|
|
1156
1751
|
};
|
|
1157
1752
|
|
|
1158
1753
|
// ../../packages/node-runtime/src/services/demo-import.ts
|
|
1159
|
-
import * as
|
|
1160
|
-
import * as
|
|
1754
|
+
import * as fs6 from "fs";
|
|
1755
|
+
import * as path7 from "path";
|
|
1161
1756
|
var DEMO_BASE_URL = "https://chatlab.fun/assets/demo";
|
|
1162
1757
|
var DEMO_FILES = ["demo-group.json", "demo-private-B-wukong.json"];
|
|
1163
1758
|
async function importDemoSessions(options) {
|
|
@@ -1189,8 +1784,8 @@ async function importDemoSessions(options) {
|
|
|
1189
1784
|
}
|
|
1190
1785
|
const rebased = rebaseChatLabDemoDocuments(downloaded, options.now?.() ?? /* @__PURE__ */ new Date(), options.targetTimeZone);
|
|
1191
1786
|
const localPaths = rebased.documents.map((document, index) => {
|
|
1192
|
-
const localPath =
|
|
1193
|
-
|
|
1787
|
+
const localPath = path7.join(createdTempDir, DEMO_FILES[index]);
|
|
1788
|
+
fs6.writeFileSync(localPath, document, "utf8");
|
|
1194
1789
|
return localPath;
|
|
1195
1790
|
});
|
|
1196
1791
|
appLogger.info("demo-import", "Demo timeline prepared", {
|
|
@@ -1274,7 +1869,6 @@ __export(semantic_index_exports, {
|
|
|
1274
1869
|
composeChunkId: () => composeChunkId,
|
|
1275
1870
|
computeChunkerConfigHash: () => computeChunkerConfigHash,
|
|
1276
1871
|
computeDbPathHash: () => computeDbPathHash,
|
|
1277
|
-
createChatDbFtsSearcher: () => createChatDbFtsSearcher,
|
|
1278
1872
|
createChatDbMessageRangeReader: () => createChatDbMessageRangeReader,
|
|
1279
1873
|
createChatDbMessageSource: () => createChatDbMessageSource,
|
|
1280
1874
|
createEmbedder: () => createEmbedder,
|
|
@@ -1287,24 +1881,22 @@ __export(semantic_index_exports, {
|
|
|
1287
1881
|
deriveParentId: () => deriveParentId,
|
|
1288
1882
|
embedding: () => embedding_exports,
|
|
1289
1883
|
estimateTokens: () => estimateTokens,
|
|
1290
|
-
extractFtsKeywords: () => extractFtsKeywords,
|
|
1291
1884
|
formatEvidenceMessages: () => formatEvidenceMessages,
|
|
1292
|
-
hybridSearch: () => hybridSearch,
|
|
1293
1885
|
isSemanticIndexConfigured: () => isSemanticIndexConfigured,
|
|
1294
1886
|
isSemanticVoid: () => isSemanticVoid,
|
|
1295
1887
|
parseParentBounds: () => parseParentBounds,
|
|
1296
1888
|
persistSemanticIndexConfig: () => persistSemanticIndexConfig,
|
|
1297
|
-
reciprocalRankFusion: () => reciprocalRankFusion,
|
|
1298
1889
|
resolveModelId: () => resolveModelId,
|
|
1299
1890
|
resolveSemanticIndexApiKeySet: () => resolveSemanticIndexApiKeySet,
|
|
1300
1891
|
runWarmup: () => runWarmup,
|
|
1892
|
+
semanticSearch: () => semanticSearch,
|
|
1301
1893
|
snapshotPathProvider: () => snapshotPathProvider,
|
|
1302
1894
|
vecTableName: () => vecTableName,
|
|
1303
1895
|
vecTableSchema: () => vecTableSchema
|
|
1304
1896
|
});
|
|
1305
1897
|
|
|
1306
1898
|
// ../../packages/node-runtime/src/semantic-index/worker-client.ts
|
|
1307
|
-
import
|
|
1899
|
+
import path8 from "path";
|
|
1308
1900
|
|
|
1309
1901
|
// ../../packages/node-runtime/src/semantic-index/worker-thread-transport.ts
|
|
1310
1902
|
import { Worker } from "worker_threads";
|
|
@@ -1686,7 +2278,7 @@ function createSemanticIndexWorkerClient(options) {
|
|
|
1686
2278
|
}
|
|
1687
2279
|
function createSemanticIndexWorkerRuntimeClient(options) {
|
|
1688
2280
|
const configStore = new SemanticIndexConfigStore(
|
|
1689
|
-
|
|
2281
|
+
path8.join(options.pathProvider.getAiDataDir(), SEMANTIC_INDEX_CONFIG_FILE)
|
|
1690
2282
|
);
|
|
1691
2283
|
return createSemanticIndexWorkerClient({
|
|
1692
2284
|
configStore,
|
|
@@ -1741,7 +2333,23 @@ export {
|
|
|
1741
2333
|
NodePathProvider,
|
|
1742
2334
|
getDefaultNodeUserDataDir,
|
|
1743
2335
|
getSystemLogsDir,
|
|
2336
|
+
initNlpDir,
|
|
2337
|
+
getNlpDir,
|
|
2338
|
+
getJieba,
|
|
2339
|
+
clearJiebaInstance,
|
|
2340
|
+
segment,
|
|
2341
|
+
batchSegmentWithFrequency,
|
|
2342
|
+
collectPosTagStats,
|
|
2343
|
+
getPosTagDefinitions,
|
|
1744
2344
|
createJiebaNlpProvider,
|
|
2345
|
+
computeWordFrequency,
|
|
2346
|
+
segmentText,
|
|
2347
|
+
isDictDownloaded,
|
|
2348
|
+
getDictList,
|
|
2349
|
+
loadDictBuffer,
|
|
2350
|
+
downloadDict,
|
|
2351
|
+
deleteDict,
|
|
2352
|
+
ensureDefaultDict,
|
|
1745
2353
|
PreferencesManager,
|
|
1746
2354
|
checkConflictsFromSources,
|
|
1747
2355
|
buildMergedOutput,
|
|
@@ -1751,4 +2359,4 @@ export {
|
|
|
1751
2359
|
createSemanticIndexWorkerRuntimeClient,
|
|
1752
2360
|
semantic_index_exports
|
|
1753
2361
|
};
|
|
1754
|
-
//# sourceMappingURL=chunk-
|
|
2362
|
+
//# sourceMappingURL=chunk-DC7IUDNV.mjs.map
|