@diegoaltoworks/chatter 1.0.0 → 2.0.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 (72) 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/guardrails.d.ts +11 -1
  43. package/dist/core/guardrails.d.ts.map +1 -1
  44. package/dist/core/llm.d.ts +3 -1
  45. package/dist/core/llm.d.ts.map +1 -1
  46. package/dist/history/index.js +12 -9
  47. package/dist/history/index.mjs +12 -9
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +50 -27
  51. package/dist/index.mjs +49 -27
  52. package/dist/mcp-server.d.ts.map +1 -1
  53. package/dist/mcp-server.js +16 -11
  54. package/dist/mcp-server.mjs +16 -11
  55. package/dist/personas/index.d.ts +1 -1
  56. package/dist/personas/index.d.ts.map +1 -1
  57. package/dist/personas/index.js +17 -5
  58. package/dist/personas/index.mjs +17 -5
  59. package/dist/personas/resolver.d.ts +35 -8
  60. package/dist/personas/resolver.d.ts.map +1 -1
  61. package/dist/routes/demo.d.ts.map +1 -1
  62. package/dist/routes/openai.d.ts.map +1 -1
  63. package/dist/routes/private.d.ts.map +1 -1
  64. package/dist/routes/public.d.ts.map +1 -1
  65. package/dist/scheduler/index.js +12 -9
  66. package/dist/scheduler/index.mjs +12 -9
  67. package/dist/server.d.ts.map +1 -1
  68. package/dist/server.js +44 -25
  69. package/dist/server.mjs +44 -25
  70. package/dist/types.d.ts +32 -1
  71. package/dist/types.d.ts.map +1 -1
  72. package/package.json +11 -11
package/dist/index.js CHANGED
@@ -538,6 +538,7 @@ __export(index_exports, {
538
538
  DEFAULT_KNOWLEDGE_DIR: () => DEFAULT_KNOWLEDGE_DIR,
539
539
  DEFAULT_MODEL: () => DEFAULT_MODEL,
540
540
  DEFAULT_PROMPTS_DIR: () => DEFAULT_PROMPTS_DIR,
541
+ DEFAULT_REFUSAL: () => DEFAULT_REFUSAL,
541
542
  PromptLoader: () => PromptLoader,
542
543
  VectorStore: () => VectorStore,
543
544
  answerOnce: () => answerOnce,
@@ -719,9 +720,10 @@ function detectLeakage(text) {
719
720
  function scrubOutput(text) {
720
721
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
721
722
  }
722
- function guardOutput(text) {
723
+ var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
724
+ function guardOutput(text, refusal) {
723
725
  if (detectLeakage(text)) {
724
- return "Sorry, I can't share internal instructions. How else can I help?";
726
+ return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
725
727
  }
726
728
  return scrubOutput(text);
727
729
  }
@@ -733,7 +735,8 @@ async function completeOnce({
733
735
  system,
734
736
  messages,
735
737
  temperature = 0.2,
736
- model = DEFAULT_MODEL
738
+ model = DEFAULT_MODEL,
739
+ refusal
737
740
  }) {
738
741
  const res = await client.chat.completions.create({
739
742
  model,
@@ -742,7 +745,7 @@ async function completeOnce({
742
745
  });
743
746
  const text = res.choices[0]?.message?.content ?? "";
744
747
  return {
745
- content: guardOutput(text),
748
+ content: guardOutput(text, refusal),
746
749
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
747
750
  };
748
751
  }
@@ -767,12 +770,12 @@ async function* completeStream({
767
770
 
768
771
  // src/core/answer.ts
769
772
  var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
770
- async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
773
+ async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
771
774
  const result = await answerFn({ system, messages, mode, sender, conversationId });
772
775
  const raw = typeof result === "string" ? result : result?.content;
773
776
  const usage = typeof result === "string" ? void 0 : result?.usage;
774
777
  return {
775
- content: guardOutput(typeof raw === "string" ? raw : ""),
778
+ content: guardOutput(typeof raw === "string" ? raw : "", refusal),
776
779
  usage: usage ?? noUsage()
777
780
  };
778
781
  }
@@ -785,12 +788,13 @@ async function answerOnce({
785
788
  sender,
786
789
  conversationId,
787
790
  temperature,
788
- model
791
+ model,
792
+ refusal
789
793
  }) {
790
794
  if (answerFn) {
791
- return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
795
+ return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
792
796
  }
793
- return completeOnce({ client, system, messages, temperature, model });
797
+ return completeOnce({ client, system, messages, temperature, model, refusal });
794
798
  }
795
799
  async function applyTransformReply(transformReply, input, logger) {
796
800
  if (!transformReply) return input.text;
@@ -814,16 +818,15 @@ async function* answerStream({
814
818
  sender,
815
819
  conversationId,
816
820
  temperature,
817
- model
821
+ model,
822
+ refusal
818
823
  }) {
819
824
  if (answerFn) {
820
- const { content } = await runAnswerFn(answerFn, {
821
- system,
822
- messages,
823
- mode,
824
- sender,
825
- conversationId
826
- });
825
+ const { content } = await runAnswerFn(
826
+ answerFn,
827
+ { system, messages, mode, sender, conversationId },
828
+ refusal
829
+ );
827
830
  if (content) yield content;
828
831
  return;
829
832
  }
@@ -1422,7 +1425,8 @@ async function createMCPServer(config) {
1422
1425
  messages: conversationMessages,
1423
1426
  mode: "public",
1424
1427
  conversationId: convId,
1425
- model
1428
+ model,
1429
+ refusal: config.refusal
1426
1430
  });
1427
1431
  const replyText = await applyTransformReply(
1428
1432
  config.transformReply,
@@ -1512,7 +1516,8 @@ async function createMCPServer(config) {
1512
1516
  messages: conversationMessages,
1513
1517
  mode: "private",
1514
1518
  conversationId: convId,
1515
- model
1519
+ model,
1520
+ refusal: config.refusal
1516
1521
  });
1517
1522
  const replyText = await applyTransformReply(
1518
1523
  config.transformReply,
@@ -2011,7 +2016,8 @@ function demoRoutes(deps) {
2011
2016
  system,
2012
2017
  messages,
2013
2018
  mode: "public",
2014
- model
2019
+ model,
2020
+ refusal: config.refusal
2015
2021
  })) {
2016
2022
  await s.write(`data: ${JSON.stringify({ delta })}
2017
2023
 
@@ -2026,7 +2032,8 @@ function demoRoutes(deps) {
2026
2032
  system,
2027
2033
  messages,
2028
2034
  mode: "public",
2029
- model
2035
+ model,
2036
+ refusal: config.refusal
2030
2037
  });
2031
2038
  const reply = await applyTransformReply(
2032
2039
  config.transformReply,
@@ -2167,7 +2174,8 @@ function openaiRoutes(deps) {
2167
2174
  sender,
2168
2175
  conversationId,
2169
2176
  temperature,
2170
- model: serverModel
2177
+ model: serverModel,
2178
+ refusal: config.refusal
2171
2179
  })) {
2172
2180
  await s.write(chunk2({ content: delta }, null));
2173
2181
  }
@@ -2184,7 +2192,8 @@ function openaiRoutes(deps) {
2184
2192
  sender,
2185
2193
  conversationId,
2186
2194
  temperature,
2187
- model: serverModel
2195
+ model: serverModel,
2196
+ refusal: config.refusal
2188
2197
  });
2189
2198
  const reply = await applyTransformReply(
2190
2199
  config.transformReply,
@@ -2275,7 +2284,8 @@ function privateRoutes(deps) {
2275
2284
  messages,
2276
2285
  mode: "private",
2277
2286
  sender,
2278
- model
2287
+ model,
2288
+ refusal: config.refusal
2279
2289
  })) {
2280
2290
  await s.write(`data: ${JSON.stringify({ delta })}
2281
2291
 
@@ -2291,7 +2301,8 @@ function privateRoutes(deps) {
2291
2301
  messages,
2292
2302
  mode: "private",
2293
2303
  sender,
2294
- model
2304
+ model,
2305
+ refusal: config.refusal
2295
2306
  });
2296
2307
  const reply = await applyTransformReply(
2297
2308
  config.transformReply,
@@ -2360,7 +2371,8 @@ function publicRoutes(deps) {
2360
2371
  system,
2361
2372
  messages,
2362
2373
  mode: "public",
2363
- model
2374
+ model,
2375
+ refusal: config.refusal
2364
2376
  })) {
2365
2377
  await s.write(`data: ${JSON.stringify({ delta })}
2366
2378
 
@@ -2369,7 +2381,15 @@ function publicRoutes(deps) {
2369
2381
  await s.write("event: end\ndata: {}\n\n");
2370
2382
  });
2371
2383
  }
2372
- const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
2384
+ const out = await answerOnce({
2385
+ answerFn,
2386
+ client,
2387
+ system,
2388
+ messages,
2389
+ mode: "public",
2390
+ model,
2391
+ refusal: config.refusal
2392
+ });
2373
2393
  const reply = await applyTransformReply(
2374
2394
  config.transformReply,
2375
2395
  { channel: "widget-public", text: out.content },
@@ -2638,6 +2658,7 @@ async function createServer(config) {
2638
2658
  app.get("/demo/react", serveStatic({ path: `${publicDir}/react-demo.html` }));
2639
2659
  }
2640
2660
  const senders = createSenderRegistry(logger);
2661
+ const identities = /* @__PURE__ */ new Map();
2641
2662
  const deps = {
2642
2663
  client,
2643
2664
  store,
@@ -2649,6 +2670,7 @@ async function createServer(config) {
2649
2670
  prompts,
2650
2671
  apiKeyManager,
2651
2672
  senders,
2673
+ identities,
2652
2674
  logger
2653
2675
  };
2654
2676
  if (enablePublic) {
@@ -2743,6 +2765,7 @@ function createShortener(config, fetchImpl = fetch) {
2743
2765
  DEFAULT_KNOWLEDGE_DIR,
2744
2766
  DEFAULT_MODEL,
2745
2767
  DEFAULT_PROMPTS_DIR,
2768
+ DEFAULT_REFUSAL,
2746
2769
  PromptLoader,
2747
2770
  VectorStore,
2748
2771
  answerOnce,
package/dist/index.mjs CHANGED
@@ -644,9 +644,10 @@ function detectLeakage(text) {
644
644
  function scrubOutput(text) {
645
645
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
646
646
  }
647
- function guardOutput(text) {
647
+ var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
648
+ function guardOutput(text, refusal) {
648
649
  if (detectLeakage(text)) {
649
- return "Sorry, I can't share internal instructions. How else can I help?";
650
+ return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
650
651
  }
651
652
  return scrubOutput(text);
652
653
  }
@@ -658,7 +659,8 @@ async function completeOnce({
658
659
  system,
659
660
  messages,
660
661
  temperature = 0.2,
661
- model = DEFAULT_MODEL
662
+ model = DEFAULT_MODEL,
663
+ refusal
662
664
  }) {
663
665
  const res = await client.chat.completions.create({
664
666
  model,
@@ -667,7 +669,7 @@ async function completeOnce({
667
669
  });
668
670
  const text = res.choices[0]?.message?.content ?? "";
669
671
  return {
670
- content: guardOutput(text),
672
+ content: guardOutput(text, refusal),
671
673
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
672
674
  };
673
675
  }
@@ -692,12 +694,12 @@ async function* completeStream({
692
694
 
693
695
  // src/core/answer.ts
694
696
  var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
695
- async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
697
+ async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
696
698
  const result = await answerFn({ system, messages, mode, sender, conversationId });
697
699
  const raw = typeof result === "string" ? result : result?.content;
698
700
  const usage = typeof result === "string" ? void 0 : result?.usage;
699
701
  return {
700
- content: guardOutput(typeof raw === "string" ? raw : ""),
702
+ content: guardOutput(typeof raw === "string" ? raw : "", refusal),
701
703
  usage: usage ?? noUsage()
702
704
  };
703
705
  }
@@ -710,12 +712,13 @@ async function answerOnce({
710
712
  sender,
711
713
  conversationId,
712
714
  temperature,
713
- model
715
+ model,
716
+ refusal
714
717
  }) {
715
718
  if (answerFn) {
716
- return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
719
+ return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
717
720
  }
718
- return completeOnce({ client, system, messages, temperature, model });
721
+ return completeOnce({ client, system, messages, temperature, model, refusal });
719
722
  }
720
723
  async function applyTransformReply(transformReply, input, logger) {
721
724
  if (!transformReply) return input.text;
@@ -739,16 +742,15 @@ async function* answerStream({
739
742
  sender,
740
743
  conversationId,
741
744
  temperature,
742
- model
745
+ model,
746
+ refusal
743
747
  }) {
744
748
  if (answerFn) {
745
- const { content } = await runAnswerFn(answerFn, {
746
- system,
747
- messages,
748
- mode,
749
- sender,
750
- conversationId
751
- });
749
+ const { content } = await runAnswerFn(
750
+ answerFn,
751
+ { system, messages, mode, sender, conversationId },
752
+ refusal
753
+ );
752
754
  if (content) yield content;
753
755
  return;
754
756
  }
@@ -1347,7 +1349,8 @@ async function createMCPServer(config) {
1347
1349
  messages: conversationMessages,
1348
1350
  mode: "public",
1349
1351
  conversationId: convId,
1350
- model
1352
+ model,
1353
+ refusal: config.refusal
1351
1354
  });
1352
1355
  const replyText = await applyTransformReply(
1353
1356
  config.transformReply,
@@ -1437,7 +1440,8 @@ async function createMCPServer(config) {
1437
1440
  messages: conversationMessages,
1438
1441
  mode: "private",
1439
1442
  conversationId: convId,
1440
- model
1443
+ model,
1444
+ refusal: config.refusal
1441
1445
  });
1442
1446
  const replyText = await applyTransformReply(
1443
1447
  config.transformReply,
@@ -1936,7 +1940,8 @@ function demoRoutes(deps) {
1936
1940
  system,
1937
1941
  messages,
1938
1942
  mode: "public",
1939
- model
1943
+ model,
1944
+ refusal: config.refusal
1940
1945
  })) {
1941
1946
  await s.write(`data: ${JSON.stringify({ delta })}
1942
1947
 
@@ -1951,7 +1956,8 @@ function demoRoutes(deps) {
1951
1956
  system,
1952
1957
  messages,
1953
1958
  mode: "public",
1954
- model
1959
+ model,
1960
+ refusal: config.refusal
1955
1961
  });
1956
1962
  const reply = await applyTransformReply(
1957
1963
  config.transformReply,
@@ -2092,7 +2098,8 @@ function openaiRoutes(deps) {
2092
2098
  sender,
2093
2099
  conversationId,
2094
2100
  temperature,
2095
- model: serverModel
2101
+ model: serverModel,
2102
+ refusal: config.refusal
2096
2103
  })) {
2097
2104
  await s.write(chunk2({ content: delta }, null));
2098
2105
  }
@@ -2109,7 +2116,8 @@ function openaiRoutes(deps) {
2109
2116
  sender,
2110
2117
  conversationId,
2111
2118
  temperature,
2112
- model: serverModel
2119
+ model: serverModel,
2120
+ refusal: config.refusal
2113
2121
  });
2114
2122
  const reply = await applyTransformReply(
2115
2123
  config.transformReply,
@@ -2200,7 +2208,8 @@ function privateRoutes(deps) {
2200
2208
  messages,
2201
2209
  mode: "private",
2202
2210
  sender,
2203
- model
2211
+ model,
2212
+ refusal: config.refusal
2204
2213
  })) {
2205
2214
  await s.write(`data: ${JSON.stringify({ delta })}
2206
2215
 
@@ -2216,7 +2225,8 @@ function privateRoutes(deps) {
2216
2225
  messages,
2217
2226
  mode: "private",
2218
2227
  sender,
2219
- model
2228
+ model,
2229
+ refusal: config.refusal
2220
2230
  });
2221
2231
  const reply = await applyTransformReply(
2222
2232
  config.transformReply,
@@ -2285,7 +2295,8 @@ function publicRoutes(deps) {
2285
2295
  system,
2286
2296
  messages,
2287
2297
  mode: "public",
2288
- model
2298
+ model,
2299
+ refusal: config.refusal
2289
2300
  })) {
2290
2301
  await s.write(`data: ${JSON.stringify({ delta })}
2291
2302
 
@@ -2294,7 +2305,15 @@ function publicRoutes(deps) {
2294
2305
  await s.write("event: end\ndata: {}\n\n");
2295
2306
  });
2296
2307
  }
2297
- const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
2308
+ const out = await answerOnce({
2309
+ answerFn,
2310
+ client,
2311
+ system,
2312
+ messages,
2313
+ mode: "public",
2314
+ model,
2315
+ refusal: config.refusal
2316
+ });
2298
2317
  const reply = await applyTransformReply(
2299
2318
  config.transformReply,
2300
2319
  { channel: "widget-public", text: out.content },
@@ -2562,6 +2581,7 @@ async function createServer(config) {
2562
2581
  app.get("/demo/react", serveStatic({ path: `${publicDir}/react-demo.html` }));
2563
2582
  }
2564
2583
  const senders = createSenderRegistry(logger);
2584
+ const identities = /* @__PURE__ */ new Map();
2565
2585
  const deps = {
2566
2586
  client,
2567
2587
  store,
@@ -2573,6 +2593,7 @@ async function createServer(config) {
2573
2593
  prompts,
2574
2594
  apiKeyManager,
2575
2595
  senders,
2596
+ identities,
2576
2597
  logger
2577
2598
  };
2578
2599
  if (enablePublic) {
@@ -2666,6 +2687,7 @@ export {
2666
2687
  DEFAULT_KNOWLEDGE_DIR,
2667
2688
  DEFAULT_MODEL,
2668
2689
  DEFAULT_PROMPTS_DIR,
2690
+ DEFAULT_REFUSAL,
2669
2691
  PromptLoader,
2670
2692
  VectorStore,
2671
2693
  answerOnce,
@@ -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;qCA4U3B,IAAI;GAEtC"}
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;qCA8U3B,IAAI;GAEtC"}
@@ -546,9 +546,10 @@ function detectLeakage(text) {
546
546
  function scrubOutput(text) {
547
547
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
548
548
  }
549
- function guardOutput(text) {
549
+ var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
550
+ function guardOutput(text, refusal) {
550
551
  if (detectLeakage(text)) {
551
- return "Sorry, I can't share internal instructions. How else can I help?";
552
+ return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
552
553
  }
553
554
  return scrubOutput(text);
554
555
  }
@@ -560,7 +561,8 @@ async function completeOnce({
560
561
  system,
561
562
  messages,
562
563
  temperature = 0.2,
563
- model = DEFAULT_MODEL
564
+ model = DEFAULT_MODEL,
565
+ refusal
564
566
  }) {
565
567
  const res = await client.chat.completions.create({
566
568
  model,
@@ -569,19 +571,19 @@ async function completeOnce({
569
571
  });
570
572
  const text = res.choices[0]?.message?.content ?? "";
571
573
  return {
572
- content: guardOutput(text),
574
+ content: guardOutput(text, refusal),
573
575
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
574
576
  };
575
577
  }
576
578
 
577
579
  // src/core/answer.ts
578
580
  var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
579
- async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
581
+ async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
580
582
  const result = await answerFn({ system, messages, mode, sender, conversationId });
581
583
  const raw = typeof result === "string" ? result : result?.content;
582
584
  const usage = typeof result === "string" ? void 0 : result?.usage;
583
585
  return {
584
- content: guardOutput(typeof raw === "string" ? raw : ""),
586
+ content: guardOutput(typeof raw === "string" ? raw : "", refusal),
585
587
  usage: usage ?? noUsage()
586
588
  };
587
589
  }
@@ -594,12 +596,13 @@ async function answerOnce({
594
596
  sender,
595
597
  conversationId,
596
598
  temperature,
597
- model
599
+ model,
600
+ refusal
598
601
  }) {
599
602
  if (answerFn) {
600
- return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
603
+ return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
601
604
  }
602
- return completeOnce({ client, system, messages, temperature, model });
605
+ return completeOnce({ client, system, messages, temperature, model, refusal });
603
606
  }
604
607
  async function applyTransformReply(transformReply, input, logger) {
605
608
  if (!transformReply) return input.text;
@@ -1100,7 +1103,8 @@ async function createMCPServer(config) {
1100
1103
  messages: conversationMessages,
1101
1104
  mode: "public",
1102
1105
  conversationId: convId,
1103
- model
1106
+ model,
1107
+ refusal: config.refusal
1104
1108
  });
1105
1109
  const replyText = await applyTransformReply(
1106
1110
  config.transformReply,
@@ -1190,7 +1194,8 @@ async function createMCPServer(config) {
1190
1194
  messages: conversationMessages,
1191
1195
  mode: "private",
1192
1196
  conversationId: convId,
1193
- model
1197
+ model,
1198
+ refusal: config.refusal
1194
1199
  });
1195
1200
  const replyText = await applyTransformReply(
1196
1201
  config.transformReply,
@@ -518,9 +518,10 @@ function detectLeakage(text) {
518
518
  function scrubOutput(text) {
519
519
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
520
520
  }
521
- function guardOutput(text) {
521
+ var DEFAULT_REFUSAL = "Sorry, I can't share internal instructions. How else can I help?";
522
+ function guardOutput(text, refusal) {
522
523
  if (detectLeakage(text)) {
523
- return "Sorry, I can't share internal instructions. How else can I help?";
524
+ return typeof refusal === "string" && refusal.trim() ? refusal : DEFAULT_REFUSAL;
524
525
  }
525
526
  return scrubOutput(text);
526
527
  }
@@ -532,7 +533,8 @@ async function completeOnce({
532
533
  system,
533
534
  messages,
534
535
  temperature = 0.2,
535
- model = DEFAULT_MODEL
536
+ model = DEFAULT_MODEL,
537
+ refusal
536
538
  }) {
537
539
  const res = await client.chat.completions.create({
538
540
  model,
@@ -541,19 +543,19 @@ async function completeOnce({
541
543
  });
542
544
  const text = res.choices[0]?.message?.content ?? "";
543
545
  return {
544
- content: guardOutput(text),
546
+ content: guardOutput(text, refusal),
545
547
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
546
548
  };
547
549
  }
548
550
 
549
551
  // src/core/answer.ts
550
552
  var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
551
- async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
553
+ async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal) {
552
554
  const result = await answerFn({ system, messages, mode, sender, conversationId });
553
555
  const raw = typeof result === "string" ? result : result?.content;
554
556
  const usage = typeof result === "string" ? void 0 : result?.usage;
555
557
  return {
556
- content: guardOutput(typeof raw === "string" ? raw : ""),
558
+ content: guardOutput(typeof raw === "string" ? raw : "", refusal),
557
559
  usage: usage ?? noUsage()
558
560
  };
559
561
  }
@@ -566,12 +568,13 @@ async function answerOnce({
566
568
  sender,
567
569
  conversationId,
568
570
  temperature,
569
- model
571
+ model,
572
+ refusal
570
573
  }) {
571
574
  if (answerFn) {
572
- return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
575
+ return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }, refusal);
573
576
  }
574
- return completeOnce({ client, system, messages, temperature, model });
577
+ return completeOnce({ client, system, messages, temperature, model, refusal });
575
578
  }
576
579
  async function applyTransformReply(transformReply, input, logger) {
577
580
  if (!transformReply) return input.text;
@@ -1072,7 +1075,8 @@ async function createMCPServer(config) {
1072
1075
  messages: conversationMessages,
1073
1076
  mode: "public",
1074
1077
  conversationId: convId,
1075
- model
1078
+ model,
1079
+ refusal: config.refusal
1076
1080
  });
1077
1081
  const replyText = await applyTransformReply(
1078
1082
  config.transformReply,
@@ -1162,7 +1166,8 @@ async function createMCPServer(config) {
1162
1166
  messages: conversationMessages,
1163
1167
  mode: "private",
1164
1168
  conversationId: convId,
1165
- model
1169
+ model,
1170
+ refusal: config.refusal
1166
1171
  });
1167
1172
  const replyText = await applyTransformReply(
1168
1173
  config.transformReply,
@@ -8,7 +8,7 @@
8
8
  */
9
9
  export type { Greeter, GreeterOptions } from "./greeter";
10
10
  export { createGreeter } from "./greeter";
11
- export type { PersonaContact, PersonaDefinition, PersonaRegistry, PersonaResolver, PersonaResolverOptions, } from "./resolver";
11
+ export type { PersonaContact, PersonaDefinition, PersonaEndpoint, PersonaKey, PersonaRegistry, PersonaResolver, PersonaResolverOptions, } from "./resolver";
12
12
  export { createPersonaResolver } from "./resolver";
13
13
  export { timeContext } from "./timeContext";
14
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/personas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/personas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -124,7 +124,19 @@ function createPersonaResolver(options = {}) {
124
124
  return void 0;
125
125
  }
126
126
  }
127
- function rollPersonaId(contactId) {
127
+ function endpointPersonaId(endpointId) {
128
+ if (!endpointId) return null;
129
+ try {
130
+ return loadRegistry().endpoints?.[endpointId]?.persona ?? null;
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+ function rollPersonaId(key) {
136
+ const { contactId, endpointId } = typeof key === "string" ? { contactId: key } : key;
137
+ const boundToEndpoint = endpointPersonaId(endpointId);
138
+ if (boundToEndpoint) return boundToEndpoint;
139
+ if (contactId === void 0) return null;
128
140
  try {
129
141
  const reg = loadRegistry();
130
142
  const nowMs = now();
@@ -132,8 +144,8 @@ function createPersonaResolver(options = {}) {
132
144
  if (existing && existing.expiresAt > nowMs) {
133
145
  return existing.personaId;
134
146
  }
135
- for (const [key, value] of window) {
136
- if (value.expiresAt <= nowMs) window.delete(key);
147
+ for (const [held, value] of window) {
148
+ if (value.expiresAt <= nowMs) window.delete(held);
137
149
  }
138
150
  const contact = reg.contacts?.[contactId];
139
151
  let personaId = null;
@@ -181,8 +193,8 @@ function createPersonaResolver(options = {}) {
181
193
  return null;
182
194
  }
183
195
  }
184
- function resolvePersonaLayer(contactId) {
185
- return personaLayerFor(rollPersonaId(contactId)) ?? personaLayerFor(defaultPersonaId());
196
+ function resolvePersonaLayer(key) {
197
+ return personaLayerFor(rollPersonaId(key)) ?? personaLayerFor(defaultPersonaId());
186
198
  }
187
199
  return {
188
200
  rollPersonaId,