Skip to content
This repository was archived by the owner on Mar 25, 2026. It is now read-only.

Commit 55d9697

Browse files
Update streaming docs (#304)
Update streaming docs based on latest SDK changes
1 parent 3f87389 commit 55d9697

3 files changed

Lines changed: 181 additions & 67 deletions

File tree

‎content/Guides/agent-streaming.mdx‎

Lines changed: 95 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,11 @@ Chain as many agents as you like; each one can inspect, transform, or just relay
188188

189189
## Low-Level Stream Control
190190

191-
For advanced use cases, you can use `context.stream.create()` to create and manage streams directly. This gives you fine-grained control over stream creation, data flow, and background processing.
191+
For advanced use cases, you can create and manage streams directly with `context.stream.create()`, giving you fine-grained control over stream creation, data flow, and background processing.
192192

193193
### Creating Streams with `context.stream.create`
194194

195-
The `context.stream.create()` method creates a named, writable stream that returns immediately, allowing for non-blocking operation and background data processing.
195+
This method returns a Promise that resolves to a named, writable stream. The stream is created immediately, enabling background data processing without blocking the response:
196196

197197
```ts
198198
import type { AgentRequest, AgentResponse, AgentContext } from "@agentuity/sdk";
@@ -206,14 +206,13 @@ export default async function Agent(
206206
) {
207207
const { prompt } = await req.data.json();
208208

209-
// Create a stream immediately - this returns right away
210-
const stream = ctx.stream.create('llm-response', {
209+
// Create a stream
210+
const stream = await ctx.stream.create('llm-response', {
211211
contentType: 'text/plain',
212212
metadata: {
213-
requestId: req.id,
213+
requestId: ctx.sessionId,
214214
type: 'llm-generation',
215-
model: 'gpt-4o',
216-
userId: req.headers.get('user-id')
215+
model: 'gpt-4o'
217216
}
218217
});
219218

@@ -239,15 +238,15 @@ export default async function Agent(
239238

240239
### Manual Stream Writing
241240

242-
You can also write to streams manually for complete control over the data flow:
241+
You can write to streams manually for complete control over the data flow. The Stream API provides a simple `write()` method that handles writer management automatically:
243242

244243
```ts
245244
export default async function Agent(
246245
req: AgentRequest,
247246
resp: AgentResponse,
248247
ctx: AgentContext,
249248
) {
250-
const stream = ctx.stream.create('progress-updates', {
249+
const stream = await ctx.stream.create('progress-updates', {
251250
contentType: 'application/json',
252251
metadata: { type: 'progress-tracking' }
253252
});
@@ -256,7 +255,7 @@ export default async function Agent(
256255
try {
257256
// Send progress updates
258257
const steps = ['Initializing', 'Processing', 'Analyzing', 'Finalizing'];
259-
258+
260259
for (let i = 0; i < steps.length; i++) {
261260
await stream.write(JSON.stringify({
262261
step: i + 1,
@@ -265,10 +264,13 @@ export default async function Agent(
265264
progress: ((i + 1) / steps.length) * 100,
266265
timestamp: new Date().toISOString()
267266
}) + '\n');
268-
267+
269268
// Simulate work
270269
await new Promise(resolve => setTimeout(resolve, 1000));
271270
}
271+
272+
// Track progress with bytesWritten
273+
ctx.logger.info(`Stream complete: ${stream.bytesWritten} bytes written`);
272274
} finally {
273275
await stream.close();
274276
}
@@ -281,6 +283,84 @@ export default async function Agent(
281283
}
282284
```
283285

286+
**Writing Patterns**
287+
288+
The Stream API supports two writing patterns:
289+
290+
- **`stream.write()`** - Simplified API that handles writer acquisition and locking automatically. Recommended for most use cases.
291+
- **`stream.getWriter()`** - Direct access to the underlying WritableStream writer for scenarios requiring precise control over the writer lifecycle (e.g., sharing a single writer across multiple operations or custom error handling).
292+
293+
**Tracking Stream Progress**
294+
295+
The `bytesWritten` property provides real-time visibility into stream progress:
296+
297+
```ts
298+
await stream.write(chunk1);
299+
ctx.logger.info(`Progress: ${stream.bytesWritten} bytes`); // e.g., "Progress: 1024 bytes"
300+
301+
await stream.write(chunk2);
302+
ctx.logger.info(`Progress: ${stream.bytesWritten} bytes`); // e.g., "Progress: 2048 bytes"
303+
```
304+
305+
### Stream Compression
306+
307+
Stream compression reduces bandwidth usage by automatically applying gzip encoding to outbound data (defaults to disabled):
308+
309+
```ts
310+
export default async function Agent(
311+
req: AgentRequest,
312+
resp: AgentResponse,
313+
ctx: AgentContext,
314+
) {
315+
const { dataset } = await req.data.json();
316+
317+
const stream = await ctx.stream.create('dataset-export', {
318+
contentType: 'application/json',
319+
compress: true, // Automatic gzip compression
320+
metadata: {
321+
type: 'data-export',
322+
recordCount: String(dataset.length),
323+
timestamp: String(Date.now())
324+
}
325+
});
326+
327+
ctx.waitUntil(async () => {
328+
try {
329+
for (const record of dataset) {
330+
await stream.write(JSON.stringify(record) + '\n');
331+
332+
// Log progress periodically
333+
if (stream.bytesWritten % 100000 < 1000) {
334+
ctx.logger.info(`Export progress: ${stream.bytesWritten} bytes written`);
335+
}
336+
}
337+
338+
ctx.logger.info(
339+
`Export complete: ${stream.bytesWritten} bytes (uncompressed), ` +
340+
`compression: ${stream.compressed ? 'enabled' : 'disabled'}`
341+
);
342+
} finally {
343+
await stream.close();
344+
}
345+
});
346+
347+
return resp.json({
348+
streamUrl: stream.url,
349+
compressed: stream.compressed,
350+
totalBytes: stream.bytesWritten
351+
});
352+
}
353+
```
354+
355+
**When to Use Compression**
356+
357+
Enable compression for highly compressible data formats:
358+
- JSON APIs and structured data streams
359+
- Text-based logs and documents
360+
- CSV files and tabular data
361+
362+
The `bytesWritten` property tracks uncompressed bytes, while clients receive gzip-encoded responses that are automatically decompressed by standard HTTP clients.
363+
284364
### Stream as Direct Response
285365

286366
You can return a stream directly from your agent handler, which will automatically redirect clients to the stream URL:
@@ -293,7 +373,7 @@ export default async function Agent(
293373
) {
294374
const { prompt } = await req.data.json();
295375

296-
const stream = ctx.stream.create('direct-stream', {
376+
const stream = await ctx.stream.create('direct-stream', {
297377
contentType: 'text/plain'
298378
});
299379

@@ -317,7 +397,9 @@ export default async function Agent(
317397
- **Rich Metadata**: Associate custom metadata with streams for tracking and debugging
318398
- **Direct Access**: Clients can access streams via direct URLs
319399
- **Flexible Content Types**: Support any content type (text, JSON, binary, etc.)
320-
- **Manual Control**: Write data chunks manually for complex streaming scenarios
400+
- **Direct Writing**: Use `stream.write()` for simple data writing without manual lock management
401+
- **Progress Monitoring**: Track bytes written in real-time with `stream.bytesWritten`
402+
- **Automatic Compression**: Enable optional compression to reduce bandwidth for compressible content
321403

322404
---
323405

0 commit comments

Comments
 (0)