@chatcops/server 0.5.0 → 0.6.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 (71) hide show
  1. package/README.md +4 -4
  2. package/dist/adapters/ai-sdk.d.ts +12 -0
  3. package/dist/adapters/ai-sdk.d.ts.map +1 -0
  4. package/dist/adapters/ai-sdk.js +27 -0
  5. package/dist/adapters/ai-sdk.js.map +1 -0
  6. package/dist/adapters/cloudflare.d.ts.map +1 -1
  7. package/dist/adapters/cloudflare.js +9 -83
  8. package/dist/adapters/cloudflare.js.map +1 -1
  9. package/dist/adapters/express.d.ts +6 -2
  10. package/dist/adapters/express.d.ts.map +1 -1
  11. package/dist/adapters/express.js +101 -30
  12. package/dist/adapters/express.js.map +1 -1
  13. package/dist/adapters/index.d.ts +1 -0
  14. package/dist/adapters/index.d.ts.map +1 -1
  15. package/dist/adapters/index.js +1 -0
  16. package/dist/adapters/index.js.map +1 -1
  17. package/dist/adapters/vercel.d.ts.map +1 -1
  18. package/dist/adapters/vercel.js +7 -74
  19. package/dist/adapters/vercel.js.map +1 -1
  20. package/dist/client-ip.d.ts +36 -0
  21. package/dist/client-ip.d.ts.map +1 -0
  22. package/dist/client-ip.js +62 -0
  23. package/dist/client-ip.js.map +1 -0
  24. package/dist/config.d.ts +110 -8
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +5 -1
  27. package/dist/config.js.map +1 -1
  28. package/dist/handler.d.ts +50 -1
  29. package/dist/handler.d.ts.map +1 -1
  30. package/dist/handler.js +384 -130
  31. package/dist/handler.js.map +1 -1
  32. package/dist/http.d.ts +66 -0
  33. package/dist/http.d.ts.map +1 -0
  34. package/dist/http.js +262 -0
  35. package/dist/http.js.map +1 -0
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/rate-limit.d.ts +5 -0
  41. package/dist/rate-limit.d.ts.map +1 -1
  42. package/dist/rate-limit.js +5 -0
  43. package/dist/rate-limit.js.map +1 -1
  44. package/dist/security/origin-policy.d.ts +19 -0
  45. package/dist/security/origin-policy.d.ts.map +1 -0
  46. package/dist/security/origin-policy.js +58 -0
  47. package/dist/security/origin-policy.js.map +1 -0
  48. package/dist/security/origin.d.ts +5 -0
  49. package/dist/security/origin.d.ts.map +1 -0
  50. package/dist/security/origin.js +47 -0
  51. package/dist/security/origin.js.map +1 -0
  52. package/dist/security/session-token.d.ts +65 -0
  53. package/dist/security/session-token.d.ts.map +1 -0
  54. package/dist/security/session-token.js +338 -0
  55. package/dist/security/session-token.js.map +1 -0
  56. package/dist/security/sessions.d.ts +49 -0
  57. package/dist/security/sessions.d.ts.map +1 -0
  58. package/dist/security/sessions.js +159 -0
  59. package/dist/security/sessions.js.map +1 -0
  60. package/dist/security/startup-checks.d.ts +44 -0
  61. package/dist/security/startup-checks.d.ts.map +1 -0
  62. package/dist/security/startup-checks.js +134 -0
  63. package/dist/security/startup-checks.js.map +1 -0
  64. package/dist/security/turnstile.d.ts +24 -0
  65. package/dist/security/turnstile.d.ts.map +1 -0
  66. package/dist/security/turnstile.js +93 -0
  67. package/dist/security/turnstile.js.map +1 -0
  68. package/dist/visitor-context.d.ts.map +1 -1
  69. package/dist/visitor-context.js +1 -0
  70. package/dist/visitor-context.js.map +1 -1
  71. package/package.json +22 -5
package/dist/handler.js CHANGED
@@ -1,49 +1,187 @@
1
- import { createProvider, ConversationManager, AnalyticsCollector, toolToDefinition, } from '@chatcops/core';
1
+ import { createProvider, isAIProvider, ConversationManager, AnalyticsCollector, BufferedEventSink, statsFromSink, createBudgetGuard, withDefaultBudgets, createRateLimiter, memoryStorage, describeInvalidRequest, errorBody, partsOf, PROTOCOL_VERSION, runTurn, statusForError, toLegacyChunk, toolRegistry, toolToDefinition, validateTools, } from '@chatcops/core';
2
2
  import { chatRequestSchema } from './config.js';
3
+ import { allowedOriginsOf } from './security/origin-policy.js';
4
+ import { DEFAULT_SESSION_TTL_SEC, createSessions } from './security/sessions.js';
5
+ import { logSecurityAtStartup } from './security/startup-checks.js';
3
6
  import { VISITOR_CONTEXT_INSTRUCTION, buildVisitorContext, isLocaleTag, withVisitorContext } from './visitor-context.js';
4
- import { RateLimiter } from './rate-limit.js';
5
7
  import { WebhookDispatcher } from './webhook.js';
6
8
  export function createChatHandler(config) {
7
9
  if (config.i18n) {
8
10
  console.warn('[chatcops] The `i18n` option is deprecated and ignored. Set the widget text with its `strings` option.');
9
11
  }
10
- const providerPromise = createProvider(config.provider);
11
- const conversations = new ConversationManager({ store: config.conversationStore });
12
- const rateLimiter = config.rateLimit ? new RateLimiter(config.rateLimit) : new RateLimiter();
13
- const analytics = config.analytics ? new AnalyticsCollector() : null;
12
+ const providerPromise = isAIProvider(config.provider)
13
+ ? Promise.resolve(config.provider)
14
+ : createProvider(config.provider);
15
+ // A failed setup (unknown provider type, SDK that throws on a missing key)
16
+ // is logged once here and reported to visitors per request below. Without
17
+ // this handler it would be an unhandled rejection and stop the process.
18
+ // Only the message is logged: SDK errors can carry the config or headers.
19
+ providerPromise.catch((err) => {
20
+ console.error('[chatcops] Provider setup failed:', err instanceof Error ? err.message : String(err));
21
+ });
22
+ if (config.storage && config.conversationStore) {
23
+ throw new Error('Set `storage` or `conversationStore`, not both. `storage.conversations` replaces `conversationStore`.');
24
+ }
25
+ if (!config.storage && !config.conversationStore && onServerless() && !warnedMemoryStorage) {
26
+ warnedMemoryStorage = true;
27
+ console.warn('[chatcops] No `storage` is set, so conversations are kept in memory. On serverless each instance has its own memory, so a conversation can lose its history between messages. Use a store package such as @chatcops/store-postgres or @chatcops/store-redis.');
28
+ }
29
+ const storage = config.storage ?? (config.conversationStore ? { conversations: config.conversationStore } : undefined);
30
+ const conversations = new ConversationManager(storage ? { storage } : {});
31
+ // Counted in the storage's counters when it has them, so limits and
32
+ // budgets hold across every server instance; otherwise in this process.
33
+ // Nothing runs on a timer, which Workers don't allow at global scope.
34
+ const counters = (storage?.counters ?? memoryStorage().counters);
35
+ const budgets = withDefaultBudgets(config.budgets);
36
+ const budgetGuard = budgets ? createBudgetGuard(counters, budgets.budgets) : undefined;
37
+ if (budgets && !loggedBudgets) {
38
+ loggedBudgets = true;
39
+ console.info(describeBudgets(budgets.budgets, budgets.defaulted));
40
+ }
41
+ const rateLimit = { maxRequests: 30, windowMs: 60_000, ...config.rateLimit };
42
+ if (rateLimit.maxRequests <= 0)
43
+ throw new Error('maxRequests must be greater than 0');
44
+ const rateLimiter = createRateLimiter(counters, {
45
+ limit: rateLimit.maxRequests,
46
+ windowMs: rateLimit.windowMs,
47
+ });
48
+ // Events always count in this process, and go to the storage's event sink
49
+ // too when it has one, so stats can cover every instance.
50
+ const collector = config.analytics ? new AnalyticsCollector() : null;
51
+ const eventSink = config.analytics ? storage?.events : undefined;
52
+ const bufferedEvents = eventSink ? new BufferedEventSink(eventSink) : undefined;
53
+ const analytics = collector
54
+ ? {
55
+ track(type, data) {
56
+ collector.track(type, data);
57
+ bufferedEvents?.track(type, data);
58
+ },
59
+ }
60
+ : null;
14
61
  const webhooks = config.webhooks?.length ? new WebhookDispatcher(config.webhooks) : null;
15
62
  const toolDefs = config.tools?.map(toolToDefinition) ?? [];
16
- const toolsByName = new Map((config.tools ?? []).map((tool) => [tool.name, tool]));
17
- // Periodic cleanup
18
- const cleanupInterval = setInterval(() => rateLimiter.cleanup(), 60_000);
63
+ // A broken tool definition is a code mistake, so fail here, at startup,
64
+ // rather than as a provider error on the first message.
65
+ validateTools(toolDefs);
66
+ const tools = toolRegistry(config.tools);
67
+ const sessions = createSessions(config, async (id) => (await conversations.getMessages(id)).length === 0);
68
+ if (!loggedSecurity) {
69
+ loggedSecurity = true;
70
+ logSecurityAtStartup({
71
+ allowedOrigins: allowedOriginsOf(config),
72
+ sessionSecrets: config.sessionSecrets,
73
+ sessionTtlSec: sessions ? (config.sessionTtlSec ?? DEFAULT_SESSION_TTL_SEC) : undefined,
74
+ requireSession: sessions?.required,
75
+ turnstile: Boolean(config.turnstile),
76
+ });
77
+ }
78
+ const requests = { v1: 0, legacy: 0, 'ai-sdk': 0 };
19
79
  /**
20
- * Streams one reply. Pass `options.signal` to stop when the visitor goes
21
- * away: the provider request is cancelled, nothing more is yielded, and the
22
- * partial reply isn't saved.
80
+ * Starts one reply. Resolves a refusal for a request that can't be
81
+ * answered (protocol v1 sends it as an HTTP status before any stream), or
82
+ * the reply as protocol v1 parts. The conversation stays locked until the
83
+ * parts are read to the end or `return()` is called on them.
23
84
  */
24
- async function* handleChat(body, clientIp, options = {}) {
25
- const { signal } = options;
26
- const provider = await providerPromise;
27
- // Validate request
85
+ async function startChat(body, clientIp, options = {}) {
86
+ const format = options.format ?? 'v1';
87
+ requests[format] += 1;
88
+ if (format === 'legacy' && !loggedLegacyFormat) {
89
+ loggedLegacyFormat = true;
90
+ console.info('[chatcops] Answered a request in the 0.5 stream format, from a widget older than 0.6 or a client that doesn\'t send `protocol: 1`. That format keeps working until 1.0.');
91
+ }
28
92
  const parsed = chatRequestSchema.safeParse(body);
29
93
  if (!parsed.success) {
30
- yield JSON.stringify({ error: 'Invalid request', details: parsed.error.flatten() });
31
- return;
94
+ return refuse('invalid_request', { message: describeInvalidRequest(parsed.error) }, { error: 'Invalid request', details: parsed.error.flatten() });
32
95
  }
33
96
  const req = parsed.data;
34
- // Rate limit
97
+ if (sessions) {
98
+ const session = await sessions.check(options.authorization, options.origin ?? null, req.conversationId);
99
+ if (!session.ok)
100
+ return refuse(session.code, { message: session.message }, { error: 'provider_error' });
101
+ }
35
102
  if (clientIp) {
36
- const limit = rateLimiter.check(clientIp);
103
+ const limit = await rateLimiter.check(clientIp);
37
104
  if (!limit.allowed) {
38
- yield JSON.stringify({ error: 'rate_limit', retryAfter: limit.retryAfter });
39
- return;
105
+ const retryAfterMs = limit.retryAfterMs ?? 1000;
106
+ // 0.5 widgets read seconds.
107
+ return refuse('rate_limited', { retryAfterMs }, { error: 'rate_limit', retryAfter: Math.ceil(retryAfterMs / 1000) });
108
+ }
109
+ }
110
+ let provider;
111
+ try {
112
+ provider = await providerPromise;
113
+ }
114
+ catch {
115
+ // Already logged where the provider was created.
116
+ return refuse('provider_unavailable', {}, { error: 'provider_error' });
117
+ }
118
+ // One reply per conversation at a time: a second request while a reply
119
+ // is being written would otherwise answer the same history twice.
120
+ const release = await conversations.acquireTurn(req.conversationId);
121
+ if (!release) {
122
+ return refuse('conversation_busy', {}, { error: 'provider_error' });
123
+ }
124
+ return { ok: true, parts: replyParts(provider, req, options.signal, clientIp, release) };
125
+ }
126
+ async function* replyParts(provider, req, signal, clientIp, release) {
127
+ const pendingWebhooks = new Set();
128
+ try {
129
+ for await (const part of reply(provider, req, signal, pendingWebhooks, clientIp)) {
130
+ // Tells the widget to get a session before its next request.
131
+ yield part.type === 'start' && sessions ? { ...part, capabilities: { ...part.capabilities, session: true } } : part;
40
132
  }
41
133
  }
42
- // Get or create conversation
43
- await conversations.getOrCreate(req.conversationId);
44
- const conversationMessages = await conversations.getMessages(req.conversationId);
134
+ finally {
135
+ await release();
136
+ }
137
+ // Keeping the stream open until lead webhooks and analytics writes
138
+ // finish keeps serverless runtimes from cutting them off once the
139
+ // response ends. A failed analytics write is logged, never thrown.
140
+ await awaitPendingWebhooks(pendingWebhooks);
141
+ await bufferedEvents?.flush();
142
+ }
143
+ /**
144
+ * Analytics stats for `range` (default: the last 30 days), counted in the
145
+ * storage's event sink when it can be queried, so they cover every
146
+ * instance. Otherwise they come from this process only, as
147
+ * `getAnalytics()` does. `null` when `analytics` is off.
148
+ */
149
+ async function analyticsStats(range) {
150
+ if (!collector)
151
+ return null;
152
+ if (!bufferedEvents || !eventSink?.query)
153
+ return collector.getStats();
154
+ await bufferedEvents.flush();
155
+ const to = range?.to ?? Date.now() + 1;
156
+ return statsFromSink(eventSink, { from: range?.from ?? to - 30 * DAY_MS, to });
157
+ }
158
+ /**
159
+ * Streams one reply in the 0.5 format, as JSON strings. Pass
160
+ * `options.signal` to stop when the visitor goes away: the provider request
161
+ * is cancelled and nothing more is yielded.
162
+ */
163
+ async function* handleChat(body, clientIp, options = {}) {
164
+ const start = await startChat(body, clientIp, { ...options, format: 'legacy' });
165
+ if (!start.ok) {
166
+ yield JSON.stringify(start.legacy);
167
+ return;
168
+ }
169
+ yield* toLegacyStream(start.parts);
170
+ }
171
+ async function* reply(provider, req, signal, pendingWebhooks, clientIp) {
172
+ const conversation = await conversations.getOrCreate(req.conversationId);
173
+ const conversationMessages = conversation.messages;
174
+ // Pre-chat answers are kept from the first message on, so the widget
175
+ // doesn't have to send them again and they can't change mid-conversation.
176
+ const storedVisitor = conversation.metadata?.visitor;
177
+ const newVisitor = storedVisitor ? undefined : allowedUserData(req.userData, config.preChatFields);
178
+ const userData = storedVisitor ?? newVisitor;
45
179
  let assistantToReplace;
46
- if (req.regenerate) {
180
+ if (typeof req.regenerate === 'object') {
181
+ const id = req.regenerate.assistantMessageId;
182
+ assistantToReplace = conversationMessages.find((message) => message.id === id && message.role === 'assistant');
183
+ }
184
+ if (req.regenerate && !assistantToReplace) {
47
185
  const userIndex = req.messageId
48
186
  ? conversationMessages.findIndex((message) => message.id === req.messageId)
49
187
  : findLastIndex(conversationMessages, (message) => message.role === 'user');
@@ -54,6 +192,20 @@ export function createChatHandler(config) {
54
192
  assistantToReplace = [...conversationMessages].reverse().find((message) => message.role === 'assistant');
55
193
  }
56
194
  }
195
+ // A retry of a message that already has a finished reply (the network
196
+ // dropped after the server saved it) gets that reply again instead of a
197
+ // second one. A partial reply is replaced once the new one succeeds.
198
+ if (!req.regenerate && req.messageId) {
199
+ const index = conversationMessages.findIndex((message) => message.id === req.messageId && message.role === 'user');
200
+ const answer = index === -1 ? undefined : conversationMessages[index + 1];
201
+ if (answer?.role === 'assistant') {
202
+ if (answer.status === undefined || answer.status === 'complete') {
203
+ yield* replay(answer, req.conversationId);
204
+ return;
205
+ }
206
+ assistantToReplace = answer;
207
+ }
208
+ }
57
209
  // Track analytics
58
210
  if (analytics && conversationMessages.length === 0) {
59
211
  analytics.track('conversation:started', { conversationId: req.conversationId });
@@ -76,134 +228,236 @@ export function createChatHandler(config) {
76
228
  content: req.message,
77
229
  timestamp: Date.now(),
78
230
  };
79
- await conversations.addMessage(req.conversationId, userMessage);
231
+ await conversations.appendMessages(req.conversationId, [userMessage], newVisitor ? { metadata: { visitor: newVisitor } } : undefined);
80
232
  }
81
- // Build system prompt
82
- let systemPrompt = config.systemPrompt;
83
- // Add knowledge context
233
+ // The system prompt is the operator's text and nothing else, so it's the
234
+ // same on every request and providers can cache it. Everything that
235
+ // changes per request goes in the context after it.
236
+ const context = [];
84
237
  if (config.knowledge?.length) {
85
238
  const contexts = await Promise.all(config.knowledge.map((k) => k.getContext(req.message)));
86
239
  const combined = contexts.filter(Boolean).join('\n\n');
87
- if (combined) {
88
- systemPrompt += '\n\n' + combined;
89
- }
240
+ if (combined)
241
+ context.push(combined);
90
242
  }
91
243
  // Visitor-supplied page context and pre-chat answers never go into the
92
244
  // system prompt; see visitor-context.ts.
93
- const visitorContext = buildVisitorContext(req);
94
- if (visitorContext) {
95
- systemPrompt += `\n\n${VISITOR_CONTEXT_INSTRUCTION}`;
96
- }
245
+ const visitorContext = buildVisitorContext({ pageContext: req.pageContext, userData });
246
+ if (visitorContext)
247
+ context.push(VISITOR_CONTEXT_INSTRUCTION);
97
248
  if (req.locale && isLocaleTag(req.locale)) {
98
- systemPrompt += `\n\nReply in the visitor's language. Their browser locale is ${req.locale}.`;
249
+ context.push(`Reply in the visitor's language. Their browser locale is ${req.locale}.`);
99
250
  }
100
- // Get conversation messages for context
101
- const storedMessages = await conversations.getMessages(req.conversationId);
251
+ // The history the model sees, trimmed to the token budget
252
+ const storedMessages = await conversations.getHistory(req.conversationId);
102
253
  const messages = withVisitorContext(assistantToReplace
103
254
  ? storedMessages.filter((message) => message.id !== assistantToReplace.id)
104
255
  : storedMessages, visitorContext);
105
- // Stream response
106
- let fullResponse = '';
107
- const pendingEvents = [];
108
- const pendingWebhooks = new Set();
109
- try {
110
- for await (const chunk of provider.chat({
111
- messages,
112
- systemPrompt,
113
- tools: toolDefs.length > 0 ? toolDefs : undefined,
114
- toolTimeoutMs: config.toolTimeoutMs,
115
- maxTokens: config.maxTokens,
116
- temperature: config.temperature,
117
- signal,
118
- toolExecutor: async (toolCall) => {
119
- const tool = toolsByName.get(toolCall.name);
120
- if (!tool) {
121
- return {
122
- success: false,
123
- message: `Unknown tool: ${toolCall.name}`,
124
- };
125
- }
126
- const result = await tool.execute(toolCall.input);
127
- if (tool.name === 'capture_lead' && result.success) {
128
- analytics?.track('lead:captured', { conversationId: req.conversationId });
129
- pendingEvents.push(JSON.stringify({
130
- leadCaptured: true,
131
- leadData: result.data,
132
- }));
133
- if (webhooks) {
134
- const delivery = webhooks
135
- .dispatch('lead:captured', {
136
- lead: result.data,
137
- conversationId: req.conversationId,
138
- })
139
- .catch((err) => {
140
- console.error('[chatcops] Webhook delivery failed:', err);
141
- })
142
- .finally(() => {
143
- pendingWebhooks.delete(delivery);
144
- });
145
- pendingWebhooks.add(delivery);
146
- }
147
- }
148
- return result;
149
- },
150
- })) {
151
- if (signal?.aborted)
152
- break;
153
- while (pendingEvents.length > 0) {
154
- yield pendingEvents.shift();
256
+ // The reply is saved as it grows: appended after the first tool round,
257
+ // updated after each one. A reply that fails before anything was saved
258
+ // isn't saved at all, so a failed regenerate keeps the old answer.
259
+ let saved = false;
260
+ const turn = runTurn({
261
+ provider,
262
+ messages,
263
+ systemPrompt: config.systemPrompt,
264
+ ...(context.length ? { systemContext: context.join('\n\n') } : {}),
265
+ tools,
266
+ conversationId: req.conversationId,
267
+ toolTimeoutMs: config.toolTimeoutMs,
268
+ maxTokens: config.maxTokens,
269
+ temperature: config.temperature,
270
+ exposeUsage: config.exposeUsage,
271
+ signal,
272
+ ...(budgetGuard
273
+ ? { budget: { guard: budgetGuard, context: { conversationId: req.conversationId, ...(clientIp ? { ip: clientIp } : {}) } } }
274
+ : {}),
275
+ onPart: (part) => {
276
+ if (part.type !== 'lead-captured')
277
+ return;
278
+ analytics?.track('lead:captured', { conversationId: req.conversationId });
279
+ if (!webhooks)
280
+ return;
281
+ const delivery = webhooks
282
+ .dispatch('lead:captured', { lead: part.lead, conversationId: req.conversationId })
283
+ .catch((err) => {
284
+ console.error('[chatcops] Webhook delivery failed:', err);
285
+ })
286
+ .finally(() => {
287
+ pendingWebhooks.delete(delivery);
288
+ });
289
+ pendingWebhooks.add(delivery);
290
+ },
291
+ onPersist: async (message, { final }) => {
292
+ const complete = message.status === 'complete';
293
+ if (!saved) {
294
+ if (final && !message.content && !message.parts?.length)
295
+ return;
296
+ // A reply the visitor walked away from is kept, marked `aborted`,
297
+ // so the conversation shows what they saw (the model doesn't see
298
+ // it). When regenerating, the old answer stands instead. A reply
299
+ // that failed isn't kept.
300
+ if (final && !complete && (message.status !== 'aborted' || assistantToReplace))
301
+ return;
302
+ await conversations.appendMessages(req.conversationId, [message]);
303
+ saved = true;
155
304
  }
156
- fullResponse += chunk;
157
- yield JSON.stringify({ content: chunk });
158
- }
159
- while (pendingEvents.length > 0) {
160
- yield pendingEvents.shift();
161
- }
305
+ else {
306
+ await conversations.updateMessage(req.conversationId, message);
307
+ }
308
+ if (final && complete) {
309
+ if (assistantToReplace)
310
+ await conversations.removeMessage(req.conversationId, assistantToReplace.id);
311
+ if (message.content)
312
+ analytics?.track('message:received', { conversationId: req.conversationId });
313
+ }
314
+ },
315
+ });
316
+ let failure;
317
+ let next = await turn.next();
318
+ while (!next.done) {
319
+ const part = next.value;
320
+ if (part.type === 'error')
321
+ failure = part;
322
+ yield part;
323
+ next = await turn.next();
162
324
  }
163
- catch (err) {
164
- if (signal?.aborted) {
165
- // The visitor left. Let lead webhooks finish, but write nothing else.
166
- await awaitPendingWebhooks(pendingWebhooks);
167
- return;
325
+ const result = next.value;
326
+ if (failure && result.status !== 'aborted') {
327
+ if (failure.code === 'budget_exceeded') {
328
+ console.warn(`[chatcops] The ${failure.scope ?? ''} budget is used up, so a reply was refused.`);
168
329
  }
169
- console.error('[chatcops] Provider error:', err);
170
- await awaitPendingWebhooks(pendingWebhooks);
171
- yield JSON.stringify({ error: 'provider_error' });
172
- return;
173
- }
174
- if (signal?.aborted) {
175
- await awaitPendingWebhooks(pendingWebhooks);
176
- return;
177
- }
178
- // Save assistant message
179
- if (fullResponse) {
180
- const assistantMessage = {
181
- id: crypto.randomUUID(),
182
- role: 'assistant',
183
- content: fullResponse,
184
- timestamp: Date.now(),
185
- };
186
- await conversations.addMessage(req.conversationId, assistantMessage);
187
- if (assistantToReplace) {
188
- await conversations.removeMessage(req.conversationId, assistantToReplace.id);
330
+ else {
331
+ console.error('[chatcops] Provider error:', result.error);
189
332
  }
190
- analytics?.track('message:received', { conversationId: req.conversationId });
191
333
  }
192
- // The reply is finished for the visitor, so say so first. Keeping the generator
193
- // open until lead webhooks finish keeps serverless runtimes from cutting
194
- // them off once the response ends.
195
- yield JSON.stringify({ done: true });
196
- await awaitPendingWebhooks(pendingWebhooks);
334
+ // The visitor left, or the reply failed: let lead webhooks finish before
335
+ // the stream ends.
336
+ if (failure || result.status === 'aborted')
337
+ await awaitPendingWebhooks(pendingWebhooks);
197
338
  }
198
- function cleanup() {
199
- clearInterval(cleanupInterval);
339
+ /**
340
+ * Deletes conversations last updated more than `retention.conversationsDays`
341
+ * (default 30) days ago. Resolves how many, or `null` when the store can't
342
+ * purge.
343
+ */
344
+ async function purge(now = Date.now()) {
345
+ const store = storage?.conversations;
346
+ if (!store?.purge)
347
+ return null;
348
+ const days = config.retention?.conversationsDays ?? 30;
349
+ return store.purge(now - days * DAY_MS);
200
350
  }
351
+ /** Kept for compatibility: the handler no longer holds timers, so there's nothing to clean up. */
352
+ function cleanup() { }
201
353
  return {
202
354
  handleChat,
203
- getAnalytics: () => analytics?.getStats() ?? null,
355
+ startChat,
356
+ purge,
357
+ /** How many requests asked for each stream format, to tell when 0.5 widgets are gone. */
358
+ /** Answers `POST /session`, or `undefined` when session tokens are off. */
359
+ startSession: sessions
360
+ ? (body, origin, clientIp) => sessions.mint(body, origin, clientIp)
361
+ : undefined,
362
+ protocolStats: () => ({ ...requests }),
363
+ /** Stats from this process only. `analyticsStats()` reads the storage's event sink. */
364
+ getAnalytics: () => collector?.getStats() ?? null,
365
+ analyticsStats,
204
366
  cleanup,
205
367
  };
206
368
  }
369
+ function refuse(code, options, legacy) {
370
+ return { ok: false, status: statusForError(code), error: errorBody(code, options).error, legacy };
371
+ }
372
+ /**
373
+ * Protocol v1 parts as 0.5 chunks (JSON strings). An error goes out last,
374
+ * after the turn has ended and lead webhooks have finished, as in 0.5.
375
+ */
376
+ export async function* toLegacyStream(parts) {
377
+ let failure = null;
378
+ let aborted = false;
379
+ for await (const part of parts) {
380
+ if (part.type === 'error') {
381
+ failure = toLegacyChunk(part);
382
+ continue;
383
+ }
384
+ if (part.type === 'finish' && part.reason === 'aborted')
385
+ aborted = true;
386
+ const chunk = toLegacyChunk(part);
387
+ if (chunk)
388
+ yield JSON.stringify(chunk);
389
+ }
390
+ // Nobody is listening after an abort.
391
+ if (failure && !aborted)
392
+ yield JSON.stringify(failure);
393
+ }
394
+ /** A saved reply, sent again: the request was a retry of an answered message. */
395
+ function* replay(message, conversationId) {
396
+ yield { type: 'start', protocol: PROTOCOL_VERSION, conversationId, messageId: message.id };
397
+ let texts = 0;
398
+ for (const part of partsOf(message)) {
399
+ if (part.type === 'text' && part.text) {
400
+ const id = `t${++texts}`;
401
+ yield { type: 'text-start', id };
402
+ yield { type: 'text-delta', id, delta: part.text };
403
+ yield { type: 'text-end', id };
404
+ }
405
+ else if (part.type === 'source') {
406
+ const { sourceId, url, title, snippet } = part;
407
+ yield { type: 'source', sourceId, url, ...(title ? { title } : {}), ...(snippet ? { snippet } : {}) };
408
+ }
409
+ else if (part.type === 'lead-captured') {
410
+ yield { type: 'lead-captured', lead: part.lead };
411
+ }
412
+ }
413
+ yield { type: 'finish', reason: 'stop' };
414
+ }
415
+ /** The pre-chat answers to keep: all of them, or only the configured fields. */
416
+ function allowedUserData(userData, fields) {
417
+ if (!userData)
418
+ return undefined;
419
+ const kept = fields ? Object.fromEntries(Object.entries(userData).filter(([key]) => fields.includes(key))) : userData;
420
+ return Object.keys(kept).length ? kept : undefined;
421
+ }
422
+ const DAY_MS = 24 * 60 * 60 * 1000;
423
+ /** Once per process (per isolate on Workers), not once per handler. */
424
+ let warnedMemoryStorage = false;
425
+ let loggedBudgets = false;
426
+ let loggedSecurity = false;
427
+ let loggedLegacyFormat = false;
428
+ const SCOPE_LABELS = { conversation: 'per conversation', ip: 'per IP per day', global: 'per day in total' };
429
+ function amount(value, unit) {
430
+ const short = value >= 1_000_000 ? `${value / 1_000_000}M` : value >= 1_000 ? `${value / 1_000}k` : String(value);
431
+ return `${short} ${unit}`;
432
+ }
433
+ /** The startup line, so the limits in force are never a surprise. */
434
+ export function describeBudgets(budgets, defaulted = []) {
435
+ const scopes = [
436
+ ['conversation', budgets.perConversation],
437
+ ['ip', budgets.perIpPerDay],
438
+ ['global', budgets.globalPerDay],
439
+ ];
440
+ const parts = [];
441
+ for (const [scope, limit] of scopes) {
442
+ if (!limit)
443
+ continue;
444
+ const caps = [
445
+ ...(limit.tokens !== undefined ? [amount(limit.tokens, 'tokens')] : []),
446
+ ...(limit.messages !== undefined ? [amount(limit.messages, 'replies')] : []),
447
+ ...(limit.usd !== undefined ? [`$${limit.usd}`] : []),
448
+ ];
449
+ parts.push(`${caps.join(' and ')} ${SCOPE_LABELS[scope]}${defaulted.includes(scope) ? ' (default)' : ''}`);
450
+ }
451
+ const noTotal = budgets.globalPerDay ? '' : ' No daily total is set; `budgets.globalPerDay` caps your whole bill.';
452
+ return `[chatcops] Budgets: ${parts.join(', ')}.${noTotal} Set \`budgets\` to change them, or \`budgets: false\` to turn them off.`;
453
+ }
454
+ /** Vercel, AWS Lambda, Netlify and Cloudflare Workers, where memory doesn't last. */
455
+ function onServerless() {
456
+ const env = globalThis.process?.env ?? {};
457
+ if (env.VERCEL || env.AWS_LAMBDA_FUNCTION_NAME || env.NETLIFY || env.K_SERVICE)
458
+ return true;
459
+ return globalThis.navigator?.userAgent === 'Cloudflare-Workers';
460
+ }
207
461
  async function awaitPendingWebhooks(pendingWebhooks) {
208
462
  if (pendingWebhooks.size > 0) {
209
463
  await Promise.allSettled(Array.from(pendingWebhooks));
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}