Skip to content

Commit ac3bd43

Browse files
whoiskatrinthreepointone
authored andcommitted
first attempt
1 parent b2187b4 commit ac3bd43

File tree

11 files changed

+1841
-0
lines changed

11 files changed

+1841
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
OPENAI_API_KEY=your_openai_api_key_here
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# HTTP Reusable Chat Example
2+
3+
This example demonstrates the new HTTP-based reusable streams implementation for the Agents SDK. It drops WebSockets in favor of HTTP requests for better AI SDK compatibility and implements a "poke and pull" pattern for real-time updates.
4+
5+
## Key Features
6+
7+
- **HTTP-Only Communication**: No WebSocket dependencies, pure HTTP requests
8+
- **Resumable Streams**: Streams can be resumed from exact positions after interruption
9+
- **Message Persistence**: Full message history persistence following AI SDK patterns
10+
- **"Poke and Pull" Updates**: Real-time updates via HTTP polling instead of WebSockets
11+
- **Single Player Mode**: No broadcast functionality, focused on individual user experience
12+
- **AI SDK v5 Compatibility**: Full compatibility with AI SDK streaming patterns
13+
14+
## Architecture
15+
16+
### Server Side (`AIHttpChatAgent`)
17+
18+
- **HTTP Endpoints**:
19+
- `GET /messages` - Retrieve paginated message history
20+
- `POST /chat` - Send message and get streaming response
21+
- `GET /stream/{streamId}` - Resume interrupted stream
22+
- `POST /stream/{streamId}/cancel` - Cancel active stream
23+
- `GET /stream/{streamId}/status` - Get stream status
24+
- `DELETE /messages` - Clear message history
25+
26+
- **Stream Persistence**: Streams are persisted to SQLite with position tracking
27+
- **Automatic Cleanup**: Old completed streams are automatically cleaned up
28+
29+
### Client Side (`useAgentChatHttp`)
30+
31+
- **Polling-Based Updates**: Uses configurable polling interval for real-time updates
32+
- **Stream Management**: Track active streams with resume/cancel capabilities
33+
- **Backward Compatibility**: Drop-in replacement for existing `useAgentChat` usage
34+
35+
## Setup
36+
37+
1. Copy `.dev.vars.example` to `.dev.vars` and add your OpenAI API key:
38+
39+
```bash
40+
cp .dev.vars.example .dev.vars
41+
# Edit .dev.vars and add your OPENAI_API_KEY
42+
```
43+
44+
2. Install dependencies:
45+
46+
```bash
47+
npm install
48+
```
49+
50+
3. Start the development server:
51+
52+
```bash
53+
npm run dev
54+
```
55+
56+
4. Open your browser to `http://localhost:5175` to see the HTML client
57+
58+
## Testing Resumable Streams
59+
60+
1. Click "Test Long Story" to populate a message that will generate a long response
61+
2. Send the message and observe the streaming response
62+
3. Refresh the page during streaming to test resumption
63+
4. Use the stream controls to resume or cancel active streams
64+
65+
## Usage Patterns
66+
67+
### Basic HTTP Chat Agent
68+
69+
```typescript
70+
import { AIHttpChatAgent } from "agents/ai-chat-agent-http";
71+
72+
export class MyHttpChatAgent extends AIHttpChatAgent<Env> {
73+
async onChatMessage(onFinish, options) {
74+
const stream = createUIMessageStream({
75+
execute: async ({ writer }) => {
76+
const result = streamText({
77+
messages: convertToModelMessages(this.messages),
78+
model: openai("gpt-4o-mini"),
79+
onFinish
80+
});
81+
writer.merge(result.toUIMessageStream());
82+
}
83+
});
84+
return createUIMessageStreamResponse({ stream });
85+
}
86+
}
87+
```
88+
89+
### React Hook Usage
90+
91+
```typescript
92+
import { useAgentChatHttp } from "agents/use-agent-chat-http";
93+
94+
function ChatComponent() {
95+
const {
96+
messages,
97+
input,
98+
handleInputChange,
99+
handleSubmit,
100+
activeStreams,
101+
resumeStream,
102+
cancelStream,
103+
clearHistory
104+
} = useAgentChatHttp({
105+
agentUrl: "http://localhost:5175/MyHttpChatAgent/chat",
106+
pollingInterval: 2000, // Poll every 2 seconds
107+
enableResumableStreams: true
108+
});
109+
110+
return (
111+
<div>
112+
{/* Chat UI */}
113+
{activeStreams.map(stream => (
114+
<div key={stream.streamId}>
115+
Stream {stream.streamId}: {stream.completed ? 'Complete' : 'Active'}
116+
<button onClick={() => resumeStream(stream.streamId)}>Resume</button>
117+
<button onClick={() => cancelStream(stream.streamId)}>Cancel</button>
118+
</div>
119+
))}
120+
</div>
121+
);
122+
}
123+
```
124+
125+
## Benefits Over WebSocket Implementation
126+
127+
1. **Better AI SDK Compatibility**: Direct HTTP streaming aligns with AI SDK patterns
128+
2. **Simpler Deployment**: No WebSocket infrastructure requirements
129+
3. **Resumable Streams**: Built-in stream resumption capabilities
130+
4. **Stateless Scaling**: HTTP-based architecture scales better
131+
5. **Debugging**: Easier to debug HTTP requests vs WebSocket messages
132+
6. **Caching**: HTTP responses can be cached and optimized
133+
134+
## Limitations
135+
136+
- **Polling Overhead**: Real-time updates require periodic polling
137+
- **Latency**: Slight delay in updates compared to WebSocket push notifications
138+
- **Single Player**: No multi-user broadcast functionality (by design)
139+
140+
## Migration from WebSocket Implementation
141+
142+
The HTTP implementation is designed as a drop-in replacement:
143+
144+
```typescript
145+
// Before (WebSocket)
146+
import { useAgentChat } from "agents/ai-react";
147+
const chat = useAgentChat({ agent });
148+
149+
// After (HTTP)
150+
import { useAgentChatHttp } from "agents/use-agent-chat-http";
151+
const chat = useAgentChatHttp({
152+
agentUrl: "http://localhost:5175/MyAgent/chat",
153+
enableResumableStreams: true
154+
});
155+
```
156+
157+
The API surface is nearly identical, with additional stream management capabilities.

0 commit comments

Comments
 (0)