chattercatcher 0.1.0 → 0.1.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.
- package/README.md +36 -0
- package/assets/readme/feishu-community-qr.png +0 -0
- package/dist/cli.js +173 -129
- package/dist/cli.js.map +1 -1
- package/dist/index.js +166 -126
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,150 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/config/paths.ts
|
|
12
|
+
import os2 from "os";
|
|
13
|
+
import path2 from "path";
|
|
14
|
+
function getChatterCatcherHome() {
|
|
15
|
+
return process.env.CHATTERCATCHER_HOME || path2.join(os2.homedir(), ".chattercatcher");
|
|
16
|
+
}
|
|
17
|
+
function resolveHomePath(value) {
|
|
18
|
+
if (value === "~") {
|
|
19
|
+
return os2.homedir();
|
|
20
|
+
}
|
|
21
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
22
|
+
return path2.join(os2.homedir(), value.slice(2));
|
|
23
|
+
}
|
|
24
|
+
return path2.resolve(value);
|
|
25
|
+
}
|
|
26
|
+
function getConfigPath() {
|
|
27
|
+
return path2.join(getChatterCatcherHome(), "config.json");
|
|
28
|
+
}
|
|
29
|
+
function getSecretsPath() {
|
|
30
|
+
return path2.join(getChatterCatcherHome(), "secrets.json");
|
|
31
|
+
}
|
|
32
|
+
var init_paths = __esm({
|
|
33
|
+
"src/config/paths.ts"() {
|
|
34
|
+
"use strict";
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// src/rag/lancedb-store.ts
|
|
39
|
+
var lancedb_store_exports = {};
|
|
40
|
+
__export(lancedb_store_exports, {
|
|
41
|
+
LanceDbVectorStore: () => LanceDbVectorStore,
|
|
42
|
+
getLanceDbPath: () => getLanceDbPath
|
|
43
|
+
});
|
|
44
|
+
import * as lancedb from "@lancedb/lancedb";
|
|
45
|
+
import fs5 from "fs/promises";
|
|
46
|
+
import path8 from "path";
|
|
47
|
+
function getLanceDbPath(config) {
|
|
48
|
+
return path8.join(resolveHomePath(config.storage.dataDir), "vector", "lancedb");
|
|
49
|
+
}
|
|
50
|
+
function toRow(record) {
|
|
51
|
+
return {
|
|
52
|
+
id: record.id,
|
|
53
|
+
vector: record.vector,
|
|
54
|
+
text: record.evidence.text,
|
|
55
|
+
source_json: JSON.stringify(record.evidence.source)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function toLanceData(rows) {
|
|
59
|
+
return rows.map((row) => ({
|
|
60
|
+
id: row.id,
|
|
61
|
+
vector: row.vector,
|
|
62
|
+
text: row.text,
|
|
63
|
+
source_json: row.source_json
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
function escapeSqlString(value) {
|
|
67
|
+
return value.replace(/'/g, "''");
|
|
68
|
+
}
|
|
69
|
+
function toEvidence(row) {
|
|
70
|
+
const distance = row._distance ?? 0;
|
|
71
|
+
const vectorScore = 1 / (1 + Math.max(0, distance));
|
|
72
|
+
return {
|
|
73
|
+
id: row.id,
|
|
74
|
+
text: row.text,
|
|
75
|
+
score: vectorScore,
|
|
76
|
+
vectorScore,
|
|
77
|
+
source: JSON.parse(row.source_json)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
var DEFAULT_TABLE_NAME, LanceDbVectorStore;
|
|
81
|
+
var init_lancedb_store = __esm({
|
|
82
|
+
"src/rag/lancedb-store.ts"() {
|
|
83
|
+
"use strict";
|
|
84
|
+
init_paths();
|
|
85
|
+
DEFAULT_TABLE_NAME = "message_chunks";
|
|
86
|
+
LanceDbVectorStore = class _LanceDbVectorStore {
|
|
87
|
+
constructor(connection, tableName) {
|
|
88
|
+
this.connection = connection;
|
|
89
|
+
this.tableName = tableName;
|
|
90
|
+
}
|
|
91
|
+
connection;
|
|
92
|
+
tableName;
|
|
93
|
+
static async connect(uri, tableName = DEFAULT_TABLE_NAME) {
|
|
94
|
+
await fs5.mkdir(uri, { recursive: true });
|
|
95
|
+
const connection = await lancedb.connect(uri);
|
|
96
|
+
return new _LanceDbVectorStore(connection, tableName);
|
|
97
|
+
}
|
|
98
|
+
static async connectFromConfig(config, tableName = DEFAULT_TABLE_NAME) {
|
|
99
|
+
return _LanceDbVectorStore.connect(getLanceDbPath(config), tableName);
|
|
100
|
+
}
|
|
101
|
+
close() {
|
|
102
|
+
this.connection.close();
|
|
103
|
+
}
|
|
104
|
+
async upsert(records) {
|
|
105
|
+
if (records.length === 0) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const rows = records.map(toRow);
|
|
109
|
+
const data = toLanceData(rows);
|
|
110
|
+
const table = await this.ensureTable(data);
|
|
111
|
+
const ids = rows.map((row) => `'${escapeSqlString(row.id)}'`).join(", ");
|
|
112
|
+
await table.delete(`id IN (${ids})`);
|
|
113
|
+
await table.add(data);
|
|
114
|
+
}
|
|
115
|
+
async search(vector, limit) {
|
|
116
|
+
const table = await this.openTableIfExists();
|
|
117
|
+
if (!table) {
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
const rows = await table.vectorSearch(vector).limit(limit).toArray();
|
|
121
|
+
return rows.map(toEvidence);
|
|
122
|
+
}
|
|
123
|
+
async count() {
|
|
124
|
+
const table = await this.openTableIfExists();
|
|
125
|
+
if (!table) {
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
return table.countRows();
|
|
129
|
+
}
|
|
130
|
+
async ensureTable(initialRows) {
|
|
131
|
+
const table = await this.openTableIfExists();
|
|
132
|
+
if (table) {
|
|
133
|
+
return table;
|
|
134
|
+
}
|
|
135
|
+
return this.connection.createTable(this.tableName, initialRows);
|
|
136
|
+
}
|
|
137
|
+
async openTableIfExists() {
|
|
138
|
+
const tableNames = await this.connection.tableNames();
|
|
139
|
+
if (!tableNames.includes(this.tableName)) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return this.connection.openTable(this.tableName);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
1
148
|
// src/config/schema.ts
|
|
2
149
|
import os from "os";
|
|
3
150
|
import path from "path";
|
|
@@ -64,30 +211,7 @@ function createDefaultSecrets() {
|
|
|
64
211
|
// src/config/store.ts
|
|
65
212
|
import fs from "fs/promises";
|
|
66
213
|
import path3 from "path";
|
|
67
|
-
|
|
68
|
-
// src/config/paths.ts
|
|
69
|
-
import os2 from "os";
|
|
70
|
-
import path2 from "path";
|
|
71
|
-
function getChatterCatcherHome() {
|
|
72
|
-
return process.env.CHATTERCATCHER_HOME || path2.join(os2.homedir(), ".chattercatcher");
|
|
73
|
-
}
|
|
74
|
-
function resolveHomePath(value) {
|
|
75
|
-
if (value === "~") {
|
|
76
|
-
return os2.homedir();
|
|
77
|
-
}
|
|
78
|
-
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
79
|
-
return path2.join(os2.homedir(), value.slice(2));
|
|
80
|
-
}
|
|
81
|
-
return path2.resolve(value);
|
|
82
|
-
}
|
|
83
|
-
function getConfigPath() {
|
|
84
|
-
return path2.join(getChatterCatcherHome(), "config.json");
|
|
85
|
-
}
|
|
86
|
-
function getSecretsPath() {
|
|
87
|
-
return path2.join(getChatterCatcherHome(), "secrets.json");
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// src/config/store.ts
|
|
214
|
+
init_paths();
|
|
91
215
|
async function readJsonFile(filePath, fallback) {
|
|
92
216
|
try {
|
|
93
217
|
const raw = await fs.readFile(filePath, "utf8");
|
|
@@ -151,6 +275,7 @@ function resolveEmbeddingApiKey(input) {
|
|
|
151
275
|
}
|
|
152
276
|
|
|
153
277
|
// src/data/deletion.ts
|
|
278
|
+
init_paths();
|
|
154
279
|
import fs2 from "fs/promises";
|
|
155
280
|
import path4 from "path";
|
|
156
281
|
function emptyResult(targetType, targetId) {
|
|
@@ -276,6 +401,7 @@ async function deleteLocalData(input) {
|
|
|
276
401
|
}
|
|
277
402
|
|
|
278
403
|
// src/db/database.ts
|
|
404
|
+
init_paths();
|
|
279
405
|
import Database from "better-sqlite3";
|
|
280
406
|
import fs3 from "fs";
|
|
281
407
|
import path5 from "path";
|
|
@@ -355,6 +481,7 @@ function migrateDatabase(database) {
|
|
|
355
481
|
}
|
|
356
482
|
|
|
357
483
|
// src/doctor/checks.ts
|
|
484
|
+
init_paths();
|
|
358
485
|
import fs6 from "fs/promises";
|
|
359
486
|
|
|
360
487
|
// src/files/jobs.ts
|
|
@@ -497,6 +624,7 @@ var FileJobRepository = class {
|
|
|
497
624
|
};
|
|
498
625
|
|
|
499
626
|
// src/gateway/runtime.ts
|
|
627
|
+
init_paths();
|
|
500
628
|
import fs4 from "fs";
|
|
501
629
|
import path7 from "path";
|
|
502
630
|
function getGatewayPidPath() {
|
|
@@ -1090,104 +1218,6 @@ var HybridRetriever = class {
|
|
|
1090
1218
|
}
|
|
1091
1219
|
};
|
|
1092
1220
|
|
|
1093
|
-
// src/rag/lancedb-store.ts
|
|
1094
|
-
import * as lancedb from "@lancedb/lancedb";
|
|
1095
|
-
import fs5 from "fs/promises";
|
|
1096
|
-
import path8 from "path";
|
|
1097
|
-
var DEFAULT_TABLE_NAME = "message_chunks";
|
|
1098
|
-
function getLanceDbPath(config) {
|
|
1099
|
-
return path8.join(resolveHomePath(config.storage.dataDir), "vector", "lancedb");
|
|
1100
|
-
}
|
|
1101
|
-
function toRow(record) {
|
|
1102
|
-
return {
|
|
1103
|
-
id: record.id,
|
|
1104
|
-
vector: record.vector,
|
|
1105
|
-
text: record.evidence.text,
|
|
1106
|
-
source_json: JSON.stringify(record.evidence.source)
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
function toLanceData(rows) {
|
|
1110
|
-
return rows.map((row) => ({
|
|
1111
|
-
id: row.id,
|
|
1112
|
-
vector: row.vector,
|
|
1113
|
-
text: row.text,
|
|
1114
|
-
source_json: row.source_json
|
|
1115
|
-
}));
|
|
1116
|
-
}
|
|
1117
|
-
function escapeSqlString(value) {
|
|
1118
|
-
return value.replace(/'/g, "''");
|
|
1119
|
-
}
|
|
1120
|
-
function toEvidence(row) {
|
|
1121
|
-
const distance = row._distance ?? 0;
|
|
1122
|
-
const vectorScore = 1 / (1 + Math.max(0, distance));
|
|
1123
|
-
return {
|
|
1124
|
-
id: row.id,
|
|
1125
|
-
text: row.text,
|
|
1126
|
-
score: vectorScore,
|
|
1127
|
-
vectorScore,
|
|
1128
|
-
source: JSON.parse(row.source_json)
|
|
1129
|
-
};
|
|
1130
|
-
}
|
|
1131
|
-
var LanceDbVectorStore = class _LanceDbVectorStore {
|
|
1132
|
-
constructor(connection, tableName) {
|
|
1133
|
-
this.connection = connection;
|
|
1134
|
-
this.tableName = tableName;
|
|
1135
|
-
}
|
|
1136
|
-
connection;
|
|
1137
|
-
tableName;
|
|
1138
|
-
static async connect(uri, tableName = DEFAULT_TABLE_NAME) {
|
|
1139
|
-
await fs5.mkdir(uri, { recursive: true });
|
|
1140
|
-
const connection = await lancedb.connect(uri);
|
|
1141
|
-
return new _LanceDbVectorStore(connection, tableName);
|
|
1142
|
-
}
|
|
1143
|
-
static async connectFromConfig(config, tableName = DEFAULT_TABLE_NAME) {
|
|
1144
|
-
return _LanceDbVectorStore.connect(getLanceDbPath(config), tableName);
|
|
1145
|
-
}
|
|
1146
|
-
close() {
|
|
1147
|
-
this.connection.close();
|
|
1148
|
-
}
|
|
1149
|
-
async upsert(records) {
|
|
1150
|
-
if (records.length === 0) {
|
|
1151
|
-
return;
|
|
1152
|
-
}
|
|
1153
|
-
const rows = records.map(toRow);
|
|
1154
|
-
const data = toLanceData(rows);
|
|
1155
|
-
const table = await this.ensureTable(data);
|
|
1156
|
-
const ids = rows.map((row) => `'${escapeSqlString(row.id)}'`).join(", ");
|
|
1157
|
-
await table.delete(`id IN (${ids})`);
|
|
1158
|
-
await table.add(data);
|
|
1159
|
-
}
|
|
1160
|
-
async search(vector, limit) {
|
|
1161
|
-
const table = await this.openTableIfExists();
|
|
1162
|
-
if (!table) {
|
|
1163
|
-
return [];
|
|
1164
|
-
}
|
|
1165
|
-
const rows = await table.vectorSearch(vector).limit(limit).toArray();
|
|
1166
|
-
return rows.map(toEvidence);
|
|
1167
|
-
}
|
|
1168
|
-
async count() {
|
|
1169
|
-
const table = await this.openTableIfExists();
|
|
1170
|
-
if (!table) {
|
|
1171
|
-
return 0;
|
|
1172
|
-
}
|
|
1173
|
-
return table.countRows();
|
|
1174
|
-
}
|
|
1175
|
-
async ensureTable(initialRows) {
|
|
1176
|
-
const table = await this.openTableIfExists();
|
|
1177
|
-
if (table) {
|
|
1178
|
-
return table;
|
|
1179
|
-
}
|
|
1180
|
-
return this.connection.createTable(this.tableName, initialRows);
|
|
1181
|
-
}
|
|
1182
|
-
async openTableIfExists() {
|
|
1183
|
-
const tableNames = await this.connection.tableNames();
|
|
1184
|
-
if (!tableNames.includes(this.tableName)) {
|
|
1185
|
-
return null;
|
|
1186
|
-
}
|
|
1187
|
-
return this.connection.openTable(this.tableName);
|
|
1188
|
-
}
|
|
1189
|
-
};
|
|
1190
|
-
|
|
1191
1221
|
// src/rag/message-retriever.ts
|
|
1192
1222
|
function toEvidenceSource(result) {
|
|
1193
1223
|
if (result.messageType === "file") {
|
|
@@ -1248,7 +1278,8 @@ async function createHybridRetriever(input) {
|
|
|
1248
1278
|
const retrievers = [new MessageFtsRetriever(input.messages, { excludeMessageIds: input.excludeMessageIds })];
|
|
1249
1279
|
const closers = [];
|
|
1250
1280
|
if (hasEmbeddingConfig(input.config, input.secrets)) {
|
|
1251
|
-
const
|
|
1281
|
+
const { LanceDbVectorStore: LanceDbVectorStore2 } = await Promise.resolve().then(() => (init_lancedb_store(), lancedb_store_exports));
|
|
1282
|
+
const vectorStore = await LanceDbVectorStore2.connectFromConfig(input.config);
|
|
1252
1283
|
retrievers.push(new VectorRetriever(createEmbeddingModel(input.config, input.secrets), vectorStore));
|
|
1253
1284
|
closers.push(() => vectorStore.close());
|
|
1254
1285
|
}
|
|
@@ -1350,9 +1381,10 @@ async function checkFilePipeline(config) {
|
|
|
1350
1381
|
async function checkLanceDb(config) {
|
|
1351
1382
|
let store = null;
|
|
1352
1383
|
try {
|
|
1353
|
-
|
|
1384
|
+
const { getLanceDbPath: getLanceDbPath2, LanceDbVectorStore: LanceDbVectorStore2 } = await Promise.resolve().then(() => (init_lancedb_store(), lancedb_store_exports));
|
|
1385
|
+
store = await LanceDbVectorStore2.connectFromConfig(config);
|
|
1354
1386
|
const count = await store.count();
|
|
1355
|
-
return pass("LanceDB", `${
|
|
1387
|
+
return pass("LanceDB", `${getLanceDbPath2(config)}\uFF1Bvectors=${count}`);
|
|
1356
1388
|
} catch (error) {
|
|
1357
1389
|
return fail("LanceDB", error instanceof Error ? error.message : String(error));
|
|
1358
1390
|
} finally {
|
|
@@ -1397,6 +1429,7 @@ function formatDoctorChecks(checks) {
|
|
|
1397
1429
|
}
|
|
1398
1430
|
|
|
1399
1431
|
// src/export/data-export.ts
|
|
1432
|
+
init_paths();
|
|
1400
1433
|
import fs7 from "fs/promises";
|
|
1401
1434
|
import path9 from "path";
|
|
1402
1435
|
function parseJsonObject(value) {
|
|
@@ -2313,6 +2346,7 @@ function normalizeFeishuReceiveMessageEvent(payload) {
|
|
|
2313
2346
|
}
|
|
2314
2347
|
|
|
2315
2348
|
// src/feishu/resource-downloader.ts
|
|
2349
|
+
init_paths();
|
|
2316
2350
|
import * as lark3 from "@larksuiteoapi/node-sdk";
|
|
2317
2351
|
import fs9 from "fs/promises";
|
|
2318
2352
|
import path11 from "path";
|
|
@@ -2378,6 +2412,7 @@ var FeishuResourceDownloader = class _FeishuResourceDownloader {
|
|
|
2378
2412
|
};
|
|
2379
2413
|
|
|
2380
2414
|
// src/files/ingest.ts
|
|
2415
|
+
init_paths();
|
|
2381
2416
|
import crypto3 from "crypto";
|
|
2382
2417
|
import fs11 from "fs/promises";
|
|
2383
2418
|
import path13 from "path";
|
|
@@ -2595,6 +2630,7 @@ var GatewayIngestor = class {
|
|
|
2595
2630
|
};
|
|
2596
2631
|
|
|
2597
2632
|
// src/logs/reader.ts
|
|
2633
|
+
init_paths();
|
|
2598
2634
|
import fs12 from "fs/promises";
|
|
2599
2635
|
import { watch } from "fs";
|
|
2600
2636
|
import path14 from "path";
|
|
@@ -2764,6 +2800,9 @@ function toEvidenceSource2(chunk) {
|
|
|
2764
2800
|
};
|
|
2765
2801
|
}
|
|
2766
2802
|
|
|
2803
|
+
// src/index.ts
|
|
2804
|
+
init_lancedb_store();
|
|
2805
|
+
|
|
2767
2806
|
// src/rag/manual-index.ts
|
|
2768
2807
|
async function processMessagesNow(input) {
|
|
2769
2808
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2777,7 +2816,8 @@ async function processMessagesNow(input) {
|
|
|
2777
2816
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2778
2817
|
};
|
|
2779
2818
|
}
|
|
2780
|
-
const
|
|
2819
|
+
const { LanceDbVectorStore: LanceDbVectorStore2 } = await Promise.resolve().then(() => (init_lancedb_store(), lancedb_store_exports));
|
|
2820
|
+
const vectorStore = await LanceDbVectorStore2.connectFromConfig(input.config);
|
|
2781
2821
|
try {
|
|
2782
2822
|
const stats = await indexMessageChunks({
|
|
2783
2823
|
messages: new MessageRepository(input.database),
|