@chatcops/server 0.6.0 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -19
- package/dist/adapters/ai-sdk.js +1 -1
- package/dist/adapters/ai-sdk.js.map +1 -1
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/express.d.ts.map +1 -1
- package/dist/adapters/express.js +6 -5
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/vercel.js +1 -1
- package/dist/adapters/vercel.js.map +1 -1
- package/dist/client-ip.d.ts +5 -4
- package/dist/client-ip.d.ts.map +1 -1
- package/dist/client-ip.js +9 -14
- package/dist/client-ip.js.map +1 -1
- package/dist/config.d.ts +33 -17
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -1
- package/dist/examples/cloudflare-worker.d.ts.map +1 -1
- package/dist/examples/cloudflare-worker.js +4 -2
- package/dist/examples/cloudflare-worker.js.map +1 -1
- package/dist/examples/express-server.js +3 -1
- package/dist/examples/express-server.js.map +1 -1
- package/dist/examples/vercel-api.d.ts.map +1 -1
- package/dist/examples/vercel-api.js +3 -1
- package/dist/examples/vercel-api.js.map +1 -1
- package/dist/handler.d.ts +2 -0
- package/dist/handler.d.ts.map +1 -1
- package/dist/handler.js +64 -37
- package/dist/handler.js.map +1 -1
- package/dist/http.d.ts +4 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +6 -6
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge.d.ts +18 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +32 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/removed-options.d.ts +7 -0
- package/dist/removed-options.d.ts.map +1 -0
- package/dist/removed-options.js +21 -0
- package/dist/removed-options.js.map +1 -0
- package/dist/security/origin-policy.d.ts +3 -5
- package/dist/security/origin-policy.d.ts.map +1 -1
- package/dist/security/origin-policy.js +6 -17
- package/dist/security/origin-policy.js.map +1 -1
- package/dist/security/sessions.d.ts +26 -3
- package/dist/security/sessions.d.ts.map +1 -1
- package/dist/security/sessions.js +69 -11
- package/dist/security/sessions.js.map +1 -1
- package/dist/security/startup-checks.d.ts +2 -1
- package/dist/security/startup-checks.d.ts.map +1 -1
- package/dist/security/startup-checks.js +6 -16
- package/dist/security/startup-checks.js.map +1 -1
- package/dist/visitor-context.d.ts.map +1 -1
- package/dist/visitor-context.js +6 -0
- package/dist/visitor-context.js.map +1 -1
- package/dist/webhook.d.ts +4 -10
- package/dist/webhook.d.ts.map +1 -1
- package/dist/webhook.js +6 -6
- package/dist/webhook.js.map +1 -1
- package/package.json +2 -2
- package/dist/rate-limit.d.ts +0 -20
- package/dist/rate-limit.d.ts.map +0 -1
- package/dist/rate-limit.js +0 -45
- package/dist/rate-limit.js.map +0 -1
package/README.md
CHANGED
|
@@ -19,13 +19,15 @@ import { chatcopsMiddleware } from '@chatcops/server';
|
|
|
19
19
|
const app = express();
|
|
20
20
|
app.use(express.json());
|
|
21
21
|
|
|
22
|
-
app.
|
|
22
|
+
// app.use, so /chat/session, where the widget gets its session token, reaches it too.
|
|
23
|
+
app.use('/chat', chatcopsMiddleware({
|
|
23
24
|
provider: {
|
|
24
25
|
type: 'claude',
|
|
25
26
|
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
26
27
|
},
|
|
27
28
|
systemPrompt: 'You are a helpful assistant for our website.',
|
|
28
29
|
allowedOrigins: ['*'],
|
|
30
|
+
sessionSecrets: [process.env.CHATCOPS_SESSION_SECRET], // openssl rand -base64 32
|
|
29
31
|
}));
|
|
30
32
|
|
|
31
33
|
app.listen(3001);
|
|
@@ -40,6 +42,7 @@ const handler = chatcopsVercelHandler({
|
|
|
40
42
|
provider: { type: 'openai', apiKey: process.env.OPENAI_API_KEY },
|
|
41
43
|
systemPrompt: 'You are a helpful assistant.',
|
|
42
44
|
allowedOrigins: ['*'],
|
|
45
|
+
sessionSecrets: [process.env.CHATCOPS_SESSION_SECRET],
|
|
43
46
|
});
|
|
44
47
|
|
|
45
48
|
export const POST = (req: Request) => handler(req);
|
|
@@ -47,6 +50,8 @@ export const OPTIONS = (req: Request) => handler(req);
|
|
|
47
50
|
export const config = { runtime: 'edge' };
|
|
48
51
|
```
|
|
49
52
|
|
|
53
|
+
Export the same handler from the `/session` route next to it (`app/api/chat/session/route.ts` for a chat at `/api/chat`), where the widget gets its session token.
|
|
54
|
+
|
|
50
55
|
### Cloudflare Workers
|
|
51
56
|
|
|
52
57
|
```typescript
|
|
@@ -58,6 +63,7 @@ function getHandler(env: Env) {
|
|
|
58
63
|
provider: { type: 'claude', apiKey: env.ANTHROPIC_API_KEY },
|
|
59
64
|
systemPrompt: 'You are a helpful assistant.',
|
|
60
65
|
allowedOrigins: ['*'],
|
|
66
|
+
sessionSecrets: [env.CHATCOPS_SESSION_SECRET],
|
|
61
67
|
});
|
|
62
68
|
return handler;
|
|
63
69
|
}
|
|
@@ -112,7 +118,10 @@ const handler = createChatHandler({
|
|
|
112
118
|
analytics: true,
|
|
113
119
|
|
|
114
120
|
// Conversation storage (optional, default: in-memory)
|
|
115
|
-
|
|
121
|
+
storage: { conversations: new RedisConversationStore(redisClient) },
|
|
122
|
+
|
|
123
|
+
// Session tokens: required unless allowAnonymous: true
|
|
124
|
+
sessionSecrets: [process.env.CHATCOPS_SESSION_SECRET],
|
|
116
125
|
|
|
117
126
|
// CORS origin (optional, default: '*')
|
|
118
127
|
allowedOrigins: ['*'],
|
|
@@ -206,29 +215,16 @@ Pass the store when initializing the handler:
|
|
|
206
215
|
const handler = createChatHandler({
|
|
207
216
|
provider: { type: 'claude', apiKey: process.env.ANTHROPIC_API_KEY },
|
|
208
217
|
systemPrompt: 'You are a helpful assistant.',
|
|
209
|
-
|
|
218
|
+
storage: { conversations: new RedisConversationStore(redisClient) },
|
|
219
|
+
allowAnonymous: true,
|
|
210
220
|
});
|
|
211
221
|
```
|
|
212
222
|
|
|
213
223
|
## Custom integrations
|
|
214
224
|
|
|
215
|
-
`
|
|
225
|
+
For a runtime with the Fetch API's `Request` and `Response` (Next.js, Hono, Bun, Deno, Workers), pass requests to `chatcopsVercelHandler(config)`: it's a plain `(Request) => Promise<Response>`. For Node's `req` and `res` (`node:http`, Fastify, Koa), turn the request into a `Request` and stream the `Response` back. The docs have the code: [Next.js, Hono, Bun and Deno](https://chat.codercops.com/server/fetch-runtimes/). Route both the chat path and `<chat path>/session` to it, since the widget gets its session token there.
|
|
216
226
|
|
|
217
|
-
|
|
218
|
-
const abort = new AbortController();
|
|
219
|
-
const stream = new ReadableStream({
|
|
220
|
-
async start(controller) {
|
|
221
|
-
for await (const chunk of handler.handleChat(body, clientIp, { signal: abort.signal })) {
|
|
222
|
-
if (abort.signal.aborted) break;
|
|
223
|
-
controller.enqueue(new TextEncoder().encode(`data: ${chunk}\n\n`));
|
|
224
|
-
}
|
|
225
|
-
if (!abort.signal.aborted) controller.close();
|
|
226
|
-
},
|
|
227
|
-
cancel() {
|
|
228
|
-
abort.abort(); // the runtime cancels the response when the client goes away
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
```
|
|
227
|
+
The handler does CORS, `allowedOrigins`, body limits, pings, session tokens and the 0.5 format for old widgets, so bridging to it is better than calling `createChatHandler` and writing the HTTP side yourself.
|
|
232
228
|
|
|
233
229
|
## License
|
|
234
230
|
|
package/dist/adapters/ai-sdk.js
CHANGED
|
@@ -16,7 +16,7 @@ export function chatcopsAiSdkHandler(config) {
|
|
|
16
16
|
const origins = originPolicy(config);
|
|
17
17
|
return function handler(req) {
|
|
18
18
|
return fetchChatResponse(chat, origins, req, {
|
|
19
|
-
clientIp: (request) => (onWorkers() ? cloudflareClientIp(request, config.clientIp) : fetchClientIp(request, config.clientIp)),
|
|
19
|
+
clientIp: (request) => (onWorkers() ? cloudflareClientIp(request, config.clientIp, chat.logger) : fetchClientIp(request, config.clientIp, chat.logger)),
|
|
20
20
|
aiSdk: true,
|
|
21
21
|
});
|
|
22
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../../src/adapters/ai-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA4B;IAC/D,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO,SAAS,OAAO,CAAC,GAAY;QAClC,OAAO,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE;YAC3C,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../../src/adapters/ai-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA4B;IAC/D,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO,SAAS,OAAO,CAAC,GAAY;QAClC,OAAO,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE;YAC3C,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACvJ,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,OAAQ,UAAqD,CAAC,SAAS,EAAE,SAAS,KAAK,oBAAoB,CAAC;AAC9G,CAAC"}
|
|
@@ -9,7 +9,7 @@ export function chatcopsCloudflareHandler(config) {
|
|
|
9
9
|
// running after a visitor disconnects.
|
|
10
10
|
return function handler(request, _env, ctx) {
|
|
11
11
|
return fetchChatResponse(chat, origins, request, {
|
|
12
|
-
clientIp: (req) => cloudflareClientIp(req, config.clientIp),
|
|
12
|
+
clientIp: (req) => cloudflareClientIp(req, config.clientIp, chat.logger),
|
|
13
13
|
...(ctx?.waitUntil ? { waitUntil: (promise) => ctx.waitUntil?.(promise) } : {}),
|
|
14
14
|
});
|
|
15
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D,MAAM,UAAU,yBAAyB,CAAC,MAA4B;IACpE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,2EAA2E;IAC3E,uCAAuC;IACvC,OAAO,SAAS,OAAO,CACrB,OAAgB,EAChB,IAAc,EACd,GAAqD;QAErD,OAAO,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;YAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D,MAAM,UAAU,yBAAyB,CAAC,MAA4B;IACpE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,2EAA2E;IAC3E,uCAAuC;IACvC,OAAO,SAAS,OAAO,CACrB,OAAgB,EAChB,IAAc,EACd,GAAqD;QAErD,OAAO,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;YAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;YACxE,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,OAAyB,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClG,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAezD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,IAIvB,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,OAAO,YAAY,
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAezD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,IAIvB,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,OAAO,YAAY,mBAwEvF;AAaD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,oBAAoB,IAIrD,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA+B1C"}
|
package/dist/adapters/express.js
CHANGED
|
@@ -33,6 +33,7 @@ export function chatcopsMiddleware(config) {
|
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
if (req.method !== 'POST') {
|
|
36
|
+
res.setHeader('Allow', 'POST, OPTIONS');
|
|
36
37
|
sendError(405, 'Method not allowed');
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
@@ -47,11 +48,11 @@ export function chatcopsMiddleware(config) {
|
|
|
47
48
|
res.status(404).json(errorBody('invalid_request', { message: 'Session tokens are off. Set `sessionSecrets` to turn them on.' }));
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
|
-
const reply = await chat.startSession(req.body, origin, expressClientIp(req));
|
|
51
|
+
const reply = await chat.startSession(req.body, origin, expressClientIp(req, chat.logger));
|
|
51
52
|
res.status(reply.status).json(reply.body);
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
|
-
const clientIp = expressClientIp(req);
|
|
55
|
+
const clientIp = expressClientIp(req, chat.logger);
|
|
55
56
|
// Stop the reply when the visitor goes away before it's done.
|
|
56
57
|
const abort = new AbortController();
|
|
57
58
|
res.on('close', () => {
|
|
@@ -99,7 +100,7 @@ function constantTimeEqual(a, b) {
|
|
|
99
100
|
* every instance, for `?from=` and `?to=` (milliseconds) or the last 30 days.
|
|
100
101
|
*/
|
|
101
102
|
export function chatcopsAnalyticsHandler(config) {
|
|
102
|
-
const { analyticsStats } = getOrCreateChatHandler(config);
|
|
103
|
+
const { analyticsStats, logger } = getOrCreateChatHandler(config);
|
|
103
104
|
let warned = false;
|
|
104
105
|
return async (req, res) => {
|
|
105
106
|
if (config.analyticsToken) {
|
|
@@ -113,7 +114,7 @@ export function chatcopsAnalyticsHandler(config) {
|
|
|
113
114
|
}
|
|
114
115
|
else if (!warned) {
|
|
115
116
|
warned = true;
|
|
116
|
-
|
|
117
|
+
logger.warn('analytics_public', 'The analytics endpoint is public and anyone can read your stats. Set `analyticsToken` in your ChatCopsServerConfig to require a bearer token.');
|
|
117
118
|
}
|
|
118
119
|
const from = timeParam(req.query?.from);
|
|
119
120
|
const to = timeParam(req.query?.to);
|
|
@@ -125,7 +126,7 @@ export function chatcopsAnalyticsHandler(config) {
|
|
|
125
126
|
res.json(await analyticsStats({ from, to }));
|
|
126
127
|
}
|
|
127
128
|
catch (err) {
|
|
128
|
-
|
|
129
|
+
logger.error('analytics_read_failed', `Reading analytics failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
129
130
|
res.status(500).json({ error: 'internal_error' });
|
|
130
131
|
}
|
|
131
132
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"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"}
|
package/dist/adapters/vercel.js
CHANGED
|
@@ -6,7 +6,7 @@ export function chatcopsVercelHandler(config) {
|
|
|
6
6
|
const chat = createChatHandler(config);
|
|
7
7
|
const origins = originPolicy(config);
|
|
8
8
|
return function handler(req) {
|
|
9
|
-
return fetchChatResponse(chat, origins, req, { clientIp: (request) => fetchClientIp(request, config.clientIp) });
|
|
9
|
+
return fetchChatResponse(chat, origins, req, { clientIp: (request) => fetchClientIp(request, config.clientIp, chat.logger) });
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=vercel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../src/adapters/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D,MAAM,UAAU,qBAAqB,CAAC,MAA4B;IAChE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO,SAAS,OAAO,CAAC,GAAY;QAClC,OAAO,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../src/adapters/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D,MAAM,UAAU,qBAAqB,CAAC,MAA4B;IAChE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO,SAAS,OAAO,CAAC,GAAY;QAClC,OAAO,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAChI,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/client-ip.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Logger } from '@chatcops/core';
|
|
1
2
|
/**
|
|
2
3
|
* The visitor's IP, for per-IP rate limits and budgets. Only headers a
|
|
3
4
|
* platform sets itself are read, never ones a visitor can send. When the IP
|
|
@@ -9,13 +10,13 @@ export type ClientIpResolver = (request: Request) => string | null | undefined;
|
|
|
9
10
|
export declare function cleanIp(value: string | null | undefined): string | undefined;
|
|
10
11
|
/** Vercel overwrites these headers, so a visitor can't set them there. */
|
|
11
12
|
export declare function onVercel(): boolean;
|
|
12
|
-
export declare function warnOnce(key: string, message: string): void;
|
|
13
|
+
export declare function warnOnce(key: string, message: string, logger?: Logger): void;
|
|
13
14
|
/** For tests. */
|
|
14
15
|
export declare function resetClientIpWarnings(): void;
|
|
15
16
|
/** The fetch handler for Vercel and other Fetch API runtimes. */
|
|
16
|
-
export declare function fetchClientIp(request: Request, resolver: ClientIpResolver | undefined): string | undefined;
|
|
17
|
+
export declare function fetchClientIp(request: Request, resolver: ClientIpResolver | undefined, logger?: Logger): string | undefined;
|
|
17
18
|
/** Cloudflare sets CF-Connecting-IP on every request that reaches a Worker. */
|
|
18
|
-
export declare function cloudflareClientIp(request: Request, resolver: ClientIpResolver | undefined): string | undefined;
|
|
19
|
+
export declare function cloudflareClientIp(request: Request, resolver: ClientIpResolver | undefined, logger?: Logger): string | undefined;
|
|
19
20
|
interface ExpressLikeRequest {
|
|
20
21
|
ip?: string;
|
|
21
22
|
socket?: {
|
|
@@ -31,6 +32,6 @@ interface ExpressLikeRequest {
|
|
|
31
32
|
* that setting off, every visitor gets the proxy's address and shares one
|
|
32
33
|
* rate limit and budget, so that case gets a warning.
|
|
33
34
|
*/
|
|
34
|
-
export declare function expressClientIp(req: ExpressLikeRequest): string | undefined;
|
|
35
|
+
export declare function expressClientIp(req: ExpressLikeRequest, logger?: Logger): string | undefined;
|
|
35
36
|
export {};
|
|
36
37
|
//# sourceMappingURL=client-ip.d.ts.map
|
package/dist/client-ip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-ip.d.ts","sourceRoot":"","sources":["../src/client-ip.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAQ/E,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"client-ip.d.ts","sourceRoot":"","sources":["../src/client-ip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC5D;;;;;GAKG;AAEH,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAQ/E,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAwB,GAAG,IAAI,CAI7F;AAED,iBAAiB;AACjB,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY3H;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOhI;AAED,UAAU,kBAAkB;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,GAAG,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS5F"}
|
package/dist/client-ip.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* The visitor's IP, for per-IP rate limits and budgets. Only headers a
|
|
3
|
-
* platform sets itself are read, never ones a visitor can send. When the IP
|
|
4
|
-
* can't be told, per-IP limits are skipped for that request (with one
|
|
5
|
-
* warning) instead of every visitor sharing one bucket.
|
|
6
|
-
*/
|
|
1
|
+
import { consoleLogger } from '@chatcops/core';
|
|
7
2
|
const DOCS = 'https://chat.codercops.com/server/fetch-runtimes/#the-visitors-ip';
|
|
8
3
|
// IPv4, IPv6 (including IPv4-mapped) and nothing else, so a header can't
|
|
9
4
|
// carry an arbitrary counter key.
|
|
@@ -17,34 +12,34 @@ export function onVercel() {
|
|
|
17
12
|
return typeof process !== 'undefined' && Boolean(process.env?.VERCEL);
|
|
18
13
|
}
|
|
19
14
|
const warned = new Set();
|
|
20
|
-
export function warnOnce(key, message) {
|
|
15
|
+
export function warnOnce(key, message, logger = consoleLogger()) {
|
|
21
16
|
if (warned.has(key))
|
|
22
17
|
return;
|
|
23
18
|
warned.add(key);
|
|
24
|
-
|
|
19
|
+
logger.warn('client_ip', message, { key });
|
|
25
20
|
}
|
|
26
21
|
/** For tests. */
|
|
27
22
|
export function resetClientIpWarnings() {
|
|
28
23
|
warned.clear();
|
|
29
24
|
}
|
|
30
25
|
/** The fetch handler for Vercel and other Fetch API runtimes. */
|
|
31
|
-
export function fetchClientIp(request, resolver) {
|
|
26
|
+
export function fetchClientIp(request, resolver, logger) {
|
|
32
27
|
if (resolver)
|
|
33
28
|
return cleanIp(resolver(request));
|
|
34
29
|
if (onVercel()) {
|
|
35
30
|
const headers = request.headers;
|
|
36
31
|
return cleanIp(headers.get('x-vercel-forwarded-for')) ?? cleanIp(headers.get('x-real-ip')) ?? cleanIp(headers.get('x-forwarded-for'));
|
|
37
32
|
}
|
|
38
|
-
warnOnce('fetch', `
|
|
33
|
+
warnOnce('fetch', `Not running on Vercel, so the visitor's IP isn't read from X-Forwarded-For, which a visitor can set themselves. Per-IP rate limits and budgets are off until you set \`clientIp\`. See ${DOCS}`, logger);
|
|
39
34
|
return undefined;
|
|
40
35
|
}
|
|
41
36
|
/** Cloudflare sets CF-Connecting-IP on every request that reaches a Worker. */
|
|
42
|
-
export function cloudflareClientIp(request, resolver) {
|
|
37
|
+
export function cloudflareClientIp(request, resolver, logger) {
|
|
43
38
|
if (resolver)
|
|
44
39
|
return cleanIp(resolver(request));
|
|
45
40
|
const ip = cleanIp(request.headers.get('cf-connecting-ip'));
|
|
46
41
|
if (!ip) {
|
|
47
|
-
warnOnce('cloudflare', '
|
|
42
|
+
warnOnce('cloudflare', 'A request had no CF-Connecting-IP header, so per-IP rate limits and budgets were skipped for it.', logger);
|
|
48
43
|
}
|
|
49
44
|
return ip;
|
|
50
45
|
}
|
|
@@ -53,9 +48,9 @@ export function cloudflareClientIp(request, resolver) {
|
|
|
53
48
|
* that setting off, every visitor gets the proxy's address and shares one
|
|
54
49
|
* rate limit and budget, so that case gets a warning.
|
|
55
50
|
*/
|
|
56
|
-
export function expressClientIp(req) {
|
|
51
|
+
export function expressClientIp(req, logger) {
|
|
57
52
|
if (req.headers?.['x-forwarded-for'] !== undefined && !req.app?.get?.('trust proxy')) {
|
|
58
|
-
warnOnce('express', "
|
|
53
|
+
warnOnce('express', "A request had X-Forwarded-For, but Express's `trust proxy` setting is off, so the connection's IP is used. Behind a proxy that means every visitor gets the proxy's IP and shares one rate limit and budget. With one proxy in front, call app.set('trust proxy', 1).", logger);
|
|
59
54
|
}
|
|
60
55
|
return cleanIp(req.ip ?? req.socket?.remoteAddress);
|
|
61
56
|
}
|
package/dist/client-ip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-ip.js","sourceRoot":"","sources":["../src/client-ip.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client-ip.js","sourceRoot":"","sources":["../src/client-ip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAe,MAAM,gBAAgB,CAAC;AAW5D,MAAM,IAAI,GAAG,mEAAmE,CAAC;AAEjF,yEAAyE;AACzE,kCAAkC;AAClC,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAE3C,MAAM,UAAU,OAAO,CAAC,KAAgC;IACtD,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACxC,OAAO,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;AAEjC,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,OAAe,EAAE,SAAiB,aAAa,EAAE;IACrF,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,qBAAqB;IACnC,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,aAAa,CAAC,OAAgB,EAAE,QAAsC,EAAE,MAAe;IACrG,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,IAAI,QAAQ,EAAE,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACxI,CAAC;IACD,QAAQ,CACN,OAAO,EACP,0LAA0L,IAAI,EAAE,EAChM,MAAM,CACP,CAAC;IACF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,kBAAkB,CAAC,OAAgB,EAAE,QAAsC,EAAE,MAAe;IAC1G,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,QAAQ,CAAC,YAAY,EAAE,kGAAkG,EAAE,MAAM,CAAC,CAAC;IACrI,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AASD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAuB,EAAE,MAAe;IACtE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;QACrF,QAAQ,CACN,SAAS,EACT,uQAAuQ,EACvQ,MAAM,CACP,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACtD,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { ClientIpResolver } from './client-ip.js';
|
|
3
3
|
import type { TurnstileConfig } from './security/turnstile.js';
|
|
4
|
-
import type { AIProvider, Budgets, ChatCopsStorage, ChatTool,
|
|
4
|
+
import type { AIProvider, Budgets, ChatCopsStorage, ChatTool, KnowledgeSource, Logger, ProviderConfig, WebhookConfig } from '@chatcops/core';
|
|
5
5
|
export interface ChatCopsServerConfig {
|
|
6
6
|
/**
|
|
7
7
|
* Which model to use: a config like `{ type: 'claude', apiKey }`, or a
|
|
@@ -9,6 +9,12 @@ export interface ChatCopsServerConfig {
|
|
|
9
9
|
*/
|
|
10
10
|
provider: ProviderConfig | AIProvider;
|
|
11
11
|
systemPrompt: string;
|
|
12
|
+
/**
|
|
13
|
+
* Where the server writes startup notes, refused requests and every error
|
|
14
|
+
* it handles instead of throwing, each with a stable `event` name. Default
|
|
15
|
+
* `consoleLogger()`; `jsonLogger()` writes one JSON object per line.
|
|
16
|
+
*/
|
|
17
|
+
logger?: Logger;
|
|
12
18
|
tools?: ChatTool[];
|
|
13
19
|
toolTimeoutMs?: number;
|
|
14
20
|
/** Most tokens in one reply. Defaults to 4096 (`DEFAULT_MAX_TOKENS` in @chatcops/core). */
|
|
@@ -47,11 +53,6 @@ export interface ChatCopsServerConfig {
|
|
|
47
53
|
* shared between serverless instances.
|
|
48
54
|
*/
|
|
49
55
|
storage?: ChatCopsStorage;
|
|
50
|
-
/**
|
|
51
|
-
* @deprecated Use `storage`. A conversation store on its own, as in 0.4.
|
|
52
|
-
* Setting both is an error.
|
|
53
|
-
*/
|
|
54
|
-
conversationStore?: ConversationStore;
|
|
55
56
|
/**
|
|
56
57
|
* How long to keep conversations. `purge()` on the handler deletes older
|
|
57
58
|
* ones; call it on a schedule (a cron job, a Workers cron trigger).
|
|
@@ -67,8 +68,6 @@ export interface ChatCopsServerConfig {
|
|
|
67
68
|
* stops other sites embedding your bot, not scripts. Defaults to `['*']`.
|
|
68
69
|
*/
|
|
69
70
|
allowedOrigins?: string[];
|
|
70
|
-
/** @deprecated Use `allowedOrigins`. Read as a one-item `allowedOrigins`. */
|
|
71
|
-
cors?: string;
|
|
72
71
|
/**
|
|
73
72
|
* Reads the visitor's IP for per-IP rate limits and budgets, in the fetch
|
|
74
73
|
* handlers (`chatcopsVercelHandler`, `chatcopsCloudflareHandler`). Needed
|
|
@@ -91,11 +90,13 @@ export interface ChatCopsServerConfig {
|
|
|
91
90
|
/** How long a session token lasts, in seconds. Defaults to 900. */
|
|
92
91
|
sessionTtlSec?: number;
|
|
93
92
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
93
|
+
* Accept chat requests without a session token. Off by default: the
|
|
94
|
+
* server needs `sessionSecrets`, and each chat request needs a token from
|
|
95
|
+
* `<chat url>/session`, which the widget gets by itself. Set true for a
|
|
96
|
+
* server without `sessionSecrets`, or, with them, while widgets older than
|
|
97
|
+
* 0.6 (which don't send tokens) are still out there.
|
|
97
98
|
*/
|
|
98
|
-
|
|
99
|
+
allowAnonymous?: boolean;
|
|
99
100
|
/**
|
|
100
101
|
* Cloudflare Turnstile when a session token is issued: `/session` needs a
|
|
101
102
|
* Turnstile token and checks it with Cloudflare before signing. Refreshing
|
|
@@ -103,18 +104,28 @@ export interface ChatCopsServerConfig {
|
|
|
103
104
|
* the widget's `turnstileSiteKey`.
|
|
104
105
|
*/
|
|
105
106
|
turnstile?: TurnstileConfig;
|
|
107
|
+
/**
|
|
108
|
+
* Signed-in visitors. Your site signs a \`userToken\` (an HS256 JWT with
|
|
109
|
+
* \`sub\`, \`exp\` and an optional \`tier\`) with \`secret\`, and the widget
|
|
110
|
+
* sends it with \`/session\`. The user id is stored on the conversation, so
|
|
111
|
+
* the same user can resume it with a fresh token, and \`tiers\` gives a
|
|
112
|
+
* tier its own budgets (merged over \`budgets\`). Needs \`sessionSecrets\`.
|
|
113
|
+
*/
|
|
114
|
+
identity?: {
|
|
115
|
+
secret: string;
|
|
116
|
+
tiers?: Record<string, Budgets>;
|
|
117
|
+
};
|
|
106
118
|
/**
|
|
107
119
|
* Adds the reply's token usage to the `finish` part of protocol v1
|
|
108
120
|
* streams. Off by default, since visitors can read the stream.
|
|
109
121
|
*/
|
|
110
122
|
exposeUsage?: boolean;
|
|
111
|
-
/** @deprecated The server ignores this. Set the widget's text with its `strings` option. */
|
|
112
|
-
i18n?: {
|
|
113
|
-
defaultLocale: string;
|
|
114
|
-
locales: Record<string, LocaleStrings>;
|
|
115
|
-
};
|
|
116
123
|
}
|
|
117
124
|
export declare const MAX_USER_DATA_FIELDS = 50;
|
|
125
|
+
/** `pageContext.data`, what a site adds with the widget's setContext(). */
|
|
126
|
+
export declare const MAX_PAGE_DATA_FIELDS = 20;
|
|
127
|
+
export declare const MAX_PAGE_DATA_KEY_LENGTH = 40;
|
|
128
|
+
export declare const MAX_PAGE_DATA_VALUE_LENGTH = 500;
|
|
118
129
|
export declare const MAX_USER_DATA_KEY_LENGTH = 100;
|
|
119
130
|
/** Longer page URLs are still accepted, but only this much reaches the prompt. */
|
|
120
131
|
export declare const MAX_PAGE_URL_LENGTH = 2000;
|
|
@@ -138,16 +149,19 @@ export declare const chatRequestSchema: z.ZodObject<{
|
|
|
138
149
|
title: z.ZodString;
|
|
139
150
|
description: z.ZodOptional<z.ZodString>;
|
|
140
151
|
contentSnippet: z.ZodOptional<z.ZodString>;
|
|
152
|
+
data: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>;
|
|
141
153
|
}, "strip", z.ZodTypeAny, {
|
|
142
154
|
url: string;
|
|
143
155
|
title: string;
|
|
144
156
|
description?: string | undefined;
|
|
145
157
|
contentSnippet?: string | undefined;
|
|
158
|
+
data?: Record<string, string> | undefined;
|
|
146
159
|
}, {
|
|
147
160
|
url: string;
|
|
148
161
|
title: string;
|
|
149
162
|
description?: string | undefined;
|
|
150
163
|
contentSnippet?: string | undefined;
|
|
164
|
+
data?: Record<string, string> | undefined;
|
|
151
165
|
}>>;
|
|
152
166
|
locale: z.ZodOptional<z.ZodString>;
|
|
153
167
|
userData: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>;
|
|
@@ -163,6 +177,7 @@ export declare const chatRequestSchema: z.ZodObject<{
|
|
|
163
177
|
title: string;
|
|
164
178
|
description?: string | undefined;
|
|
165
179
|
contentSnippet?: string | undefined;
|
|
180
|
+
data?: Record<string, string> | undefined;
|
|
166
181
|
} | undefined;
|
|
167
182
|
locale?: string | undefined;
|
|
168
183
|
userData?: Record<string, string> | undefined;
|
|
@@ -178,6 +193,7 @@ export declare const chatRequestSchema: z.ZodObject<{
|
|
|
178
193
|
title: string;
|
|
179
194
|
description?: string | undefined;
|
|
180
195
|
contentSnippet?: string | undefined;
|
|
196
|
+
data?: Record<string, string> | undefined;
|
|
181
197
|
} | undefined;
|
|
182
198
|
locale?: string | undefined;
|
|
183
199
|
userData?: Record<string, string> | undefined;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EACP,eAAe,EACf,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EACP,eAAe,EACf,QAAQ,EACR,eAAe,EACf,MAAM,EACN,cAAc,EACd,aAAa,EACd,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,EAAE,cAAc,GAAG,UAAU,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uGAAuG;IACvG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC1B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC/D;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAGD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,eAAO,MAAM,iBAAiB;;;;IAI5B;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqBH,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
// Everything in a request can end up in the system prompt, so every field has a ceiling.
|
|
3
3
|
export const MAX_USER_DATA_FIELDS = 50;
|
|
4
|
+
/** `pageContext.data`, what a site adds with the widget's setContext(). */
|
|
5
|
+
export const MAX_PAGE_DATA_FIELDS = 20;
|
|
6
|
+
export const MAX_PAGE_DATA_KEY_LENGTH = 40;
|
|
7
|
+
export const MAX_PAGE_DATA_VALUE_LENGTH = 500;
|
|
4
8
|
export const MAX_USER_DATA_KEY_LENGTH = 100;
|
|
5
9
|
/** Longer page URLs are still accepted, but only this much reaches the prompt. */
|
|
6
10
|
export const MAX_PAGE_URL_LENGTH = 2000;
|
|
@@ -18,6 +22,12 @@ export const chatRequestSchema = z.object({
|
|
|
18
22
|
title: z.string().max(500),
|
|
19
23
|
description: z.string().max(1000).optional(),
|
|
20
24
|
contentSnippet: z.string().max(2000).optional(),
|
|
25
|
+
data: z
|
|
26
|
+
.record(z.string().max(MAX_PAGE_DATA_KEY_LENGTH), z.string().max(MAX_PAGE_DATA_VALUE_LENGTH))
|
|
27
|
+
.refine((data) => Object.keys(data).length <= MAX_PAGE_DATA_FIELDS, {
|
|
28
|
+
message: `pageContext.data can have at most ${MAX_PAGE_DATA_FIELDS} fields`,
|
|
29
|
+
})
|
|
30
|
+
.optional(),
|
|
21
31
|
}).optional(),
|
|
22
32
|
locale: z.string().max(10).optional(),
|
|
23
33
|
userData: z
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8HxB,yFAAyF;AACzF,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAC9C,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAC5C,kFAAkF;AAClF,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAChD;;;OAGG;IACH,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3G,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;QACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;QAC1B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;QAC5C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;QAC/C,IAAI,EAAE,CAAC;aACJ,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;aAC5F,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,oBAAoB,EAAE;YAClE,OAAO,EAAE,qCAAqC,oBAAoB,SAAS;SAC5E,CAAC;aACD,QAAQ,EAAE;KACd,CAAC,CAAC,QAAQ,EAAE;IACb,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrC,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACrE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,oBAAoB,EAAE;QAClE,OAAO,EAAE,6BAA6B,oBAAoB,SAAS;KACpE,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-worker.d.ts","sourceRoot":"","sources":["../../src/examples/cloudflare-worker.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cloudflare-worker.d.ts","sourceRoot":"","sources":["../../src/examples/cloudflare-worker.ts"],"names":[],"mappings":";mBA0BuB,OAAO,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;;AAD/E,wBAIE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Example: Cloudflare Worker
|
|
3
3
|
*
|
|
4
|
-
* Set env vars: ANTHROPIC_API_KEY
|
|
4
|
+
* Set env vars: ANTHROPIC_API_KEY, and CHATCOPS_SESSION_SECRET (`openssl rand -base64 32`)
|
|
5
5
|
*/
|
|
6
6
|
import { chatcopsCloudflareHandler } from '@chatcops/server';
|
|
7
7
|
// Built on the first request rather than at import, because the API key is a
|
|
@@ -15,7 +15,9 @@ function getHandler(env) {
|
|
|
15
15
|
apiKey: env.ANTHROPIC_API_KEY,
|
|
16
16
|
},
|
|
17
17
|
systemPrompt: 'You are a helpful assistant.',
|
|
18
|
-
|
|
18
|
+
allowedOrigins: ['*'],
|
|
19
|
+
// Signs the session tokens the widget fetches before it chats.
|
|
20
|
+
sessionSecrets: [env.CHATCOPS_SESSION_SECRET],
|
|
19
21
|
});
|
|
20
22
|
return handler;
|
|
21
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-worker.js","sourceRoot":"","sources":["../../src/examples/cloudflare-worker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,6EAA6E;AAC7E,+EAA+E;AAC/E,2EAA2E;AAC3E,IAAI,OAAiE,CAAC;AACtE,SAAS,UAAU,CAAC,GAA2B;IAC7C,OAAO,KAAK,yBAAyB,CAAC;QACpC,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,GAAG,CAAC,iBAAiB;SAC9B;QACD,YAAY,EAAE,8BAA8B;QAC5C,
|
|
1
|
+
{"version":3,"file":"cloudflare-worker.js","sourceRoot":"","sources":["../../src/examples/cloudflare-worker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,6EAA6E;AAC7E,+EAA+E;AAC/E,2EAA2E;AAC3E,IAAI,OAAiE,CAAC;AACtE,SAAS,UAAU,CAAC,GAA2B;IAC7C,OAAO,KAAK,yBAAyB,CAAC;QACpC,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,GAAG,CAAC,iBAAiB;SAC9B;QACD,YAAY,EAAE,8BAA8B;QAC5C,cAAc,EAAE,CAAC,GAAG,CAAC;QACrB,+DAA+D;QAC/D,cAAc,EAAE,CAAC,GAAG,CAAC,uBAAuB,CAAC;KAC9C,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,eAAe;IACb,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,GAA2B;QACvD,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;CACF,CAAC"}
|
|
@@ -18,7 +18,9 @@ app.all('/chat', chatcopsMiddleware({
|
|
|
18
18
|
systemPrompt: `You are a helpful customer support assistant for Acme Inc.
|
|
19
19
|
Be friendly, concise, and helpful. If a user wants to get in touch,
|
|
20
20
|
ask for their name, email, and project details to capture as a lead.`,
|
|
21
|
-
|
|
21
|
+
allowedOrigins: ['*'],
|
|
22
|
+
// Signs the session tokens the widget fetches before it chats (`openssl rand -base64 32`).
|
|
23
|
+
sessionSecrets: [process.env.CHATCOPS_SESSION_SECRET ?? ''],
|
|
22
24
|
rateLimit: { maxRequests: 30, windowMs: 60_000 },
|
|
23
25
|
analytics: true,
|
|
24
26
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express-server.js","sourceRoot":"","sources":["../../src/examples/express-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAExB,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,kBAAkB,CAAC;IAClC,QAAQ,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAkB;QACtC,KAAK,EAAE,2BAA2B;KACnC;IACD,YAAY,EAAE;;qEAEqD;IACnE,
|
|
1
|
+
{"version":3,"file":"express-server.js","sourceRoot":"","sources":["../../src/examples/express-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAExB,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,kBAAkB,CAAC;IAClC,QAAQ,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAkB;QACtC,KAAK,EAAE,2BAA2B;KACnC;IACD,YAAY,EAAE;;qEAEqD;IACnE,cAAc,EAAE,CAAC,GAAG,CAAC;IACrB,2FAA2F;IAC3F,cAAc,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC;IAC3D,SAAS,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;IAChD,SAAS,EAAE,IAAI;CAChB,CAAC,CAAC,CAAC;AAEJ,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AACtC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACpB,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,6FAA6F,CAAC,CAAC;AAC7J,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel-api.d.ts","sourceRoot":"","sources":["../../src/examples/vercel-api.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,MAAM;;CAAsB,CAAC;;AAE1C,
|
|
1
|
+
{"version":3,"file":"vercel-api.d.ts","sourceRoot":"","sources":["../../src/examples/vercel-api.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,MAAM;;CAAsB,CAAC;;AAE1C,wBASG"}
|
|
@@ -12,6 +12,8 @@ export default chatcopsVercelHandler({
|
|
|
12
12
|
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
13
13
|
},
|
|
14
14
|
systemPrompt: 'You are a helpful assistant.',
|
|
15
|
-
|
|
15
|
+
allowedOrigins: ['*'],
|
|
16
|
+
// Signs the session tokens the widget fetches before it chats (`openssl rand -base64 32`).
|
|
17
|
+
sessionSecrets: [process.env.CHATCOPS_SESSION_SECRET ?? ''],
|
|
16
18
|
});
|
|
17
19
|
//# sourceMappingURL=vercel-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel-api.js","sourceRoot":"","sources":["../../src/examples/vercel-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,CAAC,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAE1C,eAAe,qBAAqB,CAAC;IACnC,QAAQ,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAkB;KACvC;IACD,YAAY,EAAE,8BAA8B;IAC5C,
|
|
1
|
+
{"version":3,"file":"vercel-api.js","sourceRoot":"","sources":["../../src/examples/vercel-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,CAAC,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAE1C,eAAe,qBAAqB,CAAC;IACnC,QAAQ,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAkB;KACvC;IACD,YAAY,EAAE,8BAA8B;IAC5C,cAAc,EAAE,CAAC,GAAG,CAAC;IACrB,2FAA2F;IAC3F,cAAc,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC;CAC5D,CAAC,CAAC"}
|
package/dist/handler.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare function createChatHandler(config: ChatCopsServerConfig): {
|
|
|
21
21
|
to?: number;
|
|
22
22
|
}) => Promise<AnalyticsStats | null>;
|
|
23
23
|
cleanup: () => void;
|
|
24
|
+
/** The logger the handler writes to, for adapters to use as well. */
|
|
25
|
+
logger: import("@chatcops/core").Logger;
|
|
24
26
|
};
|
|
25
27
|
/** The stream a caller writes: protocol v1, the 0.5 chunks, or the AI SDK's UI message stream. */
|
|
26
28
|
export type ChatFormat = 'v1' | 'legacy' | 'ai-sdk';
|
package/dist/handler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,cAAc,EAgBnB,KAAK,WAAW,EAChB,KAAK,OAAO,EAIZ,KAAK,WAAW,EAChB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,oBAAoB,EAAwB,MAAM,aAAa,CAAC;AAU9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB;uBAoMpD,OAAO,aACF,MAAM,YACR;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAChC,cAAc,CAAC,MAAM,CAAC;sBAtGM,OAAO,aAAa,MAAM,YAAW,gBAAgB,KAAQ,OAAO,CAAC,SAAS,CAAC;6BAiTtE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAc5D,yFAAyF;IACzF,2EAA2E;0BAEhE,OAAO,UAAU,MAAM,GAAG,IAAI,aAAa,MAAM;;;;;;IAG5D,uFAAuF;;6BAhPnD;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;;IAoPnG,qEAAqE;;EAGxE;AAED,kGAAkG;AAClG,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAQpD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,iFAAiF;IACjF,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,gEAAgE;AAChE,MAAM,MAAM,SAAS,GACjB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;CAAE,GACnD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9B,gEAAgE;IAChE,MAAM,EAAE,WAAW,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC7C,CAAC;AAEN,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAU/D;;;GAGG;AACH,wBAAuB,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAc5F;AA+CD,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,WAAW,EAAO,GAAG,MAAM,CAkBvF"}
|