@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/mcp-server.js
CHANGED
|
@@ -114,6 +114,126 @@ var init_buildLock = __esm({
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
+
// src/core/chunking.ts
|
|
118
|
+
function headingOf(line) {
|
|
119
|
+
const match = HEADING.exec(line);
|
|
120
|
+
if (!match) return void 0;
|
|
121
|
+
const title = (match[2] ?? "").replace(/[ \t]+#+$/, "").replace(/^#+$/, "").trim();
|
|
122
|
+
return { level: match[1].length, title };
|
|
123
|
+
}
|
|
124
|
+
function startsTable(lines, i) {
|
|
125
|
+
return lines[i].includes("|") && i + 1 < lines.length && TABLE_DELIMITER.test(lines[i + 1]);
|
|
126
|
+
}
|
|
127
|
+
function fenceEnd(lines, start) {
|
|
128
|
+
const opener = FENCE.exec(lines[start]);
|
|
129
|
+
if (!opener) return start + 1;
|
|
130
|
+
const marker = opener[1];
|
|
131
|
+
const closer = new RegExp(`^ {0,3}${marker[0] === "`" ? "`" : "~"}{${marker.length},}[ \\t]*$`);
|
|
132
|
+
for (let i = start + 1; i < lines.length; i++) if (closer.test(lines[i])) return i + 1;
|
|
133
|
+
return lines.length;
|
|
134
|
+
}
|
|
135
|
+
function listEnd(lines, start) {
|
|
136
|
+
let end = start + 1;
|
|
137
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
138
|
+
const line = lines[i];
|
|
139
|
+
if (isBlank(line)) {
|
|
140
|
+
let next = i + 1;
|
|
141
|
+
while (next < lines.length && isBlank(lines[next])) next++;
|
|
142
|
+
if (next < lines.length && (LIST_ITEM.test(lines[next]) || isIndented(lines[next]))) {
|
|
143
|
+
i = next - 1;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
if (headingOf(line) && !isIndented(line)) break;
|
|
149
|
+
if (FENCE.test(line) && !isIndented(line)) break;
|
|
150
|
+
end = i + 1;
|
|
151
|
+
}
|
|
152
|
+
return end;
|
|
153
|
+
}
|
|
154
|
+
function tableEnd(lines, start) {
|
|
155
|
+
let end = start + 2;
|
|
156
|
+
while (end < lines.length && !isBlank(lines[end]) && lines[end].includes("|")) end++;
|
|
157
|
+
return end;
|
|
158
|
+
}
|
|
159
|
+
function paragraphEnd(lines, start) {
|
|
160
|
+
let end = start + 1;
|
|
161
|
+
while (end < lines.length && !isBlank(lines[end]) && !headingOf(lines[end]) && !FENCE.test(lines[end]) && !LIST_ITEM.test(lines[end])) {
|
|
162
|
+
end++;
|
|
163
|
+
}
|
|
164
|
+
return end;
|
|
165
|
+
}
|
|
166
|
+
function scan(text) {
|
|
167
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
168
|
+
const sections = [{ trail: [], blocks: [] }];
|
|
169
|
+
const stack = [];
|
|
170
|
+
let i = 0;
|
|
171
|
+
while (i < lines.length) {
|
|
172
|
+
const line = lines[i];
|
|
173
|
+
if (isBlank(line)) {
|
|
174
|
+
i++;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const heading = FENCE.test(line) ? void 0 : headingOf(line);
|
|
178
|
+
if (heading) {
|
|
179
|
+
while (stack.length && stack[stack.length - 1].level >= heading.level) stack.pop();
|
|
180
|
+
stack.push(heading);
|
|
181
|
+
sections.push({ trail: stack.map((h) => h.title), heading: line, blocks: [] });
|
|
182
|
+
i++;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
let end;
|
|
186
|
+
if (FENCE.test(line)) end = fenceEnd(lines, i);
|
|
187
|
+
else if (LIST_ITEM.test(line)) end = listEnd(lines, i);
|
|
188
|
+
else if (startsTable(lines, i)) end = tableEnd(lines, i);
|
|
189
|
+
else end = paragraphEnd(lines, i);
|
|
190
|
+
sections[sections.length - 1].blocks.push({ lines: lines.slice(i, end) });
|
|
191
|
+
i = end;
|
|
192
|
+
}
|
|
193
|
+
return sections;
|
|
194
|
+
}
|
|
195
|
+
function chunkSections(text, max = 900) {
|
|
196
|
+
const cap = Math.max(1, max);
|
|
197
|
+
const out = [];
|
|
198
|
+
const emit = (parts, section) => {
|
|
199
|
+
const body = parts.join("\n\n");
|
|
200
|
+
if (body.trim() === "") return;
|
|
201
|
+
out.push({ text: body, section: [...section], position: out.length });
|
|
202
|
+
};
|
|
203
|
+
for (const section of scan(text)) {
|
|
204
|
+
let parts = section.heading ? [section.heading.trim()] : [];
|
|
205
|
+
let size = parts.join("\n\n").length;
|
|
206
|
+
let hasBlock = false;
|
|
207
|
+
for (const block of section.blocks) {
|
|
208
|
+
const piece = block.lines.join("\n");
|
|
209
|
+
const added = piece.length + (parts.length ? 2 : 0);
|
|
210
|
+
if (hasBlock && size + added > cap) {
|
|
211
|
+
emit(parts, section.trail);
|
|
212
|
+
parts = [];
|
|
213
|
+
size = 0;
|
|
214
|
+
hasBlock = false;
|
|
215
|
+
}
|
|
216
|
+
size += piece.length + (parts.length ? 2 : 0);
|
|
217
|
+
parts.push(piece);
|
|
218
|
+
hasBlock = true;
|
|
219
|
+
}
|
|
220
|
+
emit(parts, section.trail);
|
|
221
|
+
}
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
var FENCE, HEADING, LIST_ITEM, TABLE_DELIMITER, isBlank, isIndented;
|
|
225
|
+
var init_chunking = __esm({
|
|
226
|
+
"src/core/chunking.ts"() {
|
|
227
|
+
"use strict";
|
|
228
|
+
FENCE = /^ {0,3}(`{3,}|~{3,})/;
|
|
229
|
+
HEADING = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?[ \t]*$/;
|
|
230
|
+
LIST_ITEM = /^[ \t]*(?:[-*+]|\d{1,9}[.)])[ \t]+\S/;
|
|
231
|
+
TABLE_DELIMITER = /^[ \t]*\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
|
|
232
|
+
isBlank = (line) => line.trim() === "";
|
|
233
|
+
isIndented = (line) => /^(?: {2,}|\t)/.test(line);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
117
237
|
// src/core/loaders.ts
|
|
118
238
|
function walk(dir) {
|
|
119
239
|
const items = [];
|
|
@@ -194,11 +314,13 @@ async function sha256(input) {
|
|
|
194
314
|
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
195
315
|
return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
196
316
|
}
|
|
197
|
-
var EMB_MODEL, DEFAULT_KNOWLEDGE_DIR, DATABASE_CONFIG_REQUIRED_MESSAGE, VectorStore;
|
|
317
|
+
var import_node_path3, EMB_MODEL, DEFAULT_KNOWLEDGE_DIR, DATABASE_CONFIG_REQUIRED_MESSAGE, VectorStore;
|
|
198
318
|
var init_retrieval = __esm({
|
|
199
319
|
"src/core/retrieval.ts"() {
|
|
200
320
|
"use strict";
|
|
321
|
+
import_node_path3 = require("node:path");
|
|
201
322
|
init_buildLock();
|
|
323
|
+
init_chunking();
|
|
202
324
|
init_loaders();
|
|
203
325
|
init_logger();
|
|
204
326
|
EMB_MODEL = "text-embedding-3-large";
|
|
@@ -209,6 +331,7 @@ var init_retrieval = __esm({
|
|
|
209
331
|
this.embed = embed;
|
|
210
332
|
this.db = options.databaseClient;
|
|
211
333
|
this.knowledgeDir = options.knowledgeDir || DEFAULT_KNOWLEDGE_DIR;
|
|
334
|
+
this.chunking = options.chunking ?? "lines";
|
|
212
335
|
this.logger = options.logger ?? createConsoleLogger();
|
|
213
336
|
this.buildLock = options.buildLock ?? createTursoBuildLock(this.db);
|
|
214
337
|
this.instanceId = options.instanceId ?? crypto.randomUUID();
|
|
@@ -222,6 +345,7 @@ var init_retrieval = __esm({
|
|
|
222
345
|
*/
|
|
223
346
|
db;
|
|
224
347
|
knowledgeDir;
|
|
348
|
+
chunking;
|
|
225
349
|
logger;
|
|
226
350
|
buildLock;
|
|
227
351
|
instanceId;
|
|
@@ -282,11 +406,41 @@ var init_retrieval = __esm({
|
|
|
282
406
|
this.logger.info("No knowledge documents and no existing chunks - nothing to build");
|
|
283
407
|
return;
|
|
284
408
|
}
|
|
409
|
+
this.logger.info(`Chunking mode: ${this.chunking}`);
|
|
410
|
+
if (this.chunking === "sections") await this.ensureSectionColumns();
|
|
285
411
|
const rows = [];
|
|
286
412
|
for (const d of docs) {
|
|
287
|
-
|
|
288
|
-
const
|
|
289
|
-
|
|
413
|
+
if (this.chunking === "sections") {
|
|
414
|
+
const source = (0, import_node_path3.relative)(this.knowledgeDir, d.source).split(import_node_path3.sep).join("/");
|
|
415
|
+
for (const c of chunkSections(d.text)) {
|
|
416
|
+
const section = c.section.join(" > ");
|
|
417
|
+
const id = await sha256(`${d.bucket}|${source}|${section}|${c.text}`);
|
|
418
|
+
const context = section ? `${source} > ${section}` : source;
|
|
419
|
+
rows.push({
|
|
420
|
+
id,
|
|
421
|
+
bucket: d.bucket,
|
|
422
|
+
source,
|
|
423
|
+
text: c.text,
|
|
424
|
+
embedText: `${context}
|
|
425
|
+
|
|
426
|
+
${c.text}`,
|
|
427
|
+
section,
|
|
428
|
+
position: c.position
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
} else {
|
|
432
|
+
for (const part of chunk(d.text)) {
|
|
433
|
+
const id = await sha256(`${d.bucket}|${d.source}|${part}`);
|
|
434
|
+
rows.push({
|
|
435
|
+
id,
|
|
436
|
+
bucket: d.bucket,
|
|
437
|
+
source: d.source,
|
|
438
|
+
text: part,
|
|
439
|
+
embedText: part,
|
|
440
|
+
section: null,
|
|
441
|
+
position: null
|
|
442
|
+
});
|
|
443
|
+
}
|
|
290
444
|
}
|
|
291
445
|
}
|
|
292
446
|
this.logger.info(`Created ${rows.length} chunks from knowledge documents`);
|
|
@@ -295,11 +449,17 @@ var init_retrieval = __esm({
|
|
|
295
449
|
for (let i = 0; i < rows.length; i += UPSERT_BATCH) {
|
|
296
450
|
const batch = rows.slice(i, i + UPSERT_BATCH);
|
|
297
451
|
await this.db.batch(
|
|
298
|
-
batch.map(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
452
|
+
batch.map(
|
|
453
|
+
(r) => this.chunking === "sections" ? {
|
|
454
|
+
sql: `INSERT INTO chunks(id,bucket,source,text,section,position) VALUES(?,?,?,?,?,?)
|
|
455
|
+
ON CONFLICT(id) DO NOTHING`,
|
|
456
|
+
args: [r.id, r.bucket, r.source, r.text, r.section, r.position]
|
|
457
|
+
} : {
|
|
458
|
+
sql: `INSERT INTO chunks(id,bucket,source,text) VALUES(?,?,?,?)
|
|
459
|
+
ON CONFLICT(id) DO NOTHING`,
|
|
460
|
+
args: [r.id, r.bucket, r.source, r.text]
|
|
461
|
+
}
|
|
462
|
+
),
|
|
303
463
|
"write"
|
|
304
464
|
);
|
|
305
465
|
}
|
|
@@ -320,7 +480,7 @@ var init_retrieval = __esm({
|
|
|
320
480
|
return;
|
|
321
481
|
}
|
|
322
482
|
this.logger.info(`Embedding ${missing.length} new/updated chunks with ${EMB_MODEL}...`);
|
|
323
|
-
const textById = new Map(rows.map((r) => [r.id, r.
|
|
483
|
+
const textById = new Map(rows.map((r) => [r.id, r.embedText]));
|
|
324
484
|
const BATCH = 96;
|
|
325
485
|
for (let i = 0; i < missing.length; i += BATCH) {
|
|
326
486
|
const batchIds = missing.slice(i, i + BATCH);
|
|
@@ -341,6 +501,18 @@ var init_retrieval = __esm({
|
|
|
341
501
|
}
|
|
342
502
|
this.logger.info(`Successfully embedded ${missing.length} new chunks`);
|
|
343
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Adds the nullable `section`/`position` columns to a `chunks` table that
|
|
506
|
+
* every released version created without them. Checked via table_info so it
|
|
507
|
+
* is a no-op once present; only `'sections'` mode ever calls it.
|
|
508
|
+
*/
|
|
509
|
+
async ensureSectionColumns() {
|
|
510
|
+
const info = await this.db.execute("PRAGMA table_info(chunks)");
|
|
511
|
+
const have = new Set(info.rows.map((r) => String(r.name)));
|
|
512
|
+
if (!have.has("section")) await this.db.execute("ALTER TABLE chunks ADD COLUMN section TEXT");
|
|
513
|
+
if (!have.has("position"))
|
|
514
|
+
await this.db.execute("ALTER TABLE chunks ADD COLUMN position INTEGER");
|
|
515
|
+
}
|
|
344
516
|
// Remove chunks from database that no longer exist in markdown files
|
|
345
517
|
async cleanupStaleChunks(currentIds) {
|
|
346
518
|
const result = await this.db.execute("SELECT id FROM chunks");
|
|
@@ -387,25 +559,34 @@ var init_retrieval = __esm({
|
|
|
387
559
|
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
388
560
|
* the embedding call.
|
|
389
561
|
*/
|
|
390
|
-
async
|
|
562
|
+
async queryChunks(q, k = 6, allowed = ["base"]) {
|
|
391
563
|
if (allowed.length === 0) return [];
|
|
392
564
|
const [qv] = await this.embed([q]);
|
|
393
565
|
const placeholders = allowed.map(() => "?").join(",");
|
|
394
566
|
const res = await this.db.execute({
|
|
395
|
-
sql: `SELECT c
|
|
567
|
+
sql: `SELECT c.*, e.embedding
|
|
396
568
|
FROM chunks c
|
|
397
569
|
JOIN embeddings e ON e.id = c.id
|
|
398
570
|
WHERE c.bucket IN (${placeholders})`,
|
|
399
571
|
args: allowed
|
|
400
572
|
});
|
|
401
|
-
const scored =
|
|
402
|
-
for (const row of res.rows) {
|
|
573
|
+
const scored = res.rows.map((row) => {
|
|
403
574
|
const emb = JSON.parse(String(row.embedding));
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
575
|
+
const trail = row.section == null ? "" : String(row.section);
|
|
576
|
+
return {
|
|
577
|
+
text: String(row.text),
|
|
578
|
+
bucket: String(row.bucket ?? ""),
|
|
579
|
+
source: String(row.source ?? ""),
|
|
580
|
+
section: trail ? trail.split(" > ") : [],
|
|
581
|
+
score: _VectorStore.cosine(qv, emb)
|
|
582
|
+
};
|
|
583
|
+
});
|
|
584
|
+
scored.sort((a, b) => b.score - a.score);
|
|
585
|
+
return scored.slice(0, k);
|
|
586
|
+
}
|
|
587
|
+
/** Same results as {@link queryChunks}, as bare text. */
|
|
588
|
+
async query(q, k = 6, allowed = ["base"]) {
|
|
589
|
+
return (await this.queryChunks(q, k, allowed)).map((c) => c.text);
|
|
409
590
|
}
|
|
410
591
|
};
|
|
411
592
|
}
|
|
@@ -546,9 +727,10 @@ function detectLeakage(text) {
|
|
|
546
727
|
function scrubOutput(text) {
|
|
547
728
|
return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
|
|
548
729
|
}
|
|
549
|
-
|
|
730
|
+
var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
|
|
731
|
+
function guardOutput(text, refusal) {
|
|
550
732
|
if (detectLeakage(text)) {
|
|
551
|
-
return
|
|
733
|
+
return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
|
|
552
734
|
}
|
|
553
735
|
return scrubOutput(text);
|
|
554
736
|
}
|
|
@@ -560,7 +742,8 @@ async function completeOnce({
|
|
|
560
742
|
system,
|
|
561
743
|
messages,
|
|
562
744
|
temperature = 0.2,
|
|
563
|
-
model = DEFAULT_MODEL
|
|
745
|
+
model = DEFAULT_MODEL,
|
|
746
|
+
refusal
|
|
564
747
|
}) {
|
|
565
748
|
const res = await client.chat.completions.create({
|
|
566
749
|
model,
|
|
@@ -569,19 +752,19 @@ async function completeOnce({
|
|
|
569
752
|
});
|
|
570
753
|
const text = res.choices[0]?.message?.content ?? "";
|
|
571
754
|
return {
|
|
572
|
-
content: guardOutput(text),
|
|
755
|
+
content: guardOutput(text, refusal),
|
|
573
756
|
usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
|
|
574
757
|
};
|
|
575
758
|
}
|
|
576
759
|
|
|
577
760
|
// src/core/answer.ts
|
|
578
761
|
var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
579
|
-
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
|
|
762
|
+
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
|
|
580
763
|
const result = await answerFn({ system, messages, mode, sender, conversationId });
|
|
581
764
|
const raw = typeof result === "string" ? result : result?.content;
|
|
582
765
|
const usage = typeof result === "string" ? void 0 : result?.usage;
|
|
583
766
|
return {
|
|
584
|
-
content: guardOutput(typeof raw === "string" ? raw : ""),
|
|
767
|
+
content: guardOutput(typeof raw === "string" ? raw : "", refusal),
|
|
585
768
|
usage: usage ?? noUsage()
|
|
586
769
|
};
|
|
587
770
|
}
|
|
@@ -594,12 +777,13 @@ async function answerOnce({
|
|
|
594
777
|
sender,
|
|
595
778
|
conversationId,
|
|
596
779
|
temperature,
|
|
597
|
-
model
|
|
780
|
+
model,
|
|
781
|
+
refusal
|
|
598
782
|
}) {
|
|
599
783
|
if (answerFn) {
|
|
600
|
-
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
|
|
784
|
+
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
|
|
601
785
|
}
|
|
602
|
-
return completeOnce({ client, system, messages, temperature, model });
|
|
786
|
+
return completeOnce({ client, system, messages, temperature, model, refusal });
|
|
603
787
|
}
|
|
604
788
|
async function applyTransformReply(transformReply, input, logger) {
|
|
605
789
|
if (!transformReply) return input.text;
|
|
@@ -1029,6 +1213,7 @@ async function createMCPServer(config) {
|
|
|
1029
1213
|
store = new VectorStore2(createOpenAIEmbedder2(client), {
|
|
1030
1214
|
databaseClient: db,
|
|
1031
1215
|
knowledgeDir: config.knowledgeDir || DEFAULT_KNOWLEDGE_DIR2,
|
|
1216
|
+
chunking: config.chunking,
|
|
1032
1217
|
logger: log
|
|
1033
1218
|
});
|
|
1034
1219
|
}
|
|
@@ -1100,7 +1285,8 @@ async function createMCPServer(config) {
|
|
|
1100
1285
|
messages: conversationMessages,
|
|
1101
1286
|
mode: "public",
|
|
1102
1287
|
conversationId: convId,
|
|
1103
|
-
model
|
|
1288
|
+
model,
|
|
1289
|
+
refusal: config.refusal
|
|
1104
1290
|
});
|
|
1105
1291
|
const replyText = await applyTransformReply(
|
|
1106
1292
|
config.transformReply,
|
|
@@ -1190,7 +1376,8 @@ async function createMCPServer(config) {
|
|
|
1190
1376
|
messages: conversationMessages,
|
|
1191
1377
|
mode: "private",
|
|
1192
1378
|
conversationId: convId,
|
|
1193
|
-
model
|
|
1379
|
+
model,
|
|
1380
|
+
refusal: config.refusal
|
|
1194
1381
|
});
|
|
1195
1382
|
const replyText = await applyTransformReply(
|
|
1196
1383
|
config.transformReply,
|