SSE 與事件
即時串流事件與 DOM 互動協議。
在 Agent 執行期間,伺服器透過 Server-Sent Events (SSE) 串流事件給客戶端。 本頁涵蓋所有事件類型、DOM 互動的 Action Request 協議,以及用於視覺理解的 Page State。
SSE 事件參考
SSEEvent 聯合型別
SSEEvent
type SSEEvent =
| SSETextEvent
| SSEToolCallEvent
| SSEToolResultEvent
| SSEActionRequestEvent
| SSEErrorEvent
| SSEDoneEvent;事件類型
- text — 串流文字 token。 欄位:
content: string - tool_call — Agent 正在呼叫工具。 欄位:
name: string、parameters: Record<string, any> - tool_result — 工具執行完成。 欄位:
name: string、result: ToolResult - action_request — 伺服器請求客戶端執行 DOM 動作。 欄位:
correlationId、action、parameters - error — 發生錯誤。 欄位:
error: string、fatal: boolean - done — Agent 執行完成。無欄位。
事件介面
介面
interface SSETextEvent {
type: 'text';
content: string;
}
interface SSEToolCallEvent {
type: 'tool_call';
name: string; // 工具名稱
parameters: Record<string, any>; // 工具參數
}
interface SSEToolResultEvent {
type: 'tool_result';
name: string; // 工具名稱
result: ToolResult; // { success, result?, error? }
}
interface SSEActionRequestEvent {
type: 'action_request';
correlationId: string; // 用於配對請求/結果的唯一 ID
action: string; // 'click', 'scroll', 'navigate' 等
parameters: Record<string, any>;
}
interface SSEErrorEvent {
type: 'error';
error: string;
fatal: boolean; // 若為 true,Agent 停止執行
}
interface SSEDoneEvent {
type: 'done';
}在 onEvent 中處理事件
事件處理
useLensAgent({
endpoint: '/api/agent/chat',
onEvent: (event) => {
switch (event.type) {
case 'text':
// 串流文字 — messages 狀態會自動更新
break;
case 'tool_call':
console.log(`呼叫工具: ${event.name}`, event.parameters);
// 顯示此工具的「載入中」UI
break;
case 'tool_result':
console.log(`工具結果: ${event.name}`, event.result);
// 更新工具卡片為「已完成」
break;
case 'action_request':
// 由 hook 自動處理(DOM 動作)
break;
case 'error':
console.error(event.error);
if (event.fatal) {
// Agent 已停止 — 向用戶顯示錯誤
}
break;
case 'done':
// Agent 完成 — 如需要可進行清理
break;
}
},
});Action Request 協議
當 Agent 需要與用戶的頁面互動(點擊按鈕、滾動、導航),會使用 Action Request 協議:
Action Request 流程
伺服器 客戶端
│ │
│── action_request (透過 SSE) ──────►│
│ { correlationId, action, params }│
│ │ 執行 DOM 動作
│ │ 擷取頁面狀態
│◄── POST /action-result ───────────│
│ { correlationId, result, │
│ pageState } │
│ │
│ (agent 迴圈繼續) │運作方式
- Agent 決定呼叫 DOM 工具(例如
click) - 伺服器透過 SSE 發送
action_request事件,附帶correlationId - 客戶端的
useLensAgenthook 接收事件後: 執行 DOM 動作、擷取最新頁面狀態,並將結果 POST 到 action-result 端點 - 伺服器接收結果,更新頁面 context,繼續 agent 迴圈
自訂動作處理器
預設情況下,hook 使用內建的 WebUseTool 處理 DOM 動作。你可以覆寫它:
自訂處理器
useLensAgent({
endpoint: '/api/agent/chat',
onActionRequest: async (action, params) => {
// 自訂 DOM 動作處理
if (action === 'click') {
const element = document.querySelector(params.selector);
element?.click();
return { success: true, result: '已點擊元素' };
}
return { success: false, error: `未知動作: ${action}` };
},
});頁面狀態與螢幕截圖
頁面狀態讓 Agent 能「看見」當前頁面,啟用視覺理解和 DOM 工具執行。
PageState 介面
PageState
interface PageState {
url: string;
title: string;
markdown: string; // 頁面內容轉換為 markdown
screenshot: string; // Base64 data URL
actionableElements: ActionableElement[];
timestamp: Date;
}
interface ActionableElement {
id: string;
type: 'button' | 'input' | 'link' | 'select' | 'textarea';
selector: string;
text?: string;
placeholder?: string;
description: string;
}提供頁面狀態
getPageState
useLensAgent({
endpoint: '/api/agent/chat',
getPageState: async () => {
// 此函式在以下時機被呼叫:
// 1. 每次 sendMessage 之前(傳送初始頁面 context)
// 2. 每次 action_request 之後(擷取更新後的狀態)
return {
url: window.location.href,
title: document.title,
markdown: extractPageMarkdown(), // 你的實作
screenshot: await captureScreenshot(), // 你的實作
actionableElements: findActionableElements(), // 你的實作
timestamp: new Date(),
};
},
});隨訊息傳送頁面狀態
sendMessage 搭配 pageState
await sendMessage('你在這個頁面上看到什麼?', {
pageState: {
url: window.location.href,
title: document.title,
markdown: '...',
screenshot: 'data:image/png;base64,...',
actionableElements: [],
timestamp: new Date(),
},
currentUrl: window.location.href,
});Note
useLensAgent hook 會自動處理 action request 和頁面狀態擷取。 你只需在希望 Agent 擁有視覺上下文時提供 getPageState。