@cogitator-ai/express 0.2.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/LICENSE +21 -0
- package/README.md +346 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +4 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +26 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts +4 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +42 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +4 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +32 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/index.d.ts +5 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +5 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +4 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +50 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/routes/agents.d.ts +4 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +116 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/health.d.ts +4 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +18 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +7 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +7 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/swarms.d.ts +4 -0
- package/dist/routes/swarms.d.ts.map +1 -0
- package/dist/routes/swarms.js +179 -0
- package/dist/routes/swarms.js.map +1 -0
- package/dist/routes/threads.d.ts +4 -0
- package/dist/routes/threads.d.ts.map +1 -0
- package/dist/routes/threads.js +108 -0
- package/dist/routes/threads.js.map +1 -0
- package/dist/routes/tools.d.ts +4 -0
- package/dist/routes/tools.d.ts.map +1 -0
- package/dist/routes/tools.js +29 -0
- package/dist/routes/tools.js.map +1 -0
- package/dist/routes/workflows.d.ts +4 -0
- package/dist/routes/workflows.d.ts.map +1 -0
- package/dist/routes/workflows.js +110 -0
- package/dist/routes/workflows.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +90 -0
- package/dist/server.js.map +1 -0
- package/dist/streaming/express-stream-writer.d.ts +24 -0
- package/dist/streaming/express-stream-writer.d.ts.map +1 -0
- package/dist/streaming/express-stream-writer.js +73 -0
- package/dist/streaming/express-stream-writer.js.map +1 -0
- package/dist/streaming/helpers.d.ts +4 -0
- package/dist/streaming/helpers.d.ts.map +1 -0
- package/dist/streaming/helpers.js +14 -0
- package/dist/streaming/helpers.js.map +1 -0
- package/dist/streaming/index.d.ts +4 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +4 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/streaming/protocol.d.ts +76 -0
- package/dist/streaming/protocol.d.ts.map +1 -0
- package/dist/streaming/protocol.js +37 -0
- package/dist/streaming/protocol.js.map +1 -0
- package/dist/swagger/generator.d.ts +3 -0
- package/dist/swagger/generator.d.ts.map +1 -0
- package/dist/swagger/generator.js +486 -0
- package/dist/swagger/generator.js.map +1 -0
- package/dist/swagger/index.d.ts +3 -0
- package/dist/swagger/index.d.ts.map +1 -0
- package/dist/swagger/index.js +3 -0
- package/dist/swagger/index.js.map +1 -0
- package/dist/swagger/ui.d.ts +4 -0
- package/dist/swagger/ui.d.ts.map +1 -0
- package/dist/swagger/ui.js +39 -0
- package/dist/swagger/ui.js.map +1 -0
- package/dist/types.d.ts +246 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/websocket/index.d.ts +2 -0
- package/dist/websocket/index.d.ts.map +1 -0
- package/dist/websocket/index.js +2 -0
- package/dist/websocket/index.js.map +1 -0
- package/dist/websocket/ws-handler.d.ts +6 -0
- package/dist/websocket/ws-handler.d.ts.map +1 -0
- package/dist/websocket/ws-handler.js +145 -0
- package/dist/websocket/ws-handler.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Cogitator Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# @cogitator-ai/express
|
|
2
|
+
|
|
3
|
+
Express.js server adapter for Cogitator AI runtime. Automatically generates REST API endpoints for agents, workflows, and swarms with SSE streaming, WebSocket support, and Swagger documentation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @cogitator-ai/express express
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @cogitator-ai/express express
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import express from 'express';
|
|
17
|
+
import { Cogitator, Agent, tool } from '@cogitator-ai/core';
|
|
18
|
+
import { CogitatorServer } from '@cogitator-ai/express';
|
|
19
|
+
|
|
20
|
+
const app = express();
|
|
21
|
+
|
|
22
|
+
const cogitator = new Cogitator({
|
|
23
|
+
defaultBackend: 'openai',
|
|
24
|
+
backends: { openai: { apiKey: process.env.OPENAI_API_KEY } },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const chatAgent = new Agent({
|
|
28
|
+
name: 'chat',
|
|
29
|
+
instructions: 'You are a helpful assistant.',
|
|
30
|
+
model: 'gpt-4o-mini',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const server = new CogitatorServer({
|
|
34
|
+
app,
|
|
35
|
+
cogitator,
|
|
36
|
+
agents: { chat: chatAgent },
|
|
37
|
+
config: {
|
|
38
|
+
basePath: '/api',
|
|
39
|
+
enableSwagger: true,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await server.init();
|
|
44
|
+
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Auto-generated Endpoints
|
|
48
|
+
|
|
49
|
+
### Agents
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
GET /api/agents - List all agents
|
|
53
|
+
POST /api/agents/:name/run - Run agent (JSON response)
|
|
54
|
+
POST /api/agents/:name/stream - Run agent (SSE stream)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Threads (Memory)
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
GET /api/threads/:id - Get thread messages
|
|
61
|
+
POST /api/threads/:id/messages - Add message to thread
|
|
62
|
+
DELETE /api/threads/:id - Delete thread
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Workflows
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
GET /api/workflows - List all workflows
|
|
69
|
+
POST /api/workflows/:name/run - Run workflow
|
|
70
|
+
POST /api/workflows/:name/stream - Stream workflow events
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Swarms
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
GET /api/swarms - List all swarms
|
|
77
|
+
POST /api/swarms/:name/run - Run swarm
|
|
78
|
+
POST /api/swarms/:name/stream - Stream swarm events
|
|
79
|
+
GET /api/swarms/:name/blackboard - Get shared state
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Tools & Docs
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
GET /api/tools - List all tools
|
|
86
|
+
GET /api/health - Health check
|
|
87
|
+
GET /api/docs - Swagger UI
|
|
88
|
+
GET /api/openapi.json - OpenAPI spec
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const server = new CogitatorServer({
|
|
95
|
+
app,
|
|
96
|
+
cogitator,
|
|
97
|
+
agents: { chat: chatAgent, research: researchAgent },
|
|
98
|
+
workflows: { 'code-review': codeReviewWorkflow },
|
|
99
|
+
swarms: { 'dev-team': devTeamSwarm },
|
|
100
|
+
config: {
|
|
101
|
+
basePath: '/cogitator',
|
|
102
|
+
enableWebSocket: true,
|
|
103
|
+
enableSwagger: true,
|
|
104
|
+
|
|
105
|
+
// Authentication
|
|
106
|
+
auth: async (req) => {
|
|
107
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
108
|
+
const user = await validateToken(token);
|
|
109
|
+
return { userId: user.id, roles: user.roles };
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// Rate limiting
|
|
113
|
+
rateLimit: {
|
|
114
|
+
windowMs: 60000, // 1 minute
|
|
115
|
+
max: 100, // 100 requests per window
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// CORS
|
|
119
|
+
cors: {
|
|
120
|
+
origin: ['https://myapp.com'],
|
|
121
|
+
credentials: true,
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
// Swagger customization
|
|
125
|
+
swagger: {
|
|
126
|
+
title: 'My AI API',
|
|
127
|
+
description: 'AI-powered API endpoints',
|
|
128
|
+
version: '1.0.0',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## SSE Streaming
|
|
135
|
+
|
|
136
|
+
The `/agents/:name/stream` endpoint returns Server-Sent Events:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// Client-side
|
|
140
|
+
const response = await fetch('/api/agents/chat/stream', {
|
|
141
|
+
method: 'POST',
|
|
142
|
+
headers: { 'Content-Type': 'application/json' },
|
|
143
|
+
body: JSON.stringify({ input: 'Hello!' }),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const reader = response.body.getReader();
|
|
147
|
+
const decoder = new TextDecoder();
|
|
148
|
+
|
|
149
|
+
while (true) {
|
|
150
|
+
const { done, value } = await reader.read();
|
|
151
|
+
if (done) break;
|
|
152
|
+
|
|
153
|
+
const lines = decoder.decode(value).split('\n');
|
|
154
|
+
for (const line of lines) {
|
|
155
|
+
if (line.startsWith('data: ')) {
|
|
156
|
+
const event = JSON.parse(line.slice(6));
|
|
157
|
+
console.log(event);
|
|
158
|
+
// { type: 'text-delta', id: '...', delta: 'Hello' }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## WebSocket Support
|
|
165
|
+
|
|
166
|
+
Enable real-time bidirectional communication:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const server = new CogitatorServer({
|
|
170
|
+
// ...
|
|
171
|
+
config: { enableWebSocket: true },
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// After init, setup WebSocket on HTTP server
|
|
175
|
+
import { setupWebSocket } from '@cogitator-ai/express';
|
|
176
|
+
import { createServer } from 'http';
|
|
177
|
+
|
|
178
|
+
const httpServer = createServer(app);
|
|
179
|
+
await setupWebSocket(httpServer, routeContext, { path: '/api/ws' });
|
|
180
|
+
httpServer.listen(3000);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Client usage:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const ws = new WebSocket('ws://localhost:3000/api/ws');
|
|
187
|
+
|
|
188
|
+
ws.onmessage = (event) => {
|
|
189
|
+
const message = JSON.parse(event.data);
|
|
190
|
+
console.log(message);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Run agent
|
|
194
|
+
ws.send(
|
|
195
|
+
JSON.stringify({
|
|
196
|
+
type: 'run',
|
|
197
|
+
id: 'req-1',
|
|
198
|
+
payload: {
|
|
199
|
+
type: 'agent',
|
|
200
|
+
name: 'chat',
|
|
201
|
+
input: 'Hello!',
|
|
202
|
+
},
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Custom Middleware
|
|
208
|
+
|
|
209
|
+
Use built-in middleware factories or create your own:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import {
|
|
213
|
+
createAuthMiddleware,
|
|
214
|
+
createRateLimitMiddleware,
|
|
215
|
+
createCorsMiddleware,
|
|
216
|
+
errorHandler,
|
|
217
|
+
} from '@cogitator-ai/express';
|
|
218
|
+
|
|
219
|
+
// Use individually
|
|
220
|
+
app.use(
|
|
221
|
+
'/api',
|
|
222
|
+
createAuthMiddleware(async (req) => {
|
|
223
|
+
// Custom auth logic
|
|
224
|
+
})
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
app.use(
|
|
228
|
+
'/api',
|
|
229
|
+
createRateLimitMiddleware({
|
|
230
|
+
windowMs: 60000,
|
|
231
|
+
max: 100,
|
|
232
|
+
keyGenerator: (req) => req.headers['x-api-key'] as string,
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Custom Routes
|
|
238
|
+
|
|
239
|
+
Create custom routes with streaming support:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { Router } from 'express';
|
|
243
|
+
import { ExpressStreamWriter, setupSSEHeaders, generateId } from '@cogitator-ai/express';
|
|
244
|
+
|
|
245
|
+
const router = Router();
|
|
246
|
+
|
|
247
|
+
router.post('/custom/stream', async (req, res) => {
|
|
248
|
+
setupSSEHeaders(res);
|
|
249
|
+
const writer = new ExpressStreamWriter(res);
|
|
250
|
+
const messageId = generateId('msg');
|
|
251
|
+
|
|
252
|
+
writer.start(messageId);
|
|
253
|
+
writer.textStart(generateId('txt'));
|
|
254
|
+
|
|
255
|
+
// Your streaming logic
|
|
256
|
+
writer.textDelta('txt-1', 'Hello ');
|
|
257
|
+
writer.textDelta('txt-1', 'World!');
|
|
258
|
+
|
|
259
|
+
writer.textEnd('txt-1');
|
|
260
|
+
writer.finish(messageId);
|
|
261
|
+
writer.close();
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## API Reference
|
|
266
|
+
|
|
267
|
+
### CogitatorServer
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
class CogitatorServer {
|
|
271
|
+
constructor(options: CogitatorServerConfig);
|
|
272
|
+
init(): Promise<void>;
|
|
273
|
+
readonly isInitialized: boolean;
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### CogitatorServerConfig
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
interface CogitatorServerConfig {
|
|
281
|
+
app: Router;
|
|
282
|
+
cogitator: Cogitator;
|
|
283
|
+
agents?: Record<string, Agent>;
|
|
284
|
+
workflows?: Record<string, Workflow>;
|
|
285
|
+
swarms?: Record<string, SwarmConfig>;
|
|
286
|
+
config?: {
|
|
287
|
+
basePath?: string; // Default: '/cogitator'
|
|
288
|
+
enableWebSocket?: boolean; // Default: false
|
|
289
|
+
enableSwagger?: boolean; // Default: true
|
|
290
|
+
auth?: AuthFunction;
|
|
291
|
+
rateLimit?: RateLimitConfig;
|
|
292
|
+
cors?: CorsConfig;
|
|
293
|
+
swagger?: SwaggerConfig;
|
|
294
|
+
websocket?: WebSocketConfig;
|
|
295
|
+
requestTimeout?: number; // Default: 30000
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### ExpressStreamWriter
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
class ExpressStreamWriter {
|
|
304
|
+
constructor(res: Response);
|
|
305
|
+
start(messageId: string): void;
|
|
306
|
+
textStart(id: string): void;
|
|
307
|
+
textDelta(id: string, delta: string): void;
|
|
308
|
+
textEnd(id: string): void;
|
|
309
|
+
toolCallStart(id: string, toolName: string): void;
|
|
310
|
+
toolCallDelta(id: string, argsTextDelta: string): void;
|
|
311
|
+
toolCallEnd(id: string): void;
|
|
312
|
+
toolResult(id: string, toolCallId: string, result: unknown): void;
|
|
313
|
+
workflowEvent(event: string, data: unknown): void;
|
|
314
|
+
swarmEvent(event: string, data: unknown): void;
|
|
315
|
+
error(message: string, code?: string): void;
|
|
316
|
+
finish(messageId: string, usage?: Usage): void;
|
|
317
|
+
close(): void;
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Error Handling
|
|
322
|
+
|
|
323
|
+
All endpoints return consistent error responses:
|
|
324
|
+
|
|
325
|
+
```json
|
|
326
|
+
{
|
|
327
|
+
"error": {
|
|
328
|
+
"message": "Agent 'unknown' not found",
|
|
329
|
+
"code": "NOT_FOUND"
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Error codes map to HTTP status codes:
|
|
335
|
+
|
|
336
|
+
- `INVALID_INPUT` → 400
|
|
337
|
+
- `UNAUTHORIZED` → 401
|
|
338
|
+
- `PERMISSION_DENIED` → 403
|
|
339
|
+
- `NOT_FOUND` → 404
|
|
340
|
+
- `RATE_LIMIT_EXCEEDED` → 429
|
|
341
|
+
- `INTERNAL` → 500
|
|
342
|
+
- `UNAVAILABLE` → 503
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { CogitatorServer } from './server.js';
|
|
2
|
+
export type { AuthContext, AuthFunction, CogitatorRequest, CogitatorServerConfig, RateLimitConfig, CorsConfig, SwaggerConfig, WebSocketConfig, RouteContext, AgentListResponse, AgentRunRequest, AgentRunResponse, ThreadResponse, AddMessageRequest, ToolListResponse, WorkflowListResponse, WorkflowRunRequest, WorkflowRunResponse, WorkflowStatusResponse, SwarmListResponse, SwarmRunRequest, SwarmRunResponse, BlackboardResponse, HealthResponse, ErrorResponse, WebSocketMessage, WebSocketResponse, OpenAPISpec, } from './types.js';
|
|
3
|
+
export { createAuthMiddleware, createRateLimitMiddleware, createCorsMiddleware, errorHandler, notFoundHandler, } from './middleware/index.js';
|
|
4
|
+
export { createHealthRoutes, createAgentRoutes, createThreadRoutes, createToolRoutes, createWorkflowRoutes, createSwarmRoutes, } from './routes/index.js';
|
|
5
|
+
export { ExpressStreamWriter, setupSSEHeaders, generateId, encodeSSE, encodeDone, } from './streaming/index.js';
|
|
6
|
+
export type { StreamEvent, StartEvent, TextStartEvent, TextDeltaEvent, TextEndEvent, ToolCallStartEvent, ToolCallDeltaEvent, ToolCallEndEvent, ToolResultEvent, ErrorEvent, FinishEvent, Usage, } from './streaming/protocol.js';
|
|
7
|
+
export { generateOpenAPISpec, serveSwaggerUI } from './swagger/index.js';
|
|
8
|
+
export { setupWebSocket } from './websocket/index.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,UAAU,EACV,SAAS,EACT,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,WAAW,EACX,KAAK,GACN,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { CogitatorServer } from './server.js';
|
|
2
|
+
export { createAuthMiddleware, createRateLimitMiddleware, createCorsMiddleware, errorHandler, notFoundHandler, } from './middleware/index.js';
|
|
3
|
+
export { createHealthRoutes, createAgentRoutes, createThreadRoutes, createToolRoutes, createWorkflowRoutes, createSwarmRoutes, } from './routes/index.js';
|
|
4
|
+
export { ExpressStreamWriter, setupSSEHeaders, generateId, encodeSSE, encodeDone, } from './streaming/index.js';
|
|
5
|
+
export { generateOpenAPISpec, serveSwaggerUI } from './swagger/index.js';
|
|
6
|
+
export { setupWebSocket } from './websocket/index.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAiC9C,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,UAAU,EACV,SAAS,EACT,UAAU,GACX,MAAM,sBAAsB,CAAC;AAiB9B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Response, NextFunction } from 'express';
|
|
2
|
+
import type { CogitatorRequest, AuthFunction } from '../types.js';
|
|
3
|
+
export declare function createAuthMiddleware(authFn?: AuthFunction): (req: CogitatorRequest, res: Response, next: NextFunction) => Promise<void>;
|
|
4
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGlE,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,YAAY,IAC1C,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAuBvE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { generateId } from '../streaming/helpers.js';
|
|
2
|
+
export function createAuthMiddleware(authFn) {
|
|
3
|
+
return async (req, res, next) => {
|
|
4
|
+
req.cogitator = {
|
|
5
|
+
requestId: generateId('req'),
|
|
6
|
+
startTime: Date.now(),
|
|
7
|
+
};
|
|
8
|
+
if (!authFn) {
|
|
9
|
+
return next();
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const auth = await authFn(req);
|
|
13
|
+
req.cogitator.auth = auth;
|
|
14
|
+
next();
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
res.status(401).json({
|
|
18
|
+
error: {
|
|
19
|
+
message: 'Unauthorized',
|
|
20
|
+
code: 'UNAUTHORIZED',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,UAAU,oBAAoB,CAAC,MAAqB;IACxD,OAAO,KAAK,EAAE,GAAqB,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACxE,GAAG,CAAC,SAAS,GAAG;YACd,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC;YAC5B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/B,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;YAC1B,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE;oBACL,OAAO,EAAE,cAAc;oBACvB,IAAI,EAAE,cAAc;iBACrB;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Response, NextFunction, Request } from 'express';
|
|
2
|
+
import type { CorsConfig } from '../types.js';
|
|
3
|
+
export declare function createCorsMiddleware(config: CorsConfig): (req: Request, res: Response, next: NextFunction) => void;
|
|
4
|
+
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAuB9C,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,IAU7C,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA4BxD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function isOriginAllowed(origin, allowed) {
|
|
2
|
+
if (!origin)
|
|
3
|
+
return false;
|
|
4
|
+
if (typeof allowed === 'string') {
|
|
5
|
+
return allowed === '*' || allowed === origin;
|
|
6
|
+
}
|
|
7
|
+
if (Array.isArray(allowed)) {
|
|
8
|
+
return allowed.includes(origin);
|
|
9
|
+
}
|
|
10
|
+
if (typeof allowed === 'function') {
|
|
11
|
+
return allowed(origin);
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
export function createCorsMiddleware(config) {
|
|
16
|
+
const { origin, credentials = true, methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], allowedHeaders = ['Content-Type', 'Authorization', 'X-Request-ID'], exposedHeaders = ['X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-RateLimit-Reset'], maxAge = 86400, } = config;
|
|
17
|
+
return (req, res, next) => {
|
|
18
|
+
const requestOrigin = req.headers.origin;
|
|
19
|
+
if (origin === '*' || (typeof origin === 'string' && origin === '*')) {
|
|
20
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
21
|
+
}
|
|
22
|
+
else if (isOriginAllowed(requestOrigin, origin)) {
|
|
23
|
+
res.setHeader('Access-Control-Allow-Origin', requestOrigin);
|
|
24
|
+
res.setHeader('Vary', 'Origin');
|
|
25
|
+
}
|
|
26
|
+
if (credentials) {
|
|
27
|
+
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
28
|
+
}
|
|
29
|
+
if (exposedHeaders.length > 0) {
|
|
30
|
+
res.setHeader('Access-Control-Expose-Headers', exposedHeaders.join(', '));
|
|
31
|
+
}
|
|
32
|
+
if (req.method === 'OPTIONS') {
|
|
33
|
+
res.setHeader('Access-Control-Allow-Methods', methods.join(', '));
|
|
34
|
+
res.setHeader('Access-Control-Allow-Headers', allowedHeaders.join(', '));
|
|
35
|
+
res.setHeader('Access-Control-Max-Age', maxAge.toString());
|
|
36
|
+
res.status(204).end();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
next();
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAGA,SAAS,eAAe,CACtB,MAA0B,EAC1B,OAA6B;IAE7B,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,MAAM,CAAC;IAC/C,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,MAAM,EACJ,MAAM,EACN,WAAW,GAAG,IAAI,EAClB,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,EAC9D,cAAc,GAAG,CAAC,cAAc,EAAE,eAAe,EAAE,cAAc,CAAC,EAClE,cAAc,GAAG,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,mBAAmB,CAAC,EACpF,MAAM,GAAG,KAAK,GACf,GAAG,MAAM,CAAC;IAEX,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAEzC,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,eAAe,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,aAAc,CAAC,CAAC;YAC7D,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,GAAG,CAAC,SAAS,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,SAAS,CAAC,+BAA+B,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAClE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
export declare function errorHandler(err: Error, _req: Request, res: Response, _next: NextFunction): void;
|
|
3
|
+
export declare function notFoundHandler(_req: Request, res: Response): void;
|
|
4
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,wBAAgB,YAAY,CAC1B,GAAG,EAAE,KAAK,EACV,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,IAAI,CAwBN;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAOlE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CogitatorError, ERROR_STATUS_CODES, ErrorCode } from '@cogitator-ai/types';
|
|
2
|
+
export function errorHandler(err, _req, res, _next) {
|
|
3
|
+
if (res.headersSent) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
if (CogitatorError.isCogitatorError(err)) {
|
|
7
|
+
const statusCode = ERROR_STATUS_CODES[err.code] || 500;
|
|
8
|
+
res.status(statusCode).json({
|
|
9
|
+
error: {
|
|
10
|
+
message: err.message,
|
|
11
|
+
code: err.code,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
console.error('[CogitatorServer] Unhandled error:', err);
|
|
17
|
+
res.status(500).json({
|
|
18
|
+
error: {
|
|
19
|
+
message: 'Internal server error',
|
|
20
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function notFoundHandler(_req, res) {
|
|
25
|
+
res.status(404).json({
|
|
26
|
+
error: {
|
|
27
|
+
message: 'Not found',
|
|
28
|
+
code: ErrorCode.AGENT_NOT_FOUND,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEpF,MAAM,UAAU,YAAY,CAC1B,GAAU,EACV,IAAa,EACb,GAAa,EACb,KAAmB;IAEnB,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAI,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QACvD,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE;gBACL,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;aACf;SACF,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;IAEzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,KAAK,EAAE;YACL,OAAO,EAAE,uBAAuB;YAChC,IAAI,EAAE,SAAS,CAAC,cAAc;SAC/B;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAa,EAAE,GAAa;IAC1D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,KAAK,EAAE;YACL,OAAO,EAAE,WAAW;YACpB,IAAI,EAAE,SAAS,CAAC,eAAe;SAChC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createAuthMiddleware } from './auth.js';
|
|
2
|
+
export { createRateLimitMiddleware } from './rate-limit.js';
|
|
3
|
+
export { createCorsMiddleware } from './cors.js';
|
|
4
|
+
export { errorHandler, notFoundHandler } from './error-handler.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Response, NextFunction } from 'express';
|
|
2
|
+
import type { RateLimitConfig, CogitatorRequest } from '../types.js';
|
|
3
|
+
export declare function createRateLimitMiddleware(config: RateLimitConfig): (req: CogitatorRequest, res: Response, next: NextFunction) => void;
|
|
4
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAW,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA4BrE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,IASvD,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAoCjE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const store = new Map();
|
|
2
|
+
function cleanupExpired() {
|
|
3
|
+
const now = Date.now();
|
|
4
|
+
for (const [key, entry] of store.entries()) {
|
|
5
|
+
if (entry.resetTime <= now) {
|
|
6
|
+
store.delete(key);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
setInterval(cleanupExpired, 60000);
|
|
11
|
+
function defaultKeyGenerator(req) {
|
|
12
|
+
const forwarded = req.headers['x-forwarded-for'];
|
|
13
|
+
if (typeof forwarded === 'string') {
|
|
14
|
+
return forwarded.split(',')[0].trim();
|
|
15
|
+
}
|
|
16
|
+
return req.ip || req.socket.remoteAddress || 'unknown';
|
|
17
|
+
}
|
|
18
|
+
export function createRateLimitMiddleware(config) {
|
|
19
|
+
const { windowMs, max, message = 'Too many requests, please try again later', keyGenerator = defaultKeyGenerator, skip, } = config;
|
|
20
|
+
return (req, res, next) => {
|
|
21
|
+
if (skip?.(req)) {
|
|
22
|
+
return next();
|
|
23
|
+
}
|
|
24
|
+
const key = keyGenerator(req);
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
let entry = store.get(key);
|
|
27
|
+
if (!entry || entry.resetTime <= now) {
|
|
28
|
+
entry = { count: 0, resetTime: now + windowMs };
|
|
29
|
+
store.set(key, entry);
|
|
30
|
+
}
|
|
31
|
+
entry.count++;
|
|
32
|
+
const remaining = Math.max(0, max - entry.count);
|
|
33
|
+
const resetSeconds = Math.ceil((entry.resetTime - now) / 1000);
|
|
34
|
+
res.setHeader('X-RateLimit-Limit', max.toString());
|
|
35
|
+
res.setHeader('X-RateLimit-Remaining', remaining.toString());
|
|
36
|
+
res.setHeader('X-RateLimit-Reset', resetSeconds.toString());
|
|
37
|
+
if (entry.count > max) {
|
|
38
|
+
res.setHeader('Retry-After', resetSeconds.toString());
|
|
39
|
+
res.status(429).json({
|
|
40
|
+
error: {
|
|
41
|
+
message,
|
|
42
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
next();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAQA,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEhD,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;YAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED,WAAW,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;AAEnC,SAAS,mBAAmB,CAAC,GAAY;IACvC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAuB;IAC/D,MAAM,EACJ,QAAQ,EACR,GAAG,EACH,OAAO,GAAG,2CAA2C,EACrD,YAAY,GAAG,mBAAmB,EAClC,IAAI,GACL,GAAG,MAAM,CAAC;IAEX,OAAO,CAAC,GAAqB,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAClE,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YAChB,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;YACrC,KAAK,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAC;YAChD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,KAAK,EAAE,CAAC;QAEd,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAE/D,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnD,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7D,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;QAE5D,IAAI,KAAK,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;YACtB,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;YACtD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE;oBACL,OAAO;oBACP,IAAI,EAAE,qBAAqB;iBAC5B;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,KAAK,EACV,YAAY,EAKb,MAAM,aAAa,CAAC;AAIrB,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CA8H3D"}
|