@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.
Files changed (77) hide show
  1. package/README.md +3 -1
  2. package/dist/channels/gates.d.ts +21 -2
  3. package/dist/channels/gates.d.ts.map +1 -1
  4. package/dist/channels/index.d.ts +5 -3
  5. package/dist/channels/index.d.ts.map +1 -1
  6. package/dist/channels/index.js +31 -13
  7. package/dist/channels/index.mjs +30 -13
  8. package/dist/channels/matrix/channel.d.ts +2 -0
  9. package/dist/channels/matrix/channel.d.ts.map +1 -1
  10. package/dist/channels/matrix/handler.d.ts +9 -0
  11. package/dist/channels/matrix/handler.d.ts.map +1 -1
  12. package/dist/channels/matrix/index.d.ts +1 -1
  13. package/dist/channels/matrix/index.d.ts.map +1 -1
  14. package/dist/channels/matrix/index.js +75 -20
  15. package/dist/channels/matrix/index.mjs +74 -20
  16. package/dist/channels/matrix/updates.d.ts +8 -2
  17. package/dist/channels/matrix/updates.d.ts.map +1 -1
  18. package/dist/channels/pipeline.d.ts +34 -4
  19. package/dist/channels/pipeline.d.ts.map +1 -1
  20. package/dist/channels/polling.d.ts +11 -0
  21. package/dist/channels/polling.d.ts.map +1 -1
  22. package/dist/channels/telegram/channel.d.ts +2 -0
  23. package/dist/channels/telegram/channel.d.ts.map +1 -1
  24. package/dist/channels/telegram/handler.d.ts +9 -0
  25. package/dist/channels/telegram/handler.d.ts.map +1 -1
  26. package/dist/channels/telegram/index.d.ts +1 -1
  27. package/dist/channels/telegram/index.d.ts.map +1 -1
  28. package/dist/channels/telegram/index.js +73 -24
  29. package/dist/channels/telegram/index.mjs +72 -24
  30. package/dist/channels/telegram/updates.d.ts +8 -2
  31. package/dist/channels/telegram/updates.d.ts.map +1 -1
  32. package/dist/channels/telegram/webhook.d.ts +10 -0
  33. package/dist/channels/telegram/webhook.d.ts.map +1 -1
  34. package/dist/channels/whatsapp/channel.d.ts +8 -0
  35. package/dist/channels/whatsapp/channel.d.ts.map +1 -1
  36. package/dist/channels/whatsapp/inbound.d.ts +2 -0
  37. package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
  38. package/dist/channels/whatsapp/index.js +45 -18
  39. package/dist/channels/whatsapp/index.mjs +45 -18
  40. package/dist/core/answer.d.ts +9 -2
  41. package/dist/core/answer.d.ts.map +1 -1
  42. package/dist/core/chunking.d.ts +31 -0
  43. package/dist/core/chunking.d.ts.map +1 -0
  44. package/dist/core/guardrails.d.ts +11 -1
  45. package/dist/core/guardrails.d.ts.map +1 -1
  46. package/dist/core/llm.d.ts +3 -1
  47. package/dist/core/llm.d.ts.map +1 -1
  48. package/dist/core/retrieval.d.ts +39 -0
  49. package/dist/core/retrieval.d.ts.map +1 -1
  50. package/dist/history/index.js +12 -9
  51. package/dist/history/index.mjs +12 -9
  52. package/dist/index.d.ts +4 -2
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +261 -52
  55. package/dist/index.mjs +254 -47
  56. package/dist/mcp-server.d.ts.map +1 -1
  57. package/dist/mcp-server.js +217 -30
  58. package/dist/mcp-server.mjs +216 -29
  59. package/dist/personas/index.d.ts +1 -1
  60. package/dist/personas/index.d.ts.map +1 -1
  61. package/dist/personas/index.js +21 -7
  62. package/dist/personas/index.mjs +21 -7
  63. package/dist/personas/resolver.d.ts +35 -8
  64. package/dist/personas/resolver.d.ts.map +1 -1
  65. package/dist/personas/timeContext.d.ts.map +1 -1
  66. package/dist/routes/demo.d.ts.map +1 -1
  67. package/dist/routes/openai.d.ts.map +1 -1
  68. package/dist/routes/private.d.ts.map +1 -1
  69. package/dist/routes/public.d.ts.map +1 -1
  70. package/dist/scheduler/index.js +12 -9
  71. package/dist/scheduler/index.mjs +12 -9
  72. package/dist/server.d.ts.map +1 -1
  73. package/dist/server.js +251 -50
  74. package/dist/server.mjs +246 -45
  75. package/dist/types.d.ts +39 -1
  76. package/dist/types.d.ts.map +1 -1
  77. package/package.json +13 -13
package/dist/server.mjs CHANGED
@@ -92,6 +92,126 @@ var init_buildLock = __esm({
92
92
  }
93
93
  });
94
94
 
95
+ // src/core/chunking.ts
96
+ function headingOf(line) {
97
+ const match = HEADING.exec(line);
98
+ if (!match) return void 0;
99
+ const title = (match[2] ?? "").replace(/[ \t]+#+$/, "").replace(/^#+$/, "").trim();
100
+ return { level: match[1].length, title };
101
+ }
102
+ function startsTable(lines, i) {
103
+ return lines[i].includes("|") && i + 1 < lines.length && TABLE_DELIMITER.test(lines[i + 1]);
104
+ }
105
+ function fenceEnd(lines, start) {
106
+ const opener = FENCE.exec(lines[start]);
107
+ if (!opener) return start + 1;
108
+ const marker = opener[1];
109
+ const closer = new RegExp(`^ {0,3}${marker[0] === "`" ? "`" : "~"}{${marker.length},}[ \\t]*$`);
110
+ for (let i = start + 1; i < lines.length; i++) if (closer.test(lines[i])) return i + 1;
111
+ return lines.length;
112
+ }
113
+ function listEnd(lines, start) {
114
+ let end = start + 1;
115
+ for (let i = start + 1; i < lines.length; i++) {
116
+ const line = lines[i];
117
+ if (isBlank(line)) {
118
+ let next = i + 1;
119
+ while (next < lines.length && isBlank(lines[next])) next++;
120
+ if (next < lines.length && (LIST_ITEM.test(lines[next]) || isIndented(lines[next]))) {
121
+ i = next - 1;
122
+ continue;
123
+ }
124
+ break;
125
+ }
126
+ if (headingOf(line) && !isIndented(line)) break;
127
+ if (FENCE.test(line) && !isIndented(line)) break;
128
+ end = i + 1;
129
+ }
130
+ return end;
131
+ }
132
+ function tableEnd(lines, start) {
133
+ let end = start + 2;
134
+ while (end < lines.length && !isBlank(lines[end]) && lines[end].includes("|")) end++;
135
+ return end;
136
+ }
137
+ function paragraphEnd(lines, start) {
138
+ let end = start + 1;
139
+ while (end < lines.length && !isBlank(lines[end]) && !headingOf(lines[end]) && !FENCE.test(lines[end]) && !LIST_ITEM.test(lines[end])) {
140
+ end++;
141
+ }
142
+ return end;
143
+ }
144
+ function scan(text) {
145
+ const lines = text.replace(/\r\n?/g, "\n").split("\n");
146
+ const sections = [{ trail: [], blocks: [] }];
147
+ const stack = [];
148
+ let i = 0;
149
+ while (i < lines.length) {
150
+ const line = lines[i];
151
+ if (isBlank(line)) {
152
+ i++;
153
+ continue;
154
+ }
155
+ const heading = FENCE.test(line) ? void 0 : headingOf(line);
156
+ if (heading) {
157
+ while (stack.length && stack[stack.length - 1].level >= heading.level) stack.pop();
158
+ stack.push(heading);
159
+ sections.push({ trail: stack.map((h) => h.title), heading: line, blocks: [] });
160
+ i++;
161
+ continue;
162
+ }
163
+ let end;
164
+ if (FENCE.test(line)) end = fenceEnd(lines, i);
165
+ else if (LIST_ITEM.test(line)) end = listEnd(lines, i);
166
+ else if (startsTable(lines, i)) end = tableEnd(lines, i);
167
+ else end = paragraphEnd(lines, i);
168
+ sections[sections.length - 1].blocks.push({ lines: lines.slice(i, end) });
169
+ i = end;
170
+ }
171
+ return sections;
172
+ }
173
+ function chunkSections(text, max = 900) {
174
+ const cap = Math.max(1, max);
175
+ const out = [];
176
+ const emit = (parts, section) => {
177
+ const body = parts.join("\n\n");
178
+ if (body.trim() === "") return;
179
+ out.push({ text: body, section: [...section], position: out.length });
180
+ };
181
+ for (const section of scan(text)) {
182
+ let parts = section.heading ? [section.heading.trim()] : [];
183
+ let size = parts.join("\n\n").length;
184
+ let hasBlock = false;
185
+ for (const block of section.blocks) {
186
+ const piece = block.lines.join("\n");
187
+ const added = piece.length + (parts.length ? 2 : 0);
188
+ if (hasBlock && size + added > cap) {
189
+ emit(parts, section.trail);
190
+ parts = [];
191
+ size = 0;
192
+ hasBlock = false;
193
+ }
194
+ size += piece.length + (parts.length ? 2 : 0);
195
+ parts.push(piece);
196
+ hasBlock = true;
197
+ }
198
+ emit(parts, section.trail);
199
+ }
200
+ return out;
201
+ }
202
+ var FENCE, HEADING, LIST_ITEM, TABLE_DELIMITER, isBlank, isIndented;
203
+ var init_chunking = __esm({
204
+ "src/core/chunking.ts"() {
205
+ "use strict";
206
+ FENCE = /^ {0,3}(`{3,}|~{3,})/;
207
+ HEADING = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?[ \t]*$/;
208
+ LIST_ITEM = /^[ \t]*(?:[-*+]|\d{1,9}[.)])[ \t]+\S/;
209
+ TABLE_DELIMITER = /^[ \t]*\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
210
+ isBlank = (line) => line.trim() === "";
211
+ isIndented = (line) => /^(?: {2,}|\t)/.test(line);
212
+ }
213
+ });
214
+
95
215
  // src/core/loaders.ts
96
216
  import { readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
97
217
  import { join as join2 } from "node:path";
@@ -134,6 +254,7 @@ __export(retrieval_exports, {
134
254
  openLibsqlClient: () => openLibsqlClient,
135
255
  wrapMissingLibsqlError: () => wrapMissingLibsqlError
136
256
  });
257
+ import { relative, sep } from "node:path";
137
258
  function createOpenAIEmbedder(client) {
138
259
  return async (input) => {
139
260
  const res = await client.embeddings.create({ model: EMB_MODEL, input });
@@ -176,6 +297,7 @@ var init_retrieval = __esm({
176
297
  "src/core/retrieval.ts"() {
177
298
  "use strict";
178
299
  init_buildLock();
300
+ init_chunking();
179
301
  init_loaders();
180
302
  init_logger();
181
303
  EMB_MODEL = "text-embedding-3-large";
@@ -186,6 +308,7 @@ var init_retrieval = __esm({
186
308
  this.embed = embed;
187
309
  this.db = options.databaseClient;
188
310
  this.knowledgeDir = options.knowledgeDir || DEFAULT_KNOWLEDGE_DIR;
311
+ this.chunking = options.chunking ?? "lines";
189
312
  this.logger = options.logger ?? createConsoleLogger();
190
313
  this.buildLock = options.buildLock ?? createTursoBuildLock(this.db);
191
314
  this.instanceId = options.instanceId ?? crypto.randomUUID();
@@ -199,6 +322,7 @@ var init_retrieval = __esm({
199
322
  */
200
323
  db;
201
324
  knowledgeDir;
325
+ chunking;
202
326
  logger;
203
327
  buildLock;
204
328
  instanceId;
@@ -259,11 +383,41 @@ var init_retrieval = __esm({
259
383
  this.logger.info("No knowledge documents and no existing chunks - nothing to build");
260
384
  return;
261
385
  }
386
+ this.logger.info(`Chunking mode: ${this.chunking}`);
387
+ if (this.chunking === "sections") await this.ensureSectionColumns();
262
388
  const rows = [];
263
389
  for (const d of docs) {
264
- for (const part of chunk(d.text)) {
265
- const id = await sha256(`${d.bucket}|${d.source}|${part}`);
266
- rows.push({ id, bucket: d.bucket, source: d.source, text: part });
390
+ if (this.chunking === "sections") {
391
+ const source = relative(this.knowledgeDir, d.source).split(sep).join("/");
392
+ for (const c of chunkSections(d.text)) {
393
+ const section = c.section.join(" > ");
394
+ const id = await sha256(`${d.bucket}|${source}|${section}|${c.text}`);
395
+ const context = section ? `${source} > ${section}` : source;
396
+ rows.push({
397
+ id,
398
+ bucket: d.bucket,
399
+ source,
400
+ text: c.text,
401
+ embedText: `${context}
402
+
403
+ ${c.text}`,
404
+ section,
405
+ position: c.position
406
+ });
407
+ }
408
+ } else {
409
+ for (const part of chunk(d.text)) {
410
+ const id = await sha256(`${d.bucket}|${d.source}|${part}`);
411
+ rows.push({
412
+ id,
413
+ bucket: d.bucket,
414
+ source: d.source,
415
+ text: part,
416
+ embedText: part,
417
+ section: null,
418
+ position: null
419
+ });
420
+ }
267
421
  }
268
422
  }
269
423
  this.logger.info(`Created ${rows.length} chunks from knowledge documents`);
@@ -272,11 +426,17 @@ var init_retrieval = __esm({
272
426
  for (let i = 0; i < rows.length; i += UPSERT_BATCH) {
273
427
  const batch = rows.slice(i, i + UPSERT_BATCH);
274
428
  await this.db.batch(
275
- batch.map((r) => ({
276
- sql: `INSERT INTO chunks(id,bucket,source,text) VALUES(?,?,?,?)
277
- ON CONFLICT(id) DO NOTHING`,
278
- args: [r.id, r.bucket, r.source, r.text]
279
- })),
429
+ batch.map(
430
+ (r) => this.chunking === "sections" ? {
431
+ sql: `INSERT INTO chunks(id,bucket,source,text,section,position) VALUES(?,?,?,?,?,?)
432
+ ON CONFLICT(id) DO NOTHING`,
433
+ args: [r.id, r.bucket, r.source, r.text, r.section, r.position]
434
+ } : {
435
+ sql: `INSERT INTO chunks(id,bucket,source,text) VALUES(?,?,?,?)
436
+ ON CONFLICT(id) DO NOTHING`,
437
+ args: [r.id, r.bucket, r.source, r.text]
438
+ }
439
+ ),
280
440
  "write"
281
441
  );
282
442
  }
@@ -297,7 +457,7 @@ var init_retrieval = __esm({
297
457
  return;
298
458
  }
299
459
  this.logger.info(`Embedding ${missing.length} new/updated chunks with ${EMB_MODEL}...`);
300
- const textById = new Map(rows.map((r) => [r.id, r.text]));
460
+ const textById = new Map(rows.map((r) => [r.id, r.embedText]));
301
461
  const BATCH = 96;
302
462
  for (let i = 0; i < missing.length; i += BATCH) {
303
463
  const batchIds = missing.slice(i, i + BATCH);
@@ -318,6 +478,18 @@ var init_retrieval = __esm({
318
478
  }
319
479
  this.logger.info(`Successfully embedded ${missing.length} new chunks`);
320
480
  }
481
+ /**
482
+ * Adds the nullable `section`/`position` columns to a `chunks` table that
483
+ * every released version created without them. Checked via table_info so it
484
+ * is a no-op once present; only `'sections'` mode ever calls it.
485
+ */
486
+ async ensureSectionColumns() {
487
+ const info = await this.db.execute("PRAGMA table_info(chunks)");
488
+ const have = new Set(info.rows.map((r) => String(r.name)));
489
+ if (!have.has("section")) await this.db.execute("ALTER TABLE chunks ADD COLUMN section TEXT");
490
+ if (!have.has("position"))
491
+ await this.db.execute("ALTER TABLE chunks ADD COLUMN position INTEGER");
492
+ }
321
493
  // Remove chunks from database that no longer exist in markdown files
322
494
  async cleanupStaleChunks(currentIds) {
323
495
  const result = await this.db.execute("SELECT id FROM chunks");
@@ -364,25 +536,34 @@ var init_retrieval = __esm({
364
536
  * interpolated. An empty list retrieves nothing, and short-circuits before
365
537
  * the embedding call.
366
538
  */
367
- async query(q, k = 6, allowed = ["base"]) {
539
+ async queryChunks(q, k = 6, allowed = ["base"]) {
368
540
  if (allowed.length === 0) return [];
369
541
  const [qv] = await this.embed([q]);
370
542
  const placeholders = allowed.map(() => "?").join(",");
371
543
  const res = await this.db.execute({
372
- sql: `SELECT c.id, c.text, e.embedding
544
+ sql: `SELECT c.*, e.embedding
373
545
  FROM chunks c
374
546
  JOIN embeddings e ON e.id = c.id
375
547
  WHERE c.bucket IN (${placeholders})`,
376
548
  args: allowed
377
549
  });
378
- const scored = [];
379
- for (const row of res.rows) {
550
+ const scored = res.rows.map((row) => {
380
551
  const emb = JSON.parse(String(row.embedding));
381
- const s = _VectorStore.cosine(qv, emb);
382
- scored.push({ s, text: String(row.text) });
383
- }
384
- scored.sort((a, b) => b.s - a.s);
385
- return scored.slice(0, k).map((r) => r.text);
552
+ const trail = row.section == null ? "" : String(row.section);
553
+ return {
554
+ text: String(row.text),
555
+ bucket: String(row.bucket ?? ""),
556
+ source: String(row.source ?? ""),
557
+ section: trail ? trail.split(" > ") : [],
558
+ score: _VectorStore.cosine(qv, emb)
559
+ };
560
+ });
561
+ scored.sort((a, b) => b.score - a.score);
562
+ return scored.slice(0, k);
563
+ }
564
+ /** Same results as {@link queryChunks}, as bare text. */
565
+ async query(q, k = 6, allowed = ["base"]) {
566
+ return (await this.queryChunks(q, k, allowed)).map((c) => c.text);
386
567
  }
387
568
  };
388
569
  }
@@ -502,7 +683,7 @@ var init_knowledgeHealth = __esm({
502
683
  });
503
684
 
504
685
  // src/server.ts
505
- import { relative } from "node:path";
686
+ import { relative as relative2 } from "node:path";
506
687
  import { Hono as Hono5 } from "hono";
507
688
  import OpenAI from "openai";
508
689
 
@@ -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
- function guardOutput(text) {
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 "Sorry, I can't share internal instructions. How else can I help?";
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(answerFn, {
746
- system,
747
- messages,
748
- mode,
749
- sender,
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
  }
@@ -1396,7 +1579,8 @@ function demoRoutes(deps) {
1396
1579
  system,
1397
1580
  messages,
1398
1581
  mode: "public",
1399
- model
1582
+ model,
1583
+ refusal: config.refusal
1400
1584
  })) {
1401
1585
  await s.write(`data: ${JSON.stringify({ delta })}
1402
1586
 
@@ -1411,7 +1595,8 @@ function demoRoutes(deps) {
1411
1595
  system,
1412
1596
  messages,
1413
1597
  mode: "public",
1414
- model
1598
+ model,
1599
+ refusal: config.refusal
1415
1600
  });
1416
1601
  const reply = await applyTransformReply(
1417
1602
  config.transformReply,
@@ -1633,7 +1818,8 @@ function openaiRoutes(deps) {
1633
1818
  sender,
1634
1819
  conversationId,
1635
1820
  temperature,
1636
- model: serverModel
1821
+ model: serverModel,
1822
+ refusal: config.refusal
1637
1823
  })) {
1638
1824
  await s.write(chunk2({ content: delta }, null));
1639
1825
  }
@@ -1650,7 +1836,8 @@ function openaiRoutes(deps) {
1650
1836
  sender,
1651
1837
  conversationId,
1652
1838
  temperature,
1653
- model: serverModel
1839
+ model: serverModel,
1840
+ refusal: config.refusal
1654
1841
  });
1655
1842
  const reply = await applyTransformReply(
1656
1843
  config.transformReply,
@@ -1741,7 +1928,8 @@ function privateRoutes(deps) {
1741
1928
  messages,
1742
1929
  mode: "private",
1743
1930
  sender,
1744
- model
1931
+ model,
1932
+ refusal: config.refusal
1745
1933
  })) {
1746
1934
  await s.write(`data: ${JSON.stringify({ delta })}
1747
1935
 
@@ -1757,7 +1945,8 @@ function privateRoutes(deps) {
1757
1945
  messages,
1758
1946
  mode: "private",
1759
1947
  sender,
1760
- model
1948
+ model,
1949
+ refusal: config.refusal
1761
1950
  });
1762
1951
  const reply = await applyTransformReply(
1763
1952
  config.transformReply,
@@ -1924,7 +2113,8 @@ function publicRoutes(deps) {
1924
2113
  system,
1925
2114
  messages,
1926
2115
  mode: "public",
1927
- model
2116
+ model,
2117
+ refusal: config.refusal
1928
2118
  })) {
1929
2119
  await s.write(`data: ${JSON.stringify({ delta })}
1930
2120
 
@@ -1933,7 +2123,15 @@ function publicRoutes(deps) {
1933
2123
  await s.write("event: end\ndata: {}\n\n");
1934
2124
  });
1935
2125
  }
1936
- const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
2126
+ const out = await answerOnce({
2127
+ answerFn,
2128
+ client,
2129
+ system,
2130
+ messages,
2131
+ mode: "public",
2132
+ model,
2133
+ refusal: config.refusal
2134
+ });
1937
2135
  const reply = await applyTransformReply(
1938
2136
  config.transformReply,
1939
2137
  { channel: "widget-public", text: out.content },
@@ -1975,6 +2173,7 @@ async function createServer(config) {
1975
2173
  store = new VectorStore2(createOpenAIEmbedder2(client), {
1976
2174
  databaseClient: db,
1977
2175
  knowledgeDir: config.knowledgeDir || DEFAULT_KNOWLEDGE_DIR2,
2176
+ chunking: config.chunking,
1978
2177
  logger
1979
2178
  });
1980
2179
  }
@@ -2025,7 +2224,7 @@ async function createServer(config) {
2025
2224
  }
2026
2225
  }
2027
2226
  if (serveStatic && staticDir) {
2028
- const relativePath = relative(process.cwd(), staticDir);
2227
+ const relativePath = relative2(process.cwd(), staticDir);
2029
2228
  app.get("/chatter.js", serveStatic({ path: `${relativePath}/chatter.js` }));
2030
2229
  app.get("/chatter.css", serveStatic({ path: `${relativePath}/chatter.css` }));
2031
2230
  }
@@ -2072,6 +2271,7 @@ async function createServer(config) {
2072
2271
  app.get("/demo/react", serveStatic({ path: `${publicDir}/react-demo.html` }));
2073
2272
  }
2074
2273
  const senders = createSenderRegistry(logger);
2274
+ const identities = /* @__PURE__ */ new Map();
2075
2275
  const deps = {
2076
2276
  client,
2077
2277
  store,
@@ -2083,6 +2283,7 @@ async function createServer(config) {
2083
2283
  prompts,
2084
2284
  apiKeyManager,
2085
2285
  senders,
2286
+ identities,
2086
2287
  logger
2087
2288
  };
2088
2289
  if (enablePublic) {
package/dist/types.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  import type { Client as LibsqlClient } from "@libsql/client";
8
8
  import type { Hono } from "hono";
9
9
  import type OpenAI from "openai";
10
- import type { Channel, ChannelSenderRegistry } from "./channels";
10
+ import type { Channel, ChannelSenderRegistry, SessionIdentityRegistry } from "./channels";
11
11
  import type { AnswerFn, TransformReply } from "./core/answer";
12
12
  import type { BucketsFor } from "./core/buckets";
13
13
  import type { KnowledgeHealthCheckConfig } from "./core/knowledgeHealth";
@@ -159,6 +159,22 @@ export interface BrainHooks {
159
159
  * never consulted for them. Unset: replies pass through unchanged.
160
160
  */
161
161
  transformReply?: TransformReply;
162
+ /**
163
+ * The line sent instead of an answer when the output guardrails detect
164
+ * leaked instructions. Chatter otherwise ships no user-facing copy, and
165
+ * this is the one string it puts in a bot's mouth, so a host running a
166
+ * character can supply its own wording.
167
+ *
168
+ * Copy only: detection and credential scrubbing are not configurable, so
169
+ * this voices the guard and never weakens it. A blank string is treated as
170
+ * unset. A caller that has already resolved a persona can override it for
171
+ * one turn by passing `refusal` to `answerOnce`/`answerStream`.
172
+ *
173
+ * Honoured by the channel pipeline and every HTTP chat surface (widget and
174
+ * demo routes, OpenAI-compatible endpoints, MCP chat tools). Unset: the
175
+ * built-in wording applies.
176
+ */
177
+ refusal?: string;
162
178
  }
163
179
  /**
164
180
  * Main configuration for Chatter server
@@ -171,6 +187,13 @@ export interface ChatterConfig extends BrainHooks {
171
187
  configDir?: string;
172
188
  /** Knowledge base directory. Default: ./config/knowledge */
173
189
  knowledgeDir?: string;
190
+ /**
191
+ * How knowledge files are chunked by the default `VectorStore`: `'lines'`
192
+ * (default, unchanged) or `'sections'` (heading-aware, with section context
193
+ * in the embedding). Switching re-embeds the knowledge base once. Ignored
194
+ * when `retriever` is set.
195
+ */
196
+ chunking?: "lines" | "sections";
174
197
  /** Prompts directory. Default: ./config/prompts */
175
198
  promptsDir?: string;
176
199
  /** Public static files directory. Default: ./public */
@@ -431,6 +454,21 @@ export interface ServerDependencies {
431
454
  * channel name without importing the transport.
432
455
  */
433
456
  senders: ChannelSenderRegistry;
457
+ /**
458
+ * The one {@link SessionIdentityRegistry} for this `createServer` call:
459
+ * every identity any of its channels knows itself by, keyed by the endpoint
460
+ * that owns it. Channels register their own identities here on start and
461
+ * resolve `fromBot` against the whole map (`isEffectivelyFromSelf`), so a
462
+ * message from ANOTHER of this process's identities is recognised as "us"
463
+ * rather than answered as a stranger - the loop two of your own bots
464
+ * would otherwise fall into, answering each other until someone notices.
465
+ *
466
+ * Owned by `createServer` so the protection is the default rather than
467
+ * something each host remembers to wire, and scoped to that call the way
468
+ * `stopChannels` is: two servers in one process each protect their own. A host running its own inbound
469
+ * handler (WhatsApp's, say) passes this same map rather than a fresh one.
470
+ */
471
+ identities: SessionIdentityRegistry;
434
472
  /** Resolved logger — `config.logger`, or the default console logger. */
435
473
  logger: Logger;
436
474
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,oFAAoF;IACpF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAE/C,GAAG,EAAE,WAAW,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,IAAI,CAAC,EAAE,aAAa,CAAC;IAGrB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAChC,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,MAAM,EAAE;QACN,qBAAqB;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf;;;;;WAKG;QACH,OAAO,CAAC,EAAE,YAAY,CAAC;KACxB,CAAC;IAGF;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QACT,yBAAyB;QACzB,GAAG,EAAE,MAAM,CAAC;QACZ,uBAAuB;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAGlD,IAAI,CAAC,EAAE;QACL,mDAAmD;QACnD,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,qEAAqE;QACrE,aAAa,CAAC,EAAE;YACd,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;gBAAE,KAAK,EAAE,OAAO,CAAC;gBAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC3F,CAAC;QACF,6CAA6C;QAC7C,GAAG,CAAC,EAAE;YACJ,oCAAoC;YACpC,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,0BAA0B;YAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,4BAA4B;YAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,2CAA2C;YAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;QACF,0BAA0B;QAC1B,KAAK,CAAC,EAAE;YACN,4BAA4B;YAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;YACxB,6BAA6B;YAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;SACtB,CAAC;KACH,CAAC;IAGF,QAAQ,CAAC,EAAE;QACT,iDAAiD;QACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,kDAAkD;QAClD,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,mDAAmD;QACnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B;;;;WAIG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IAGF,SAAS,CAAC,EAAE;QACV,2DAA2D;QAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,6DAA6D;QAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;;;;;;;;WASG;QACH,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB;;;;WAIG;QACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IAGF,MAAM,CAAC,EAAE;QACP,iCAAiC;QACjC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,iCAAiC;QACjC,IAAI,CAAC,EAAE,OAAO,CAAC;QACf;;;;;;;WAOG;QACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B;;;;;;;;WAQG;QACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B;;;;;;;;WAQG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB;;;;;;;;;;;;WAYG;QACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B;;;;;;WAMG;QACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;KAC1C,CAAC;IAGF,2FAA2F;IAC3F,YAAY,CAAC,EAAE,YAAY,CAAC;IAG5B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAGrB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qGAAqG;IACrG,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GACpB,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC,GAC/C,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,+GAA+G;IAC/G,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;;;;;;OAUG;IACH,EAAE,EAAE,YAAY,CAAC;IACjB,4BAA4B;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,+CAA+C;IAC/C,aAAa,CAAC,EAAE;QACd,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC3F,CAAC;IACF;;;;;OAKG;IACH,OAAO,EAAE,qBAAqB,CAAC;IAC/B;;;;;;;;;;;;;OAaG;IACH,UAAU,EAAE,uBAAuB,CAAC;IACpC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,QAAQ,EAAE;QACR,uBAAuB;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,2CAA2C;QAC3C,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;QACrC,8BAA8B;QAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qBAAqB;IACrB,QAAQ,EAAE;QACR,uBAAuB;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,qBAAqB;QACrB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;QACrC,8BAA8B;QAC9B,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegoaltoworks/chatter",
3
- "version": "1.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Embeddable AI chatbot framework with RAG, authentication, and customizable widgets",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -195,26 +195,26 @@
195
195
  }
196
196
  },
197
197
  "dependencies": {
198
- "jose": "6.2.8"
198
+ "jose": "6.2.12"
199
199
  },
200
200
  "devDependencies": {
201
- "@biomejs/biome": "2.5.8",
201
+ "@biomejs/biome": "2.5.14",
202
202
  "@commitlint/cli": "21.2.2",
203
203
  "@commitlint/config-conventional": "21.2.2",
204
204
  "@hono/node-server": "2.1.1",
205
- "@libsql/client": "0.17.4",
206
- "@modelcontextprotocol/sdk": "1.30.0",
207
- "@types/bun": "1.3.14",
208
- "@types/node": "26.2.0",
205
+ "@libsql/client": "0.18.0",
206
+ "@modelcontextprotocol/sdk": "1.31.0",
207
+ "@types/bun": "1.4.2",
208
+ "@types/node": "26.6.1",
209
209
  "@whiskeysockets/baileys": "7.0.0-rc14",
210
210
  "esbuild": "0.28.2",
211
- "hono": "4.13.2",
211
+ "hono": "4.13.8",
212
212
  "husky": "9.1.7",
213
- "lint-staged": "17.3.0",
214
- "openai": "7.4.0",
213
+ "lint-staged": "17.5.1",
214
+ "openai": "7.19.0",
215
215
  "qrcode-terminal": "0.12.0",
216
216
  "typescript": "7.0.2",
217
- "zod": "4.4.3"
217
+ "zod": "4.6.5"
218
218
  },
219
219
  "lint-staged": {
220
220
  "*.{ts,js,json,md}": [
@@ -225,9 +225,9 @@
225
225
  ]
226
226
  },
227
227
  "overrides": {
228
- "qs": "^6.15.3",
228
+ "qs": "^6.15.4",
229
229
  "ws": "^8.21.1",
230
- "fast-uri": "^3.1.3",
230
+ "fast-uri": "^3.1.6",
231
231
  "ip-address": "^10.4.0"
232
232
  }
233
233
  }