@diegoaltoworks/chatter 0.43.0 → 0.45.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 (156) hide show
  1. package/dist/client/index.js +615 -0
  2. package/dist/client/index.mjs +592 -0
  3. package/dist/core/messages.d.ts +38 -0
  4. package/dist/core/messages.d.ts.map +1 -0
  5. package/dist/core/session.d.ts +1 -0
  6. package/dist/core/session.d.ts.map +1 -1
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +64 -51
  10. package/dist/index.mjs +62 -51
  11. package/dist/routes/demo.d.ts.map +1 -1
  12. package/dist/routes/openai.d.ts +0 -7
  13. package/dist/routes/openai.d.ts.map +1 -1
  14. package/dist/routes/private.d.ts.map +1 -1
  15. package/dist/routes/public.d.ts.map +1 -1
  16. package/dist/server.js +1526 -0
  17. package/dist/server.mjs +1497 -0
  18. package/package.json +9 -5
  19. package/dist/auth/apikeys.test.d.ts +0 -2
  20. package/dist/auth/apikeys.test.d.ts.map +0 -1
  21. package/dist/channels/gates.test.d.ts +0 -2
  22. package/dist/channels/gates.test.d.ts.map +0 -1
  23. package/dist/channels/senders.test.d.ts +0 -2
  24. package/dist/channels/senders.test.d.ts.map +0 -1
  25. package/dist/channels/whatsapp/authState.test.d.ts +0 -2
  26. package/dist/channels/whatsapp/authState.test.d.ts.map +0 -1
  27. package/dist/channels/whatsapp/baileys.test.d.ts +0 -2
  28. package/dist/channels/whatsapp/baileys.test.d.ts.map +0 -1
  29. package/dist/channels/whatsapp/channel.test.d.ts +0 -2
  30. package/dist/channels/whatsapp/channel.test.d.ts.map +0 -1
  31. package/dist/channels/whatsapp/crypto.test.d.ts +0 -2
  32. package/dist/channels/whatsapp/crypto.test.d.ts.map +0 -1
  33. package/dist/channels/whatsapp/images.test.d.ts +0 -2
  34. package/dist/channels/whatsapp/images.test.d.ts.map +0 -1
  35. package/dist/channels/whatsapp/inbound.test.d.ts +0 -2
  36. package/dist/channels/whatsapp/inbound.test.d.ts.map +0 -1
  37. package/dist/channels/whatsapp/lease.test.d.ts +0 -2
  38. package/dist/channels/whatsapp/lease.test.d.ts.map +0 -1
  39. package/dist/channels/whatsapp/pairing.test.d.ts +0 -2
  40. package/dist/channels/whatsapp/pairing.test.d.ts.map +0 -1
  41. package/dist/channels/whatsapp/qr.test.d.ts +0 -2
  42. package/dist/channels/whatsapp/qr.test.d.ts.map +0 -1
  43. package/dist/client/__tests__/markdown.test.d.ts +0 -5
  44. package/dist/client/__tests__/markdown.test.d.ts.map +0 -1
  45. package/dist/client/__tests__/mobile-chat.test.d.ts +0 -6
  46. package/dist/client/__tests__/mobile-chat.test.d.ts.map +0 -1
  47. package/dist/client/examples/node.d.ts +0 -5
  48. package/dist/client/examples/node.d.ts.map +0 -1
  49. package/dist/core/answer.test.d.ts +0 -8
  50. package/dist/core/answer.test.d.ts.map +0 -1
  51. package/dist/core/buckets.test.d.ts +0 -10
  52. package/dist/core/buckets.test.d.ts.map +0 -1
  53. package/dist/core/guardrails.test.d.ts +0 -2
  54. package/dist/core/guardrails.test.d.ts.map +0 -1
  55. package/dist/core/loaders.test.d.ts +0 -2
  56. package/dist/core/loaders.test.d.ts.map +0 -1
  57. package/dist/core/pipeline.test.d.ts +0 -8
  58. package/dist/core/pipeline.test.d.ts.map +0 -1
  59. package/dist/core/prompts.test.d.ts +0 -2
  60. package/dist/core/prompts.test.d.ts.map +0 -1
  61. package/dist/core/retrieval.test.d.ts +0 -8
  62. package/dist/core/retrieval.test.d.ts.map +0 -1
  63. package/dist/core/session.test.d.ts +0 -2
  64. package/dist/core/session.test.d.ts.map +0 -1
  65. package/dist/core/widgets.test.d.ts +0 -2
  66. package/dist/core/widgets.test.d.ts.map +0 -1
  67. package/dist/flows/__fixtures__/broken/handler.d.ts +0 -3
  68. package/dist/flows/__fixtures__/broken/handler.d.ts.map +0 -1
  69. package/dist/flows/__fixtures__/greeting/handler.d.ts +0 -3
  70. package/dist/flows/__fixtures__/greeting/handler.d.ts.map +0 -1
  71. package/dist/flows/__fixtures__/greeting/prefill.d.ts +0 -3
  72. package/dist/flows/__fixtures__/greeting/prefill.d.ts.map +0 -1
  73. package/dist/flows/engine.test.d.ts +0 -9
  74. package/dist/flows/engine.test.d.ts.map +0 -1
  75. package/dist/flows/intent.test.d.ts +0 -6
  76. package/dist/flows/intent.test.d.ts.map +0 -1
  77. package/dist/flows/loader.test.d.ts +0 -8
  78. package/dist/flows/loader.test.d.ts.map +0 -1
  79. package/dist/flows/params.test.d.ts +0 -2
  80. package/dist/flows/params.test.d.ts.map +0 -1
  81. package/dist/flows/registry.test.d.ts +0 -2
  82. package/dist/flows/registry.test.d.ts.map +0 -1
  83. package/dist/flows/session.test.d.ts +0 -7
  84. package/dist/flows/session.test.d.ts.map +0 -1
  85. package/dist/flows/utils.test.d.ts +0 -2
  86. package/dist/flows/utils.test.d.ts.map +0 -1
  87. package/dist/images/cache.test.d.ts +0 -2
  88. package/dist/images/cache.test.d.ts.map +0 -1
  89. package/dist/images/cacheStore.test.d.ts +0 -8
  90. package/dist/images/cacheStore.test.d.ts.map +0 -1
  91. package/dist/images/captionComposer.test.d.ts +0 -2
  92. package/dist/images/captionComposer.test.d.ts.map +0 -1
  93. package/dist/images/cloudinaryClient.test.d.ts +0 -2
  94. package/dist/images/cloudinaryClient.test.d.ts.map +0 -1
  95. package/dist/images/cloudinaryConfig.test.d.ts +0 -2
  96. package/dist/images/cloudinaryConfig.test.d.ts.map +0 -1
  97. package/dist/images/cloudinarySignature.test.d.ts +0 -2
  98. package/dist/images/cloudinarySignature.test.d.ts.map +0 -1
  99. package/dist/images/config.test.d.ts +0 -2
  100. package/dist/images/config.test.d.ts.map +0 -1
  101. package/dist/images/generator.test.d.ts +0 -2
  102. package/dist/images/generator.test.d.ts.map +0 -1
  103. package/dist/images/openaiClient.test.d.ts +0 -2
  104. package/dist/images/openaiClient.test.d.ts.map +0 -1
  105. package/dist/images/uploader.test.d.ts +0 -2
  106. package/dist/images/uploader.test.d.ts.map +0 -1
  107. package/dist/mcp-server/conversation-id.test.d.ts +0 -2
  108. package/dist/mcp-server/conversation-id.test.d.ts.map +0 -1
  109. package/dist/mcp-server/cost-tracker.test.d.ts +0 -2
  110. package/dist/mcp-server/cost-tracker.test.d.ts.map +0 -1
  111. package/dist/mcp-server/logger.test.d.ts +0 -2
  112. package/dist/mcp-server/logger.test.d.ts.map +0 -1
  113. package/dist/mcp-server/rate-limiter.test.d.ts +0 -2
  114. package/dist/mcp-server/rate-limiter.test.d.ts.map +0 -1
  115. package/dist/middleware/auth.test.d.ts +0 -2
  116. package/dist/middleware/auth.test.d.ts.map +0 -1
  117. package/dist/middleware/cors.test.d.ts +0 -2
  118. package/dist/middleware/cors.test.d.ts.map +0 -1
  119. package/dist/middleware/jwt.test.d.ts +0 -2
  120. package/dist/middleware/jwt.test.d.ts.map +0 -1
  121. package/dist/middleware/ratelimit.test.d.ts +0 -2
  122. package/dist/middleware/ratelimit.test.d.ts.map +0 -1
  123. package/dist/middleware/referrer.test.d.ts +0 -2
  124. package/dist/middleware/referrer.test.d.ts.map +0 -1
  125. package/dist/middleware/session.test.d.ts +0 -2
  126. package/dist/middleware/session.test.d.ts.map +0 -1
  127. package/dist/personas/greeter.test.d.ts +0 -2
  128. package/dist/personas/greeter.test.d.ts.map +0 -1
  129. package/dist/personas/resolver.test.d.ts +0 -2
  130. package/dist/personas/resolver.test.d.ts.map +0 -1
  131. package/dist/personas/timeContext.test.d.ts +0 -2
  132. package/dist/personas/timeContext.test.d.ts.map +0 -1
  133. package/dist/routes/chat.test.d.ts +0 -9
  134. package/dist/routes/chat.test.d.ts.map +0 -1
  135. package/dist/routes/openai.test.d.ts +0 -8
  136. package/dist/routes/openai.test.d.ts.map +0 -1
  137. package/dist/scheduler/claimStore.test.d.ts +0 -2
  138. package/dist/scheduler/claimStore.test.d.ts.map +0 -1
  139. package/dist/scheduler/compose.test.d.ts +0 -2
  140. package/dist/scheduler/compose.test.d.ts.map +0 -1
  141. package/dist/scheduler/deliver.test.d.ts +0 -2
  142. package/dist/scheduler/deliver.test.d.ts.map +0 -1
  143. package/dist/scheduler/dueDrops.test.d.ts +0 -2
  144. package/dist/scheduler/dueDrops.test.d.ts.map +0 -1
  145. package/dist/scheduler/scheduler.test.d.ts +0 -2
  146. package/dist/scheduler/scheduler.test.d.ts.map +0 -1
  147. package/dist/scheduler/tick.test.d.ts +0 -2
  148. package/dist/scheduler/tick.test.d.ts.map +0 -1
  149. package/dist/server.test.d.ts +0 -9
  150. package/dist/server.test.d.ts.map +0 -1
  151. package/dist/shortener.test.d.ts +0 -2
  152. package/dist/shortener.test.d.ts.map +0 -1
  153. package/dist/usage/limits.test.d.ts +0 -10
  154. package/dist/usage/limits.test.d.ts.map +0 -1
  155. package/dist/usage/tursoStore.test.d.ts +0 -9
  156. package/dist/usage/tursoStore.test.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -7559,6 +7559,8 @@ __export(index_exports, {
7559
7559
  guardOutput: () => guardOutput,
7560
7560
  jwtSubject: () => jwtSubject,
7561
7561
  loadKnowledge: () => loadKnowledge,
7562
+ normalizeChatBody: () => normalizeChatBody,
7563
+ normalizeMessages: () => normalizeMessages,
7562
7564
  openaiRoutes: () => openaiRoutes,
7563
7565
  prepareChat: () => prepareChat,
7564
7566
  privateRoutes: () => privateRoutes,
@@ -7845,6 +7847,52 @@ function loadKnowledge(root = "config/knowledge") {
7845
7847
  return docs;
7846
7848
  }
7847
7849
 
7850
+ // src/core/messages.ts
7851
+ function isClientRole(role) {
7852
+ return role === "user" || role === "assistant";
7853
+ }
7854
+ function normalizeMessages(raw) {
7855
+ if (!Array.isArray(raw) || raw.length === 0) return null;
7856
+ const messages = [];
7857
+ for (const entry of raw) {
7858
+ if (!entry || typeof entry !== "object") return null;
7859
+ const { role, content } = entry;
7860
+ if (!isClientRole(role)) continue;
7861
+ let text = null;
7862
+ if (typeof content === "string") {
7863
+ text = content;
7864
+ } else if (Array.isArray(content)) {
7865
+ text = content.filter(
7866
+ (part) => !!part && typeof part === "object" && part.type === "text" && typeof part.text === "string"
7867
+ ).map((part) => part.text).join("");
7868
+ }
7869
+ if (text === null) continue;
7870
+ messages.push({ role, content: text });
7871
+ }
7872
+ return messages.length > 0 ? messages : null;
7873
+ }
7874
+ function normalizeChatBody(body) {
7875
+ const source = body && typeof body === "object" ? body : {};
7876
+ if (Array.isArray(source.messages)) {
7877
+ if (source.messages.length === 0) {
7878
+ return { ok: false, error: "messages array cannot be empty" };
7879
+ }
7880
+ const messages = normalizeMessages(source.messages);
7881
+ if (!messages) {
7882
+ return {
7883
+ ok: false,
7884
+ error: "messages must contain user/assistant messages with text content"
7885
+ };
7886
+ }
7887
+ return { ok: true, messages };
7888
+ }
7889
+ const { message } = source;
7890
+ if (message && typeof message !== "object") {
7891
+ return { ok: true, messages: [{ role: "user", content: String(message) }] };
7892
+ }
7893
+ return { ok: false, error: "either 'message' or 'messages' required" };
7894
+ }
7895
+
7848
7896
  // src/core/pipeline.ts
7849
7897
  var MODE_SETTINGS = {
7850
7898
  public: { topK: 6, label: "Context" },
@@ -8092,7 +8140,7 @@ var VectorStore = class _VectorStore {
8092
8140
  // src/core/session.ts
8093
8141
  var import_node_crypto2 = require("node:crypto");
8094
8142
  var sessions = /* @__PURE__ */ new Map();
8095
- setInterval(
8143
+ var sessionSweeper = setInterval(
8096
8144
  () => {
8097
8145
  const now = Date.now();
8098
8146
  for (const [key, data] of Array.from(sessions.entries())) {
@@ -8103,6 +8151,7 @@ setInterval(
8103
8151
  },
8104
8152
  5 * 60 * 1e3
8105
8153
  );
8154
+ sessionSweeper.unref?.();
8106
8155
  function createSession(options = {}) {
8107
8156
  const { maxRequests = 20, ttl = 3600, metadata } = options;
8108
8157
  const key = `session_${(0, import_node_crypto2.randomUUID)()}`;
@@ -32840,17 +32889,11 @@ function demoRoutes(deps) {
32840
32889
  app.post("/api/demo/chat", limitDemo(), async (c) => {
32841
32890
  try {
32842
32891
  const body = await c.req.json().catch(() => ({}));
32843
- let messages;
32844
- if (body?.messages && Array.isArray(body.messages)) {
32845
- messages = body.messages;
32846
- if (messages.length === 0) {
32847
- return c.json({ error: "messages array cannot be empty" }, 400);
32848
- }
32849
- } else if (body?.message) {
32850
- messages = [{ role: "user", content: String(body.message) }];
32851
- } else {
32852
- return c.json({ error: "either 'message' or 'messages' required" }, 400);
32892
+ const normalized = normalizeChatBody(body);
32893
+ if (!normalized.ok) {
32894
+ return c.json({ error: normalized.error }, 400);
32853
32895
  }
32896
+ const { messages } = normalized;
32854
32897
  const lastUserMsg = [...messages].reverse().find((m) => m.role === "user");
32855
32898
  if (!lastUserMsg) {
32856
32899
  return c.json({ error: "no user message found in conversation" }, 400);
@@ -32901,26 +32944,6 @@ ${ctx.join("\n\n")}`
32901
32944
  // src/routes/openai.ts
32902
32945
  var import_hono2 = require("hono");
32903
32946
  var import_streaming2 = require("hono/streaming");
32904
- function normalizeMessages(raw) {
32905
- if (!Array.isArray(raw) || raw.length === 0) return null;
32906
- const messages = [];
32907
- for (const entry of raw) {
32908
- if (!entry || typeof entry !== "object") return null;
32909
- const { role, content } = entry;
32910
- if (role !== "user" && role !== "assistant") continue;
32911
- let text = null;
32912
- if (typeof content === "string") {
32913
- text = content;
32914
- } else if (Array.isArray(content)) {
32915
- text = content.filter(
32916
- (part) => !!part && typeof part === "object" && part.type === "text" && typeof part.text === "string"
32917
- ).map((part) => part.text).join("");
32918
- }
32919
- if (text === null) continue;
32920
- messages.push({ role, content: text });
32921
- }
32922
- return messages.length > 0 ? messages : null;
32923
- }
32924
32947
  function errorJson(c, status, message) {
32925
32948
  return c.json(
32926
32949
  { error: { message, type: status === 401 ? "authentication_error" : "invalid_request_error" } },
@@ -33055,17 +33078,11 @@ function privateRoutes(deps) {
33055
33078
  app.use("/api/private/*", limitPrivate2());
33056
33079
  app.post("/api/private/chat", async (c) => {
33057
33080
  const body = await c.req.json().catch(() => ({}));
33058
- let messages;
33059
- if (body?.messages && Array.isArray(body.messages)) {
33060
- messages = body.messages;
33061
- if (messages.length === 0) {
33062
- return c.json({ error: "messages array cannot be empty" }, 400);
33063
- }
33064
- } else if (body?.message) {
33065
- messages = [{ role: "user", content: String(body.message) }];
33066
- } else {
33067
- return c.json({ error: "either 'message' or 'messages' required" }, 400);
33081
+ const normalized = normalizeChatBody(body);
33082
+ if (!normalized.ok) {
33083
+ return c.json({ error: normalized.error }, 400);
33068
33084
  }
33085
+ const { messages } = normalized;
33069
33086
  const buckets = await resolveBuckets({
33070
33087
  mode: "private",
33071
33088
  sender: jwtSubject(c),
@@ -33123,17 +33140,11 @@ function publicRoutes(deps) {
33123
33140
  app.use("/api/public/*", limitPublic2());
33124
33141
  app.post("/api/public/chat", async (c) => {
33125
33142
  const body = await c.req.json().catch(() => ({}));
33126
- let messages;
33127
- if (body?.messages && Array.isArray(body.messages)) {
33128
- messages = body.messages;
33129
- if (messages.length === 0) {
33130
- return c.json({ error: "messages array cannot be empty" }, 400);
33131
- }
33132
- } else if (body?.message) {
33133
- messages = [{ role: "user", content: String(body.message) }];
33134
- } else {
33135
- return c.json({ error: "either 'message' or 'messages' required" }, 400);
33143
+ const normalized = normalizeChatBody(body);
33144
+ if (!normalized.ok) {
33145
+ return c.json({ error: normalized.error }, 400);
33136
33146
  }
33147
+ const { messages } = normalized;
33137
33148
  const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor });
33138
33149
  let system;
33139
33150
  try {
@@ -33462,6 +33473,8 @@ function createShortener(config2, fetchImpl = fetch) {
33462
33473
  guardOutput,
33463
33474
  jwtSubject,
33464
33475
  loadKnowledge,
33476
+ normalizeChatBody,
33477
+ normalizeMessages,
33465
33478
  openaiRoutes,
33466
33479
  prepareChat,
33467
33480
  privateRoutes,
package/dist/index.mjs CHANGED
@@ -7807,6 +7807,52 @@ function loadKnowledge(root = "config/knowledge") {
7807
7807
  return docs;
7808
7808
  }
7809
7809
 
7810
+ // src/core/messages.ts
7811
+ function isClientRole(role) {
7812
+ return role === "user" || role === "assistant";
7813
+ }
7814
+ function normalizeMessages(raw) {
7815
+ if (!Array.isArray(raw) || raw.length === 0) return null;
7816
+ const messages = [];
7817
+ for (const entry of raw) {
7818
+ if (!entry || typeof entry !== "object") return null;
7819
+ const { role, content } = entry;
7820
+ if (!isClientRole(role)) continue;
7821
+ let text = null;
7822
+ if (typeof content === "string") {
7823
+ text = content;
7824
+ } else if (Array.isArray(content)) {
7825
+ text = content.filter(
7826
+ (part) => !!part && typeof part === "object" && part.type === "text" && typeof part.text === "string"
7827
+ ).map((part) => part.text).join("");
7828
+ }
7829
+ if (text === null) continue;
7830
+ messages.push({ role, content: text });
7831
+ }
7832
+ return messages.length > 0 ? messages : null;
7833
+ }
7834
+ function normalizeChatBody(body) {
7835
+ const source = body && typeof body === "object" ? body : {};
7836
+ if (Array.isArray(source.messages)) {
7837
+ if (source.messages.length === 0) {
7838
+ return { ok: false, error: "messages array cannot be empty" };
7839
+ }
7840
+ const messages = normalizeMessages(source.messages);
7841
+ if (!messages) {
7842
+ return {
7843
+ ok: false,
7844
+ error: "messages must contain user/assistant messages with text content"
7845
+ };
7846
+ }
7847
+ return { ok: true, messages };
7848
+ }
7849
+ const { message } = source;
7850
+ if (message && typeof message !== "object") {
7851
+ return { ok: true, messages: [{ role: "user", content: String(message) }] };
7852
+ }
7853
+ return { ok: false, error: "either 'message' or 'messages' required" };
7854
+ }
7855
+
7810
7856
  // src/core/pipeline.ts
7811
7857
  var MODE_SETTINGS = {
7812
7858
  public: { topK: 6, label: "Context" },
@@ -8054,7 +8100,7 @@ var VectorStore = class _VectorStore {
8054
8100
  // src/core/session.ts
8055
8101
  import { randomUUID as randomUUID2 } from "node:crypto";
8056
8102
  var sessions = /* @__PURE__ */ new Map();
8057
- setInterval(
8103
+ var sessionSweeper = setInterval(
8058
8104
  () => {
8059
8105
  const now = Date.now();
8060
8106
  for (const [key, data] of Array.from(sessions.entries())) {
@@ -8065,6 +8111,7 @@ setInterval(
8065
8111
  },
8066
8112
  5 * 60 * 1e3
8067
8113
  );
8114
+ sessionSweeper.unref?.();
8068
8115
  function createSession(options = {}) {
8069
8116
  const { maxRequests = 20, ttl = 3600, metadata } = options;
8070
8117
  const key = `session_${randomUUID2()}`;
@@ -32802,17 +32849,11 @@ function demoRoutes(deps) {
32802
32849
  app.post("/api/demo/chat", limitDemo(), async (c) => {
32803
32850
  try {
32804
32851
  const body = await c.req.json().catch(() => ({}));
32805
- let messages;
32806
- if (body?.messages && Array.isArray(body.messages)) {
32807
- messages = body.messages;
32808
- if (messages.length === 0) {
32809
- return c.json({ error: "messages array cannot be empty" }, 400);
32810
- }
32811
- } else if (body?.message) {
32812
- messages = [{ role: "user", content: String(body.message) }];
32813
- } else {
32814
- return c.json({ error: "either 'message' or 'messages' required" }, 400);
32852
+ const normalized = normalizeChatBody(body);
32853
+ if (!normalized.ok) {
32854
+ return c.json({ error: normalized.error }, 400);
32815
32855
  }
32856
+ const { messages } = normalized;
32816
32857
  const lastUserMsg = [...messages].reverse().find((m) => m.role === "user");
32817
32858
  if (!lastUserMsg) {
32818
32859
  return c.json({ error: "no user message found in conversation" }, 400);
@@ -32863,26 +32904,6 @@ ${ctx.join("\n\n")}`
32863
32904
  // src/routes/openai.ts
32864
32905
  import { Hono as Hono2 } from "hono";
32865
32906
  import { stream as stream2 } from "hono/streaming";
32866
- function normalizeMessages(raw) {
32867
- if (!Array.isArray(raw) || raw.length === 0) return null;
32868
- const messages = [];
32869
- for (const entry of raw) {
32870
- if (!entry || typeof entry !== "object") return null;
32871
- const { role, content } = entry;
32872
- if (role !== "user" && role !== "assistant") continue;
32873
- let text = null;
32874
- if (typeof content === "string") {
32875
- text = content;
32876
- } else if (Array.isArray(content)) {
32877
- text = content.filter(
32878
- (part) => !!part && typeof part === "object" && part.type === "text" && typeof part.text === "string"
32879
- ).map((part) => part.text).join("");
32880
- }
32881
- if (text === null) continue;
32882
- messages.push({ role, content: text });
32883
- }
32884
- return messages.length > 0 ? messages : null;
32885
- }
32886
32907
  function errorJson(c, status, message) {
32887
32908
  return c.json(
32888
32909
  { error: { message, type: status === 401 ? "authentication_error" : "invalid_request_error" } },
@@ -33017,17 +33038,11 @@ function privateRoutes(deps) {
33017
33038
  app.use("/api/private/*", limitPrivate2());
33018
33039
  app.post("/api/private/chat", async (c) => {
33019
33040
  const body = await c.req.json().catch(() => ({}));
33020
- let messages;
33021
- if (body?.messages && Array.isArray(body.messages)) {
33022
- messages = body.messages;
33023
- if (messages.length === 0) {
33024
- return c.json({ error: "messages array cannot be empty" }, 400);
33025
- }
33026
- } else if (body?.message) {
33027
- messages = [{ role: "user", content: String(body.message) }];
33028
- } else {
33029
- return c.json({ error: "either 'message' or 'messages' required" }, 400);
33041
+ const normalized = normalizeChatBody(body);
33042
+ if (!normalized.ok) {
33043
+ return c.json({ error: normalized.error }, 400);
33030
33044
  }
33045
+ const { messages } = normalized;
33031
33046
  const buckets = await resolveBuckets({
33032
33047
  mode: "private",
33033
33048
  sender: jwtSubject(c),
@@ -33085,17 +33100,11 @@ function publicRoutes(deps) {
33085
33100
  app.use("/api/public/*", limitPublic2());
33086
33101
  app.post("/api/public/chat", async (c) => {
33087
33102
  const body = await c.req.json().catch(() => ({}));
33088
- let messages;
33089
- if (body?.messages && Array.isArray(body.messages)) {
33090
- messages = body.messages;
33091
- if (messages.length === 0) {
33092
- return c.json({ error: "messages array cannot be empty" }, 400);
33093
- }
33094
- } else if (body?.message) {
33095
- messages = [{ role: "user", content: String(body.message) }];
33096
- } else {
33097
- return c.json({ error: "either 'message' or 'messages' required" }, 400);
33103
+ const normalized = normalizeChatBody(body);
33104
+ if (!normalized.ok) {
33105
+ return c.json({ error: normalized.error }, 400);
33098
33106
  }
33107
+ const { messages } = normalized;
33099
33108
  const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor });
33100
33109
  let system;
33101
33110
  try {
@@ -33425,6 +33434,8 @@ export {
33425
33434
  guardOutput,
33426
33435
  jwtSubject,
33427
33436
  loadKnowledge,
33437
+ normalizeChatBody,
33438
+ normalizeMessages,
33428
33439
  openaiRoutes,
33429
33440
  prepareChat,
33430
33441
  privateRoutes,
@@ -1 +1 @@
1
- {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsHnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EAqHlD"}
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsHnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EA+GlD"}
@@ -22,13 +22,6 @@
22
22
  * Bearer` or `x-api-key`; widget-only session/demo keys are not valid.
23
23
  */
24
24
  import { Hono } from "hono";
25
- import { type PipelineMessage } from "../core/pipeline";
26
25
  import type { ServerDependencies } from "../types";
27
- /**
28
- * Normalize OpenAI-format messages to the pipeline format.
29
- * Accepts string content and text content-part arrays; drops system/tool
30
- * messages. Returns null when nothing usable remains.
31
- */
32
- export declare function normalizeMessages(raw: unknown): PipelineMessage[] | null;
33
26
  export declare function openaiRoutes(deps: ServerDependencies): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
34
27
  //# sourceMappingURL=openai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/routes/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,EAAE,KAAK,eAAe,EAAkC,MAAM,kBAAkB,CAAC;AAGxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,EAAE,GAAG,IAAI,CA8BxE;AASD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAwIpD"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/routes/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAwIpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EAoErD"}
1
+ {"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EA4DrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EA0EpD"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAkEpD"}