add screencast (#67)
* docs * updates * Fix: The handleCopy function fails to handle errors from navigator.clipboard.writeText(), causing unhandled exceptions and misleading UI feedback when clipboard operations fail. Co-authored-by: ctate <chris@ctate.dev> * Fix: The benchmark file uses emojis (📊, 🚀, 🔨, 📈, 📋, ✅, ⏱️, ⚠) in console output, violating repository guidelines that forbid emojis in code and output. Co-authored-by: ctate <chris@ctate.dev> * Remove benchmark/run.ts from PR * screencast * update docs * address comments --------- Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
This commit is contained in:
@@ -479,6 +479,113 @@ This enables control of:
|
||||
- WebView2 applications
|
||||
- Any browser exposing a CDP endpoint
|
||||
|
||||
## Streaming (Browser Preview)
|
||||
|
||||
Stream the browser viewport via WebSocket for live preview or "pair browsing" where a human can watch and interact alongside an AI agent.
|
||||
|
||||
### Enable Streaming
|
||||
|
||||
Set the `AGENT_BROWSER_STREAM_PORT` environment variable:
|
||||
|
||||
```bash
|
||||
AGENT_BROWSER_STREAM_PORT=9223 agent-browser open example.com
|
||||
```
|
||||
|
||||
This starts a WebSocket server on the specified port that streams the browser viewport and accepts input events.
|
||||
|
||||
### WebSocket Protocol
|
||||
|
||||
Connect to `ws://localhost:9223` to receive frames and send input:
|
||||
|
||||
**Receive frames:**
|
||||
```json
|
||||
{
|
||||
"type": "frame",
|
||||
"data": "<base64-encoded-jpeg>",
|
||||
"metadata": {
|
||||
"deviceWidth": 1280,
|
||||
"deviceHeight": 720,
|
||||
"pageScaleFactor": 1,
|
||||
"offsetTop": 0,
|
||||
"scrollOffsetX": 0,
|
||||
"scrollOffsetY": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Send mouse events:**
|
||||
```json
|
||||
{
|
||||
"type": "input_mouse",
|
||||
"eventType": "mousePressed",
|
||||
"x": 100,
|
||||
"y": 200,
|
||||
"button": "left",
|
||||
"clickCount": 1
|
||||
}
|
||||
```
|
||||
|
||||
**Send keyboard events:**
|
||||
```json
|
||||
{
|
||||
"type": "input_keyboard",
|
||||
"eventType": "keyDown",
|
||||
"key": "Enter",
|
||||
"code": "Enter"
|
||||
}
|
||||
```
|
||||
|
||||
**Send touch events:**
|
||||
```json
|
||||
{
|
||||
"type": "input_touch",
|
||||
"eventType": "touchStart",
|
||||
"touchPoints": [{ "x": 100, "y": 200 }]
|
||||
}
|
||||
```
|
||||
|
||||
### Programmatic API
|
||||
|
||||
For advanced use, control streaming directly via the protocol:
|
||||
|
||||
```typescript
|
||||
import { BrowserManager } from 'agent-browser';
|
||||
|
||||
const browser = new BrowserManager();
|
||||
await browser.launch({ headless: true });
|
||||
await browser.navigate('https://example.com');
|
||||
|
||||
// Start screencast
|
||||
await browser.startScreencast((frame) => {
|
||||
// frame.data is base64-encoded image
|
||||
// frame.metadata contains viewport info
|
||||
console.log('Frame received:', frame.metadata.deviceWidth, 'x', frame.metadata.deviceHeight);
|
||||
}, {
|
||||
format: 'jpeg',
|
||||
quality: 80,
|
||||
maxWidth: 1280,
|
||||
maxHeight: 720,
|
||||
});
|
||||
|
||||
// Inject mouse events
|
||||
await browser.injectMouseEvent({
|
||||
type: 'mousePressed',
|
||||
x: 100,
|
||||
y: 200,
|
||||
button: 'left',
|
||||
});
|
||||
|
||||
// Inject keyboard events
|
||||
await browser.injectKeyboardEvent({
|
||||
type: 'keyDown',
|
||||
key: 'Enter',
|
||||
code: 'Enter',
|
||||
});
|
||||
|
||||
// Stop when done
|
||||
await browser.stopScreencast();
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
agent-browser uses a client-daemon architecture:
|
||||
|
||||
Reference in New Issue
Block a user