@jaypie/mcp 0.3.0 → 0.3.1
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/dist/index.js
CHANGED
|
@@ -1208,7 +1208,7 @@ async function purgeSQSQueue(options, logger = nullLogger) {
|
|
|
1208
1208
|
return executeAwsCommand("sqs", "purge-queue", ["--queue-url", options.queueUrl], { profile: options.profile, region: options.region }, logger);
|
|
1209
1209
|
}
|
|
1210
1210
|
|
|
1211
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.3.
|
|
1211
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.3.1#4e71c6ce"
|
|
1212
1212
|
;
|
|
1213
1213
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
1214
1214
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -106,7 +106,6 @@ For streaming responses (SSE, real-time updates), use `createLambdaStreamHandler
|
|
|
106
106
|
|
|
107
107
|
```typescript
|
|
108
108
|
import { JaypieExpressLambda, JaypieDistribution } from "@jaypie/constructs";
|
|
109
|
-
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
110
109
|
|
|
111
110
|
// Create Lambda (handler uses createLambdaStreamHandler internally)
|
|
112
111
|
const streamingApi = new JaypieExpressLambda(this, "StreamingApi", {
|
|
@@ -114,10 +113,10 @@ const streamingApi = new JaypieExpressLambda(this, "StreamingApi", {
|
|
|
114
113
|
handler: "index.handler",
|
|
115
114
|
});
|
|
116
115
|
|
|
117
|
-
// Use with CloudFront and
|
|
116
|
+
// Use with CloudFront and streaming enabled
|
|
118
117
|
new JaypieDistribution(this, "Distribution", {
|
|
119
118
|
handler: streamingApi,
|
|
120
|
-
|
|
119
|
+
streaming: true,
|
|
121
120
|
host: "api.example.com",
|
|
122
121
|
zone: "example.com",
|
|
123
122
|
});
|
|
@@ -135,13 +134,13 @@ const streamingLambda = new JaypieLambda(this, "StreamingFunction", {
|
|
|
135
134
|
|
|
136
135
|
const functionUrl = streamingLambda.addFunctionUrl({
|
|
137
136
|
authType: FunctionUrlAuthType.NONE,
|
|
138
|
-
invokeMode: InvokeMode.RESPONSE_STREAM,
|
|
137
|
+
invokeMode: InvokeMode.RESPONSE_STREAM, // Direct Function URL still uses InvokeMode
|
|
139
138
|
});
|
|
140
139
|
|
|
141
140
|
new cdk.CfnOutput(this, "StreamingUrl", { value: functionUrl.url });
|
|
142
141
|
```
|
|
143
142
|
|
|
144
|
-
Note: Streaming requires Lambda Function URLs (not API Gateway). `JaypieDistribution` uses Function URLs by default.
|
|
143
|
+
Note: Streaming requires Lambda Function URLs (not API Gateway). `JaypieDistribution` uses Function URLs by default and accepts `streaming: true` for a cleaner API.
|
|
145
144
|
|
|
146
145
|
### Stack Types
|
|
147
146
|
|
|
@@ -482,6 +482,14 @@ streamingLambda.addFunctionUrl({
|
|
|
482
482
|
authType: FunctionUrlAuthType.NONE, // or AWS_IAM for auth
|
|
483
483
|
invokeMode: InvokeMode.RESPONSE_STREAM,
|
|
484
484
|
});
|
|
485
|
+
|
|
486
|
+
// Or use JaypieDistribution with streaming: true for CloudFront integration
|
|
487
|
+
new JaypieDistribution(this, "Distribution", {
|
|
488
|
+
handler: streamingLambda,
|
|
489
|
+
streaming: true,
|
|
490
|
+
host: "api.example.com",
|
|
491
|
+
zone: "example.com",
|
|
492
|
+
});
|
|
485
493
|
```
|
|
486
494
|
|
|
487
495
|
### Error Handling in Streams
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Complete guide to streaming in Jaypie - Lambda, Express, and
|
|
2
|
+
description: Complete guide to streaming in Jaypie - Lambda, Express, SSE, and NLJSON patterns
|
|
3
3
|
globs: packages/express/**, packages/lambda/**, packages/aws/**
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -7,6 +7,23 @@ globs: packages/express/**, packages/lambda/**, packages/aws/**
|
|
|
7
7
|
|
|
8
8
|
Jaypie provides three distinct streaming patterns for different deployment scenarios. This guide explains when to use each approach and how to implement streaming correctly.
|
|
9
9
|
|
|
10
|
+
## Stream Formats
|
|
11
|
+
|
|
12
|
+
Jaypie supports two stream output formats:
|
|
13
|
+
|
|
14
|
+
| Format | Content-Type | Use Case |
|
|
15
|
+
|--------|--------------|----------|
|
|
16
|
+
| SSE (default) | `text/event-stream` | Browser EventSource, real-time UI updates |
|
|
17
|
+
| NLJSON | `application/x-ndjson` | Machine-to-machine, log processing |
|
|
18
|
+
|
|
19
|
+
### Format Comparison
|
|
20
|
+
|
|
21
|
+
| Aspect | SSE | NLJSON |
|
|
22
|
+
|--------|-----|--------|
|
|
23
|
+
| Data format | `event: <type>\ndata: {...}\n\n` | `{...}\n` |
|
|
24
|
+
| Error format | `event: error\ndata: {...}\n\n` | `{"error":{...}}\n` |
|
|
25
|
+
| Browser support | Native EventSource API | Requires manual parsing |
|
|
26
|
+
|
|
10
27
|
## Quick Reference
|
|
11
28
|
|
|
12
29
|
| Handler | Package | Express Required | Use Case |
|
|
@@ -31,8 +48,11 @@ All streaming utilities are exported from `@jaypie/aws` and re-exported through
|
|
|
31
48
|
| `createExpressStream(stream, res)` | Pipe async iterable to Express response with SSE headers |
|
|
32
49
|
| `JaypieStream` | Wrapper class with `.toLambda()` and `.toExpress()` methods |
|
|
33
50
|
| `createJaypieStream(source)` | Factory function for JaypieStream |
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
51
|
+
| `formatSse(chunk)` | Format a chunk as SSE event string |
|
|
52
|
+
| `formatNljson(chunk)` | Format a chunk as NLJSON string |
|
|
53
|
+
| `formatStreamError(errorBody, format)` | Format error based on stream format |
|
|
54
|
+
| `getContentTypeForFormat(format)` | Get content type for stream format |
|
|
55
|
+
| `streamToSse(stream)` | Convert async iterable to SSE-formatted strings |
|
|
36
56
|
|
|
37
57
|
### Types
|
|
38
58
|
|
|
@@ -40,8 +60,9 @@ All streaming utilities are exported from `@jaypie/aws` and re-exported through
|
|
|
40
60
|
import type {
|
|
41
61
|
ExpressStreamResponse,
|
|
42
62
|
LambdaStreamWriter,
|
|
43
|
-
|
|
63
|
+
SseEvent,
|
|
44
64
|
StreamChunk,
|
|
65
|
+
StreamFormat, // "sse" | "nljson"
|
|
45
66
|
} from "jaypie";
|
|
46
67
|
```
|
|
47
68
|
|
|
@@ -49,13 +70,16 @@ import type {
|
|
|
49
70
|
|
|
50
71
|
Use for pure Lambda functions without Express. Requires AWS Lambda Response Streaming via Function URL.
|
|
51
72
|
|
|
73
|
+
**Note:** `lambdaStreamHandler` automatically wraps with `awslambda.streamifyResponse()` in the Lambda runtime. You no longer need to wrap manually.
|
|
74
|
+
|
|
52
75
|
### Basic Usage
|
|
53
76
|
|
|
54
77
|
```typescript
|
|
55
78
|
import { lambdaStreamHandler } from "jaypie";
|
|
56
79
|
import type { StreamHandlerContext } from "@jaypie/lambda";
|
|
57
80
|
|
|
58
|
-
|
|
81
|
+
// Auto-wrapped with awslambda.streamifyResponse() in Lambda runtime
|
|
82
|
+
export const handler = lambdaStreamHandler(
|
|
59
83
|
async (event: unknown, context: StreamHandlerContext) => {
|
|
60
84
|
const { responseStream } = context;
|
|
61
85
|
|
|
@@ -70,13 +94,18 @@ const streamWorker = lambdaStreamHandler(
|
|
|
70
94
|
},
|
|
71
95
|
{
|
|
72
96
|
name: "streamWorker",
|
|
73
|
-
contentType: "text/event-stream",
|
|
74
97
|
}
|
|
75
98
|
);
|
|
99
|
+
```
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
### With Format Option
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// SSE format (default)
|
|
105
|
+
export const sseHandler = lambdaStreamHandler(myHandler, { format: "sse" });
|
|
106
|
+
|
|
107
|
+
// NLJSON format
|
|
108
|
+
export const nljsonHandler = lambdaStreamHandler(myHandler, { format: "nljson" });
|
|
80
109
|
```
|
|
81
110
|
|
|
82
111
|
### With LLM Streaming
|
|
@@ -89,7 +118,8 @@ interface PromptEvent {
|
|
|
89
118
|
prompt?: string;
|
|
90
119
|
}
|
|
91
120
|
|
|
92
|
-
|
|
121
|
+
// Auto-wrapped with awslambda.streamifyResponse() in Lambda runtime
|
|
122
|
+
export const handler = lambdaStreamHandler(
|
|
93
123
|
async (event: PromptEvent, context: StreamHandlerContext) => {
|
|
94
124
|
const llm = new Llm("anthropic");
|
|
95
125
|
const stream = llm.stream(event.prompt || "Hello");
|
|
@@ -102,25 +132,23 @@ const llmStreamHandler = lambdaStreamHandler(
|
|
|
102
132
|
secrets: ["ANTHROPIC_API_KEY"],
|
|
103
133
|
}
|
|
104
134
|
);
|
|
105
|
-
|
|
106
|
-
declare const awslambda: { streamifyResponse: <T>(handler: T) => T };
|
|
107
|
-
export const handler = awslambda.streamifyResponse(llmStreamHandler);
|
|
108
135
|
```
|
|
109
136
|
|
|
110
137
|
### Handler Options
|
|
111
138
|
|
|
112
139
|
```typescript
|
|
113
|
-
import type { LambdaStreamHandlerOptions } from "@jaypie/lambda";
|
|
140
|
+
import type { LambdaStreamHandlerOptions, StreamFormat } from "@jaypie/lambda";
|
|
114
141
|
|
|
115
142
|
const options: LambdaStreamHandlerOptions = {
|
|
116
143
|
name: "myStreamHandler", // Handler name for logging
|
|
117
|
-
|
|
144
|
+
format: "sse", // Stream format: "sse" (default) or "nljson"
|
|
145
|
+
contentType: "text/event-stream", // Response content type (auto-set from format)
|
|
118
146
|
chaos: "low", // Chaos testing level
|
|
119
147
|
secrets: ["API_KEY"], // AWS secrets to load into process.env
|
|
120
148
|
setup: [], // Setup function(s)
|
|
121
149
|
teardown: [], // Teardown function(s)
|
|
122
150
|
validate: [], // Validation function(s)
|
|
123
|
-
throw: false, // Re-throw errors instead of
|
|
151
|
+
throw: false, // Re-throw errors instead of streaming error
|
|
124
152
|
unavailable: false, // Return 503 if true
|
|
125
153
|
};
|
|
126
154
|
```
|
|
@@ -137,11 +165,19 @@ const streamingLambda = new JaypieLambda(this, "StreamingFunction", {
|
|
|
137
165
|
timeout: Duration.minutes(5),
|
|
138
166
|
});
|
|
139
167
|
|
|
140
|
-
//
|
|
168
|
+
// For direct Function URL access:
|
|
141
169
|
streamingLambda.addFunctionUrl({
|
|
142
170
|
authType: FunctionUrlAuthType.NONE,
|
|
143
171
|
invokeMode: InvokeMode.RESPONSE_STREAM,
|
|
144
172
|
});
|
|
173
|
+
|
|
174
|
+
// Or use JaypieDistribution with streaming: true
|
|
175
|
+
new JaypieDistribution(this, "Distribution", {
|
|
176
|
+
handler: streamingLambda,
|
|
177
|
+
streaming: true,
|
|
178
|
+
host: "api.example.com",
|
|
179
|
+
zone: "example.com",
|
|
180
|
+
});
|
|
145
181
|
```
|
|
146
182
|
|
|
147
183
|
## Pattern 2: expressStreamHandler
|
|
@@ -180,14 +216,25 @@ const llmStreamRoute = expressStreamHandler(async (req: Request, res: Response)
|
|
|
180
216
|
app.post("/chat", llmStreamRoute);
|
|
181
217
|
```
|
|
182
218
|
|
|
219
|
+
### With Format Option
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// SSE format (default)
|
|
223
|
+
app.get("/stream-sse", expressStreamHandler(myHandler, { format: "sse" }));
|
|
224
|
+
|
|
225
|
+
// NLJSON format
|
|
226
|
+
app.get("/stream-nljson", expressStreamHandler(myHandler, { format: "nljson" }));
|
|
227
|
+
```
|
|
228
|
+
|
|
183
229
|
### Handler Options
|
|
184
230
|
|
|
185
231
|
```typescript
|
|
186
|
-
import type { ExpressStreamHandlerOptions } from "jaypie";
|
|
232
|
+
import type { ExpressStreamHandlerOptions, StreamFormat } from "jaypie";
|
|
187
233
|
|
|
188
234
|
const options: ExpressStreamHandlerOptions = {
|
|
189
235
|
name: "myStreamHandler", // Handler name for logging
|
|
190
|
-
|
|
236
|
+
format: "sse", // Stream format: "sse" (default) or "nljson"
|
|
237
|
+
contentType: "text/event-stream", // Response content type (auto-set from format)
|
|
191
238
|
chaos: "low", // Chaos testing level
|
|
192
239
|
secrets: ["API_KEY"], // Secrets to load
|
|
193
240
|
setup: [], // Setup function(s)
|
|
@@ -296,17 +343,17 @@ for await (const sseEvent of stream.toSSE()) {
|
|
|
296
343
|
### Manual SSE Formatting
|
|
297
344
|
|
|
298
345
|
```typescript
|
|
299
|
-
import {
|
|
346
|
+
import { formatSse } from "jaypie";
|
|
300
347
|
|
|
301
348
|
const chunk = { type: "message", content: "Hello" };
|
|
302
|
-
const sseString =
|
|
349
|
+
const sseString = formatSse(chunk);
|
|
303
350
|
// "event: message\ndata: {\"type\":\"message\",\"content\":\"Hello\"}\n\n"
|
|
304
351
|
```
|
|
305
352
|
|
|
306
353
|
### Converting Async Iterables
|
|
307
354
|
|
|
308
355
|
```typescript
|
|
309
|
-
import {
|
|
356
|
+
import { streamToSse } from "jaypie";
|
|
310
357
|
|
|
311
358
|
async function* myGenerator() {
|
|
312
359
|
yield { type: "start", data: {} };
|
|
@@ -314,28 +361,36 @@ async function* myGenerator() {
|
|
|
314
361
|
yield { type: "end", data: {} };
|
|
315
362
|
}
|
|
316
363
|
|
|
317
|
-
for await (const sseEvent of
|
|
364
|
+
for await (const sseEvent of streamToSse(myGenerator())) {
|
|
318
365
|
responseStream.write(sseEvent);
|
|
319
366
|
}
|
|
320
367
|
```
|
|
321
368
|
|
|
322
369
|
## Error Handling
|
|
323
370
|
|
|
324
|
-
Errors in streaming handlers are written
|
|
371
|
+
Errors in streaming handlers are written to the stream in the configured format:
|
|
372
|
+
|
|
373
|
+
**SSE format (default):**
|
|
374
|
+
```
|
|
375
|
+
event: error
|
|
376
|
+
data: {"errors":[{"status":500,"title":"Internal Error"}]}
|
|
325
377
|
|
|
326
|
-
```
|
|
327
|
-
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**NLJSON format:**
|
|
381
|
+
```
|
|
382
|
+
{"error":{"errors":[{"status":500,"title":"Internal Error"}]}}
|
|
328
383
|
```
|
|
329
384
|
|
|
330
385
|
For `lambdaStreamHandler`, set `throw: true` to re-throw errors instead of writing to stream:
|
|
331
386
|
|
|
332
387
|
```typescript
|
|
333
|
-
const handler = lambdaStreamHandler(
|
|
388
|
+
export const handler = lambdaStreamHandler(
|
|
334
389
|
async (event, context) => {
|
|
335
390
|
throw new InternalError("Something went wrong");
|
|
336
391
|
},
|
|
337
392
|
{
|
|
338
|
-
throw: true, // Re-throw instead of
|
|
393
|
+
throw: true, // Re-throw instead of streaming error
|
|
339
394
|
}
|
|
340
395
|
);
|
|
341
396
|
```
|
|
@@ -383,10 +438,13 @@ Use the Docker setup in `packages/express/docker/` for local Lambda streaming te
|
|
|
383
438
|
```typescript
|
|
384
439
|
// From @jaypie/lambda
|
|
385
440
|
import type {
|
|
441
|
+
AwsStreamingHandler,
|
|
442
|
+
LambdaHandler, // Wrapped handler type (after awslambda.streamifyResponse)
|
|
386
443
|
LambdaStreamHandlerOptions,
|
|
387
|
-
|
|
444
|
+
RawStreamingHandler, // Alias for AwsStreamingHandler (for testing)
|
|
388
445
|
ResponseStream,
|
|
389
|
-
|
|
446
|
+
StreamFormat, // "sse" | "nljson" (re-exported from @jaypie/aws)
|
|
447
|
+
StreamHandlerContext,
|
|
390
448
|
} from "@jaypie/lambda";
|
|
391
449
|
|
|
392
450
|
// From @jaypie/express (or jaypie)
|
|
@@ -402,7 +460,8 @@ import type {
|
|
|
402
460
|
import type {
|
|
403
461
|
ExpressStreamResponse,
|
|
404
462
|
LambdaStreamWriter,
|
|
405
|
-
|
|
463
|
+
SseEvent,
|
|
406
464
|
StreamChunk,
|
|
465
|
+
StreamFormat, // "sse" | "nljson"
|
|
407
466
|
} from "jaypie";
|
|
408
467
|
```
|