@diegoaltoworks/chatter 1.0.0 → 2.1.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/README.md +3 -1
- package/dist/channels/gates.d.ts +21 -2
- package/dist/channels/gates.d.ts.map +1 -1
- package/dist/channels/index.d.ts +5 -3
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +31 -13
- package/dist/channels/index.mjs +30 -13
- package/dist/channels/matrix/channel.d.ts +2 -0
- package/dist/channels/matrix/channel.d.ts.map +1 -1
- package/dist/channels/matrix/handler.d.ts +9 -0
- package/dist/channels/matrix/handler.d.ts.map +1 -1
- package/dist/channels/matrix/index.d.ts +1 -1
- package/dist/channels/matrix/index.d.ts.map +1 -1
- package/dist/channels/matrix/index.js +75 -20
- package/dist/channels/matrix/index.mjs +74 -20
- package/dist/channels/matrix/updates.d.ts +8 -2
- package/dist/channels/matrix/updates.d.ts.map +1 -1
- package/dist/channels/pipeline.d.ts +34 -4
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/polling.d.ts +11 -0
- package/dist/channels/polling.d.ts.map +1 -1
- package/dist/channels/telegram/channel.d.ts +2 -0
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/handler.d.ts +9 -0
- package/dist/channels/telegram/handler.d.ts.map +1 -1
- package/dist/channels/telegram/index.d.ts +1 -1
- package/dist/channels/telegram/index.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +73 -24
- package/dist/channels/telegram/index.mjs +72 -24
- package/dist/channels/telegram/updates.d.ts +8 -2
- package/dist/channels/telegram/updates.d.ts.map +1 -1
- package/dist/channels/telegram/webhook.d.ts +10 -0
- package/dist/channels/telegram/webhook.d.ts.map +1 -1
- package/dist/channels/whatsapp/channel.d.ts +8 -0
- package/dist/channels/whatsapp/channel.d.ts.map +1 -1
- package/dist/channels/whatsapp/inbound.d.ts +2 -0
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +45 -18
- package/dist/channels/whatsapp/index.mjs +45 -18
- package/dist/core/answer.d.ts +9 -2
- package/dist/core/answer.d.ts.map +1 -1
- package/dist/core/chunking.d.ts +31 -0
- package/dist/core/chunking.d.ts.map +1 -0
- package/dist/core/guardrails.d.ts +11 -1
- package/dist/core/guardrails.d.ts.map +1 -1
- package/dist/core/llm.d.ts +3 -1
- package/dist/core/llm.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +39 -0
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/history/index.js +12 -9
- package/dist/history/index.mjs +12 -9
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +261 -52
- package/dist/index.mjs +254 -47
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +217 -30
- package/dist/mcp-server.mjs +216 -29
- package/dist/personas/index.d.ts +1 -1
- package/dist/personas/index.d.ts.map +1 -1
- package/dist/personas/index.js +21 -7
- package/dist/personas/index.mjs +21 -7
- package/dist/personas/resolver.d.ts +35 -8
- package/dist/personas/resolver.d.ts.map +1 -1
- package/dist/personas/timeContext.d.ts.map +1 -1
- package/dist/routes/demo.d.ts.map +1 -1
- package/dist/routes/openai.d.ts.map +1 -1
- package/dist/routes/private.d.ts.map +1 -1
- package/dist/routes/public.d.ts.map +1 -1
- package/dist/scheduler/index.js +12 -9
- package/dist/scheduler/index.mjs +12 -9
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +251 -50
- package/dist/server.mjs +246 -45
- package/dist/types.d.ts +39 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -13
package/dist/index.mjs
CHANGED
|
@@ -72,6 +72,126 @@ var init_buildLock = __esm({
|
|
|
72
72
|
}
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
+
// src/core/chunking.ts
|
|
76
|
+
function headingOf(line) {
|
|
77
|
+
const match = HEADING.exec(line);
|
|
78
|
+
if (!match) return void 0;
|
|
79
|
+
const title = (match[2] ?? "").replace(/[ \t]+#+$/, "").replace(/^#+$/, "").trim();
|
|
80
|
+
return { level: match[1].length, title };
|
|
81
|
+
}
|
|
82
|
+
function startsTable(lines, i) {
|
|
83
|
+
return lines[i].includes("|") && i + 1 < lines.length && TABLE_DELIMITER.test(lines[i + 1]);
|
|
84
|
+
}
|
|
85
|
+
function fenceEnd(lines, start) {
|
|
86
|
+
const opener = FENCE.exec(lines[start]);
|
|
87
|
+
if (!opener) return start + 1;
|
|
88
|
+
const marker = opener[1];
|
|
89
|
+
const closer = new RegExp(`^ {0,3}${marker[0] === "`" ? "`" : "~"}{${marker.length},}[ \\t]*$`);
|
|
90
|
+
for (let i = start + 1; i < lines.length; i++) if (closer.test(lines[i])) return i + 1;
|
|
91
|
+
return lines.length;
|
|
92
|
+
}
|
|
93
|
+
function listEnd(lines, start) {
|
|
94
|
+
let end = start + 1;
|
|
95
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
96
|
+
const line = lines[i];
|
|
97
|
+
if (isBlank(line)) {
|
|
98
|
+
let next = i + 1;
|
|
99
|
+
while (next < lines.length && isBlank(lines[next])) next++;
|
|
100
|
+
if (next < lines.length && (LIST_ITEM.test(lines[next]) || isIndented(lines[next]))) {
|
|
101
|
+
i = next - 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
if (headingOf(line) && !isIndented(line)) break;
|
|
107
|
+
if (FENCE.test(line) && !isIndented(line)) break;
|
|
108
|
+
end = i + 1;
|
|
109
|
+
}
|
|
110
|
+
return end;
|
|
111
|
+
}
|
|
112
|
+
function tableEnd(lines, start) {
|
|
113
|
+
let end = start + 2;
|
|
114
|
+
while (end < lines.length && !isBlank(lines[end]) && lines[end].includes("|")) end++;
|
|
115
|
+
return end;
|
|
116
|
+
}
|
|
117
|
+
function paragraphEnd(lines, start) {
|
|
118
|
+
let end = start + 1;
|
|
119
|
+
while (end < lines.length && !isBlank(lines[end]) && !headingOf(lines[end]) && !FENCE.test(lines[end]) && !LIST_ITEM.test(lines[end])) {
|
|
120
|
+
end++;
|
|
121
|
+
}
|
|
122
|
+
return end;
|
|
123
|
+
}
|
|
124
|
+
function scan(text) {
|
|
125
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
126
|
+
const sections = [{ trail: [], blocks: [] }];
|
|
127
|
+
const stack = [];
|
|
128
|
+
let i = 0;
|
|
129
|
+
while (i < lines.length) {
|
|
130
|
+
const line = lines[i];
|
|
131
|
+
if (isBlank(line)) {
|
|
132
|
+
i++;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const heading = FENCE.test(line) ? void 0 : headingOf(line);
|
|
136
|
+
if (heading) {
|
|
137
|
+
while (stack.length && stack[stack.length - 1].level >= heading.level) stack.pop();
|
|
138
|
+
stack.push(heading);
|
|
139
|
+
sections.push({ trail: stack.map((h) => h.title), heading: line, blocks: [] });
|
|
140
|
+
i++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
let end;
|
|
144
|
+
if (FENCE.test(line)) end = fenceEnd(lines, i);
|
|
145
|
+
else if (LIST_ITEM.test(line)) end = listEnd(lines, i);
|
|
146
|
+
else if (startsTable(lines, i)) end = tableEnd(lines, i);
|
|
147
|
+
else end = paragraphEnd(lines, i);
|
|
148
|
+
sections[sections.length - 1].blocks.push({ lines: lines.slice(i, end) });
|
|
149
|
+
i = end;
|
|
150
|
+
}
|
|
151
|
+
return sections;
|
|
152
|
+
}
|
|
153
|
+
function chunkSections(text, max = 900) {
|
|
154
|
+
const cap = Math.max(1, max);
|
|
155
|
+
const out = [];
|
|
156
|
+
const emit = (parts, section) => {
|
|
157
|
+
const body = parts.join("\n\n");
|
|
158
|
+
if (body.trim() === "") return;
|
|
159
|
+
out.push({ text: body, section: [...section], position: out.length });
|
|
160
|
+
};
|
|
161
|
+
for (const section of scan(text)) {
|
|
162
|
+
let parts = section.heading ? [section.heading.trim()] : [];
|
|
163
|
+
let size = parts.join("\n\n").length;
|
|
164
|
+
let hasBlock = false;
|
|
165
|
+
for (const block of section.blocks) {
|
|
166
|
+
const piece = block.lines.join("\n");
|
|
167
|
+
const added = piece.length + (parts.length ? 2 : 0);
|
|
168
|
+
if (hasBlock && size + added > cap) {
|
|
169
|
+
emit(parts, section.trail);
|
|
170
|
+
parts = [];
|
|
171
|
+
size = 0;
|
|
172
|
+
hasBlock = false;
|
|
173
|
+
}
|
|
174
|
+
size += piece.length + (parts.length ? 2 : 0);
|
|
175
|
+
parts.push(piece);
|
|
176
|
+
hasBlock = true;
|
|
177
|
+
}
|
|
178
|
+
emit(parts, section.trail);
|
|
179
|
+
}
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
182
|
+
var FENCE, HEADING, LIST_ITEM, TABLE_DELIMITER, isBlank, isIndented;
|
|
183
|
+
var init_chunking = __esm({
|
|
184
|
+
"src/core/chunking.ts"() {
|
|
185
|
+
"use strict";
|
|
186
|
+
FENCE = /^ {0,3}(`{3,}|~{3,})/;
|
|
187
|
+
HEADING = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?[ \t]*$/;
|
|
188
|
+
LIST_ITEM = /^[ \t]*(?:[-*+]|\d{1,9}[.)])[ \t]+\S/;
|
|
189
|
+
TABLE_DELIMITER = /^[ \t]*\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
|
|
190
|
+
isBlank = (line) => line.trim() === "";
|
|
191
|
+
isIndented = (line) => /^(?: {2,}|\t)/.test(line);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
75
195
|
// src/core/loaders.ts
|
|
76
196
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
77
197
|
import { join } from "node:path";
|
|
@@ -139,6 +259,7 @@ __export(retrieval_exports, {
|
|
|
139
259
|
openLibsqlClient: () => openLibsqlClient,
|
|
140
260
|
wrapMissingLibsqlError: () => wrapMissingLibsqlError
|
|
141
261
|
});
|
|
262
|
+
import { relative, sep } from "node:path";
|
|
142
263
|
function createOpenAIEmbedder(client) {
|
|
143
264
|
return async (input) => {
|
|
144
265
|
const res = await client.embeddings.create({ model: EMB_MODEL, input });
|
|
@@ -181,6 +302,7 @@ var init_retrieval = __esm({
|
|
|
181
302
|
"src/core/retrieval.ts"() {
|
|
182
303
|
"use strict";
|
|
183
304
|
init_buildLock();
|
|
305
|
+
init_chunking();
|
|
184
306
|
init_loaders();
|
|
185
307
|
init_logger();
|
|
186
308
|
EMB_MODEL = "text-embedding-3-large";
|
|
@@ -191,6 +313,7 @@ var init_retrieval = __esm({
|
|
|
191
313
|
this.embed = embed;
|
|
192
314
|
this.db = options.databaseClient;
|
|
193
315
|
this.knowledgeDir = options.knowledgeDir || DEFAULT_KNOWLEDGE_DIR;
|
|
316
|
+
this.chunking = options.chunking ?? "lines";
|
|
194
317
|
this.logger = options.logger ?? createConsoleLogger();
|
|
195
318
|
this.buildLock = options.buildLock ?? createTursoBuildLock(this.db);
|
|
196
319
|
this.instanceId = options.instanceId ?? crypto.randomUUID();
|
|
@@ -204,6 +327,7 @@ var init_retrieval = __esm({
|
|
|
204
327
|
*/
|
|
205
328
|
db;
|
|
206
329
|
knowledgeDir;
|
|
330
|
+
chunking;
|
|
207
331
|
logger;
|
|
208
332
|
buildLock;
|
|
209
333
|
instanceId;
|
|
@@ -264,11 +388,41 @@ var init_retrieval = __esm({
|
|
|
264
388
|
this.logger.info("No knowledge documents and no existing chunks - nothing to build");
|
|
265
389
|
return;
|
|
266
390
|
}
|
|
391
|
+
this.logger.info(`Chunking mode: ${this.chunking}`);
|
|
392
|
+
if (this.chunking === "sections") await this.ensureSectionColumns();
|
|
267
393
|
const rows = [];
|
|
268
394
|
for (const d of docs) {
|
|
269
|
-
|
|
270
|
-
const
|
|
271
|
-
|
|
395
|
+
if (this.chunking === "sections") {
|
|
396
|
+
const source = relative(this.knowledgeDir, d.source).split(sep).join("/");
|
|
397
|
+
for (const c of chunkSections(d.text)) {
|
|
398
|
+
const section = c.section.join(" > ");
|
|
399
|
+
const id = await sha256(`${d.bucket}|${source}|${section}|${c.text}`);
|
|
400
|
+
const context = section ? `${source} > ${section}` : source;
|
|
401
|
+
rows.push({
|
|
402
|
+
id,
|
|
403
|
+
bucket: d.bucket,
|
|
404
|
+
source,
|
|
405
|
+
text: c.text,
|
|
406
|
+
embedText: `${context}
|
|
407
|
+
|
|
408
|
+
${c.text}`,
|
|
409
|
+
section,
|
|
410
|
+
position: c.position
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
} else {
|
|
414
|
+
for (const part of chunk(d.text)) {
|
|
415
|
+
const id = await sha256(`${d.bucket}|${d.source}|${part}`);
|
|
416
|
+
rows.push({
|
|
417
|
+
id,
|
|
418
|
+
bucket: d.bucket,
|
|
419
|
+
source: d.source,
|
|
420
|
+
text: part,
|
|
421
|
+
embedText: part,
|
|
422
|
+
section: null,
|
|
423
|
+
position: null
|
|
424
|
+
});
|
|
425
|
+
}
|
|
272
426
|
}
|
|
273
427
|
}
|
|
274
428
|
this.logger.info(`Created ${rows.length} chunks from knowledge documents`);
|
|
@@ -277,11 +431,17 @@ var init_retrieval = __esm({
|
|
|
277
431
|
for (let i = 0; i < rows.length; i += UPSERT_BATCH) {
|
|
278
432
|
const batch = rows.slice(i, i + UPSERT_BATCH);
|
|
279
433
|
await this.db.batch(
|
|
280
|
-
batch.map(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
434
|
+
batch.map(
|
|
435
|
+
(r) => this.chunking === "sections" ? {
|
|
436
|
+
sql: `INSERT INTO chunks(id,bucket,source,text,section,position) VALUES(?,?,?,?,?,?)
|
|
437
|
+
ON CONFLICT(id) DO NOTHING`,
|
|
438
|
+
args: [r.id, r.bucket, r.source, r.text, r.section, r.position]
|
|
439
|
+
} : {
|
|
440
|
+
sql: `INSERT INTO chunks(id,bucket,source,text) VALUES(?,?,?,?)
|
|
441
|
+
ON CONFLICT(id) DO NOTHING`,
|
|
442
|
+
args: [r.id, r.bucket, r.source, r.text]
|
|
443
|
+
}
|
|
444
|
+
),
|
|
285
445
|
"write"
|
|
286
446
|
);
|
|
287
447
|
}
|
|
@@ -302,7 +462,7 @@ var init_retrieval = __esm({
|
|
|
302
462
|
return;
|
|
303
463
|
}
|
|
304
464
|
this.logger.info(`Embedding ${missing.length} new/updated chunks with ${EMB_MODEL}...`);
|
|
305
|
-
const textById = new Map(rows.map((r) => [r.id, r.
|
|
465
|
+
const textById = new Map(rows.map((r) => [r.id, r.embedText]));
|
|
306
466
|
const BATCH = 96;
|
|
307
467
|
for (let i = 0; i < missing.length; i += BATCH) {
|
|
308
468
|
const batchIds = missing.slice(i, i + BATCH);
|
|
@@ -323,6 +483,18 @@ var init_retrieval = __esm({
|
|
|
323
483
|
}
|
|
324
484
|
this.logger.info(`Successfully embedded ${missing.length} new chunks`);
|
|
325
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Adds the nullable `section`/`position` columns to a `chunks` table that
|
|
488
|
+
* every released version created without them. Checked via table_info so it
|
|
489
|
+
* is a no-op once present; only `'sections'` mode ever calls it.
|
|
490
|
+
*/
|
|
491
|
+
async ensureSectionColumns() {
|
|
492
|
+
const info = await this.db.execute("PRAGMA table_info(chunks)");
|
|
493
|
+
const have = new Set(info.rows.map((r) => String(r.name)));
|
|
494
|
+
if (!have.has("section")) await this.db.execute("ALTER TABLE chunks ADD COLUMN section TEXT");
|
|
495
|
+
if (!have.has("position"))
|
|
496
|
+
await this.db.execute("ALTER TABLE chunks ADD COLUMN position INTEGER");
|
|
497
|
+
}
|
|
326
498
|
// Remove chunks from database that no longer exist in markdown files
|
|
327
499
|
async cleanupStaleChunks(currentIds) {
|
|
328
500
|
const result = await this.db.execute("SELECT id FROM chunks");
|
|
@@ -369,25 +541,34 @@ var init_retrieval = __esm({
|
|
|
369
541
|
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
370
542
|
* the embedding call.
|
|
371
543
|
*/
|
|
372
|
-
async
|
|
544
|
+
async queryChunks(q, k = 6, allowed = ["base"]) {
|
|
373
545
|
if (allowed.length === 0) return [];
|
|
374
546
|
const [qv] = await this.embed([q]);
|
|
375
547
|
const placeholders = allowed.map(() => "?").join(",");
|
|
376
548
|
const res = await this.db.execute({
|
|
377
|
-
sql: `SELECT c
|
|
549
|
+
sql: `SELECT c.*, e.embedding
|
|
378
550
|
FROM chunks c
|
|
379
551
|
JOIN embeddings e ON e.id = c.id
|
|
380
552
|
WHERE c.bucket IN (${placeholders})`,
|
|
381
553
|
args: allowed
|
|
382
554
|
});
|
|
383
|
-
const scored =
|
|
384
|
-
for (const row of res.rows) {
|
|
555
|
+
const scored = res.rows.map((row) => {
|
|
385
556
|
const emb = JSON.parse(String(row.embedding));
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
557
|
+
const trail = row.section == null ? "" : String(row.section);
|
|
558
|
+
return {
|
|
559
|
+
text: String(row.text),
|
|
560
|
+
bucket: String(row.bucket ?? ""),
|
|
561
|
+
source: String(row.source ?? ""),
|
|
562
|
+
section: trail ? trail.split(" > ") : [],
|
|
563
|
+
score: _VectorStore.cosine(qv, emb)
|
|
564
|
+
};
|
|
565
|
+
});
|
|
566
|
+
scored.sort((a, b) => b.score - a.score);
|
|
567
|
+
return scored.slice(0, k);
|
|
568
|
+
}
|
|
569
|
+
/** Same results as {@link queryChunks}, as bare text. */
|
|
570
|
+
async query(q, k = 6, allowed = ["base"]) {
|
|
571
|
+
return (await this.queryChunks(q, k, allowed)).map((c) => c.text);
|
|
391
572
|
}
|
|
392
573
|
};
|
|
393
574
|
}
|
|
@@ -644,9 +825,10 @@ function detectLeakage(text) {
|
|
|
644
825
|
function scrubOutput(text) {
|
|
645
826
|
return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
|
|
646
827
|
}
|
|
647
|
-
|
|
828
|
+
var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
|
|
829
|
+
function guardOutput(text, refusal) {
|
|
648
830
|
if (detectLeakage(text)) {
|
|
649
|
-
return
|
|
831
|
+
return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
|
|
650
832
|
}
|
|
651
833
|
return scrubOutput(text);
|
|
652
834
|
}
|
|
@@ -658,7 +840,8 @@ async function completeOnce({
|
|
|
658
840
|
system,
|
|
659
841
|
messages,
|
|
660
842
|
temperature = 0.2,
|
|
661
|
-
model = DEFAULT_MODEL
|
|
843
|
+
model = DEFAULT_MODEL,
|
|
844
|
+
refusal
|
|
662
845
|
}) {
|
|
663
846
|
const res = await client.chat.completions.create({
|
|
664
847
|
model,
|
|
@@ -667,7 +850,7 @@ async function completeOnce({
|
|
|
667
850
|
});
|
|
668
851
|
const text = res.choices[0]?.message?.content ?? "";
|
|
669
852
|
return {
|
|
670
|
-
content: guardOutput(text),
|
|
853
|
+
content: guardOutput(text, refusal),
|
|
671
854
|
usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
|
|
672
855
|
};
|
|
673
856
|
}
|
|
@@ -692,12 +875,12 @@ async function* completeStream({
|
|
|
692
875
|
|
|
693
876
|
// src/core/answer.ts
|
|
694
877
|
var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
695
|
-
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
|
|
878
|
+
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
|
|
696
879
|
const result = await answerFn({ system, messages, mode, sender, conversationId });
|
|
697
880
|
const raw = typeof result === "string" ? result : result?.content;
|
|
698
881
|
const usage = typeof result === "string" ? void 0 : result?.usage;
|
|
699
882
|
return {
|
|
700
|
-
content: guardOutput(typeof raw === "string" ? raw : ""),
|
|
883
|
+
content: guardOutput(typeof raw === "string" ? raw : "", refusal),
|
|
701
884
|
usage: usage ?? noUsage()
|
|
702
885
|
};
|
|
703
886
|
}
|
|
@@ -710,12 +893,13 @@ async function answerOnce({
|
|
|
710
893
|
sender,
|
|
711
894
|
conversationId,
|
|
712
895
|
temperature,
|
|
713
|
-
model
|
|
896
|
+
model,
|
|
897
|
+
refusal
|
|
714
898
|
}) {
|
|
715
899
|
if (answerFn) {
|
|
716
|
-
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
|
|
900
|
+
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
|
|
717
901
|
}
|
|
718
|
-
return completeOnce({ client, system, messages, temperature, model });
|
|
902
|
+
return completeOnce({ client, system, messages, temperature, model, refusal });
|
|
719
903
|
}
|
|
720
904
|
async function applyTransformReply(transformReply, input, logger) {
|
|
721
905
|
if (!transformReply) return input.text;
|
|
@@ -739,16 +923,15 @@ async function* answerStream({
|
|
|
739
923
|
sender,
|
|
740
924
|
conversationId,
|
|
741
925
|
temperature,
|
|
742
|
-
model
|
|
926
|
+
model,
|
|
927
|
+
refusal
|
|
743
928
|
}) {
|
|
744
929
|
if (answerFn) {
|
|
745
|
-
const { content } = await runAnswerFn(
|
|
746
|
-
|
|
747
|
-
messages,
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
conversationId
|
|
751
|
-
});
|
|
930
|
+
const { content } = await runAnswerFn(
|
|
931
|
+
answerFn,
|
|
932
|
+
{ system, messages, mode, sender, conversationId },
|
|
933
|
+
refusal
|
|
934
|
+
);
|
|
752
935
|
if (content) yield content;
|
|
753
936
|
return;
|
|
754
937
|
}
|
|
@@ -788,6 +971,7 @@ async function resolveBuckets({
|
|
|
788
971
|
|
|
789
972
|
// src/index.ts
|
|
790
973
|
init_buildLock();
|
|
974
|
+
init_chunking();
|
|
791
975
|
init_loaders();
|
|
792
976
|
init_logger();
|
|
793
977
|
|
|
@@ -1276,6 +1460,7 @@ async function createMCPServer(config) {
|
|
|
1276
1460
|
store = new VectorStore2(createOpenAIEmbedder2(client), {
|
|
1277
1461
|
databaseClient: db,
|
|
1278
1462
|
knowledgeDir: config.knowledgeDir || DEFAULT_KNOWLEDGE_DIR2,
|
|
1463
|
+
chunking: config.chunking,
|
|
1279
1464
|
logger: log
|
|
1280
1465
|
});
|
|
1281
1466
|
}
|
|
@@ -1347,7 +1532,8 @@ async function createMCPServer(config) {
|
|
|
1347
1532
|
messages: conversationMessages,
|
|
1348
1533
|
mode: "public",
|
|
1349
1534
|
conversationId: convId,
|
|
1350
|
-
model
|
|
1535
|
+
model,
|
|
1536
|
+
refusal: config.refusal
|
|
1351
1537
|
});
|
|
1352
1538
|
const replyText = await applyTransformReply(
|
|
1353
1539
|
config.transformReply,
|
|
@@ -1437,7 +1623,8 @@ async function createMCPServer(config) {
|
|
|
1437
1623
|
messages: conversationMessages,
|
|
1438
1624
|
mode: "private",
|
|
1439
1625
|
conversationId: convId,
|
|
1440
|
-
model
|
|
1626
|
+
model,
|
|
1627
|
+
refusal: config.refusal
|
|
1441
1628
|
});
|
|
1442
1629
|
const replyText = await applyTransformReply(
|
|
1443
1630
|
config.transformReply,
|
|
@@ -1936,7 +2123,8 @@ function demoRoutes(deps) {
|
|
|
1936
2123
|
system,
|
|
1937
2124
|
messages,
|
|
1938
2125
|
mode: "public",
|
|
1939
|
-
model
|
|
2126
|
+
model,
|
|
2127
|
+
refusal: config.refusal
|
|
1940
2128
|
})) {
|
|
1941
2129
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
1942
2130
|
|
|
@@ -1951,7 +2139,8 @@ function demoRoutes(deps) {
|
|
|
1951
2139
|
system,
|
|
1952
2140
|
messages,
|
|
1953
2141
|
mode: "public",
|
|
1954
|
-
model
|
|
2142
|
+
model,
|
|
2143
|
+
refusal: config.refusal
|
|
1955
2144
|
});
|
|
1956
2145
|
const reply = await applyTransformReply(
|
|
1957
2146
|
config.transformReply,
|
|
@@ -2092,7 +2281,8 @@ function openaiRoutes(deps) {
|
|
|
2092
2281
|
sender,
|
|
2093
2282
|
conversationId,
|
|
2094
2283
|
temperature,
|
|
2095
|
-
model: serverModel
|
|
2284
|
+
model: serverModel,
|
|
2285
|
+
refusal: config.refusal
|
|
2096
2286
|
})) {
|
|
2097
2287
|
await s.write(chunk2({ content: delta }, null));
|
|
2098
2288
|
}
|
|
@@ -2109,7 +2299,8 @@ function openaiRoutes(deps) {
|
|
|
2109
2299
|
sender,
|
|
2110
2300
|
conversationId,
|
|
2111
2301
|
temperature,
|
|
2112
|
-
model: serverModel
|
|
2302
|
+
model: serverModel,
|
|
2303
|
+
refusal: config.refusal
|
|
2113
2304
|
});
|
|
2114
2305
|
const reply = await applyTransformReply(
|
|
2115
2306
|
config.transformReply,
|
|
@@ -2200,7 +2391,8 @@ function privateRoutes(deps) {
|
|
|
2200
2391
|
messages,
|
|
2201
2392
|
mode: "private",
|
|
2202
2393
|
sender,
|
|
2203
|
-
model
|
|
2394
|
+
model,
|
|
2395
|
+
refusal: config.refusal
|
|
2204
2396
|
})) {
|
|
2205
2397
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
2206
2398
|
|
|
@@ -2216,7 +2408,8 @@ function privateRoutes(deps) {
|
|
|
2216
2408
|
messages,
|
|
2217
2409
|
mode: "private",
|
|
2218
2410
|
sender,
|
|
2219
|
-
model
|
|
2411
|
+
model,
|
|
2412
|
+
refusal: config.refusal
|
|
2220
2413
|
});
|
|
2221
2414
|
const reply = await applyTransformReply(
|
|
2222
2415
|
config.transformReply,
|
|
@@ -2285,7 +2478,8 @@ function publicRoutes(deps) {
|
|
|
2285
2478
|
system,
|
|
2286
2479
|
messages,
|
|
2287
2480
|
mode: "public",
|
|
2288
|
-
model
|
|
2481
|
+
model,
|
|
2482
|
+
refusal: config.refusal
|
|
2289
2483
|
})) {
|
|
2290
2484
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
2291
2485
|
|
|
@@ -2294,7 +2488,15 @@ function publicRoutes(deps) {
|
|
|
2294
2488
|
await s.write("event: end\ndata: {}\n\n");
|
|
2295
2489
|
});
|
|
2296
2490
|
}
|
|
2297
|
-
const out = await answerOnce({
|
|
2491
|
+
const out = await answerOnce({
|
|
2492
|
+
answerFn,
|
|
2493
|
+
client,
|
|
2494
|
+
system,
|
|
2495
|
+
messages,
|
|
2496
|
+
mode: "public",
|
|
2497
|
+
model,
|
|
2498
|
+
refusal: config.refusal
|
|
2499
|
+
});
|
|
2298
2500
|
const reply = await applyTransformReply(
|
|
2299
2501
|
config.transformReply,
|
|
2300
2502
|
{ channel: "widget-public", text: out.content },
|
|
@@ -2306,7 +2508,7 @@ function publicRoutes(deps) {
|
|
|
2306
2508
|
}
|
|
2307
2509
|
|
|
2308
2510
|
// src/server.ts
|
|
2309
|
-
import { relative } from "node:path";
|
|
2511
|
+
import { relative as relative2 } from "node:path";
|
|
2310
2512
|
import { Hono as Hono5 } from "hono";
|
|
2311
2513
|
import OpenAI2 from "openai";
|
|
2312
2514
|
|
|
@@ -2465,6 +2667,7 @@ async function createServer(config) {
|
|
|
2465
2667
|
store = new VectorStore2(createOpenAIEmbedder2(client), {
|
|
2466
2668
|
databaseClient: db,
|
|
2467
2669
|
knowledgeDir: config.knowledgeDir || DEFAULT_KNOWLEDGE_DIR2,
|
|
2670
|
+
chunking: config.chunking,
|
|
2468
2671
|
logger
|
|
2469
2672
|
});
|
|
2470
2673
|
}
|
|
@@ -2515,7 +2718,7 @@ async function createServer(config) {
|
|
|
2515
2718
|
}
|
|
2516
2719
|
}
|
|
2517
2720
|
if (serveStatic && staticDir) {
|
|
2518
|
-
const relativePath =
|
|
2721
|
+
const relativePath = relative2(process.cwd(), staticDir);
|
|
2519
2722
|
app.get("/chatter.js", serveStatic({ path: `${relativePath}/chatter.js` }));
|
|
2520
2723
|
app.get("/chatter.css", serveStatic({ path: `${relativePath}/chatter.css` }));
|
|
2521
2724
|
}
|
|
@@ -2562,6 +2765,7 @@ async function createServer(config) {
|
|
|
2562
2765
|
app.get("/demo/react", serveStatic({ path: `${publicDir}/react-demo.html` }));
|
|
2563
2766
|
}
|
|
2564
2767
|
const senders = createSenderRegistry(logger);
|
|
2768
|
+
const identities = /* @__PURE__ */ new Map();
|
|
2565
2769
|
const deps = {
|
|
2566
2770
|
client,
|
|
2567
2771
|
store,
|
|
@@ -2573,6 +2777,7 @@ async function createServer(config) {
|
|
|
2573
2777
|
prompts,
|
|
2574
2778
|
apiKeyManager,
|
|
2575
2779
|
senders,
|
|
2780
|
+
identities,
|
|
2576
2781
|
logger
|
|
2577
2782
|
};
|
|
2578
2783
|
if (enablePublic) {
|
|
@@ -2666,6 +2871,7 @@ export {
|
|
|
2666
2871
|
DEFAULT_KNOWLEDGE_DIR,
|
|
2667
2872
|
DEFAULT_MODEL,
|
|
2668
2873
|
DEFAULT_PROMPTS_DIR,
|
|
2874
|
+
DEFAULT_REFUSAL,
|
|
2669
2875
|
PromptLoader,
|
|
2670
2876
|
VectorStore,
|
|
2671
2877
|
answerOnce,
|
|
@@ -2673,6 +2879,7 @@ export {
|
|
|
2673
2879
|
applyTransformReply,
|
|
2674
2880
|
canAcquireBuildLock,
|
|
2675
2881
|
chatBodyLimit,
|
|
2882
|
+
chunkSections,
|
|
2676
2883
|
completeOnce,
|
|
2677
2884
|
completeStream,
|
|
2678
2885
|
cors,
|
package/dist/mcp-server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,YAAY,EACV,WAAW,EACX,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,YAAY,EACV,WAAW,EACX,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,gBAAgB;qCA+U3B,IAAI;GAEtC"}
|