useLensAgent Hook
Core React Hook for managing Agent conversation state
Overview
useLensAgent is the core React Hook provided by Lens OS SDK, offering complete Agent interaction functionality: sending messages, receiving streamed responses, managing conversation history, and more.
Basic Usage
Basic Example
import { useLensAgent } from "@lens-os/sdk/react";
function Chat() {
const {
messages,
isLoading,
sendMessage,
newSession,
} = useLensAgent({
endpoint: "/api/lens/agent/chat",
userId: "user-123",
});
return (
<div>
{messages.map((msg, i) => (
<div key={i}>{msg.content}</div>
))}
<button onClick={() => sendMessage("Hello!")}>
Send
</button>
</div>
);
}API Reference
Options
Options
interface UseLensAgentOptions {
// Required
endpoint: string; // Chat API path
// Optional
userId?: string; // User identifier (can be injected server-side)
onEvent?: (event: SSEEvent) => void; // Event callback
}| Parameter | Type | Required | Description |
|---|---|---|---|
endpoint | string | Yes | Chat API path, e.g. "/api/lens/agent/chat" |
userId | string | No | User identifier (can be injected server-side) |
onEvent | function | No | SSE event callback function |
Return Value
Return
interface UseLensAgentReturn {
// State
messages: Message[]; // Conversation messages
isLoading: boolean; // Is executing
isInitialized: boolean; // SDK initialized
sessionId: string; // Current Session ID
error: Error | null; // Last error
// Methods
sendMessage: (message: string, context?: MessageContext) => Promise<void>;
abort: () => void; // Cancel current execution
newSession: () => void; // Start new conversation
loadSession: (sessionId: string, messages: Message[]) => void;
}State
messages
Conversation message array, each message formatted as:
Message
interface Message {
role: "user" | "assistant" | "system" | "tool";
content: string | MessageContent[];
timestamp?: Date;
}isLoading
true when Agent is processing a message, useful for:
- Showing loading indicator
- Disabling send button
- Switching to stop button
sessionId
Unique identifier for the current conversation. A new ID is generated each time newSession() is called.
Methods
sendMessage
Send a message to the Agent:
sendMessage
// Basic usage
await sendMessage("Find TypeScript books for me");
// With context (for page capture)
await sendMessage("Click the search button", {
currentUrl: window.location.href,
pageState: {
url: "...",
title: "...",
markdown: "...",
screenshot: "...",
actionableElements: [...],
},
});abort
Cancel the current request:
abort
<button onClick={isLoading ? abort : handleSend}>
{isLoading ? "Stop" : "Send"}
</button>newSession
Start a new conversation, clearing current messages:
newSession
<button onClick={newSession}>New Chat</button>loadSession
Load a history conversation:
loadSession
const handleLoad = async (targetSessionId: string) => {
const res = await fetch(`/api/lens/agent/sessions/${targetSessionId}`);
const data = await res.json();
if (data.success) {
loadSession(targetSessionId, data.messages);
}
};Event Handling
Use onEvent callback to handle SSE events:
onEvent
const { messages } = useLensAgent({
endpoint: "/api/lens/agent/chat",
userId: "user-123",
onEvent: (event) => {
switch (event.type) {
case "tool_call":
console.log("Tool started:", event.name);
// Show Tool Card
break;
case "tool_result":
console.log("Tool completed:", event.name, event.result);
// Update Tool Card
break;
case "text":
console.log("Text:", event.content);
break;
case "error":
console.error("Error:", event.error);
break;
case "done":
console.log("Completed");
break;
}
},
});Event type descriptions:
tool_call: Agent starts executing a tool, use to show Tool Cardtool_result: Tool execution complete, use to update Tool Card statetext: Text content updateerror: Error occurreddone: Conversation round complete
Full Example
Here is a complete chat component example with all features:
Chat.tsx
"use client";
import { useState, useRef, useEffect } from "react";
import { useLensAgent } from "@lens-os/sdk/react";
export function Chat({ userId }: { userId: string }) {
const [input, setInput] = useState("");
const messagesEndRef = useRef<HTMLDivElement>(null);
const {
messages,
isLoading,
error,
sendMessage,
abort,
newSession,
} = useLensAgent({
endpoint: "/api/lens/agent/chat",
userId,
onEvent: (event) => {
if (event.type === "tool_call") {
console.log("Tool:", event.name);
}
},
});
// Auto scroll
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const handleSend = async () => {
if (!input.trim() || isLoading) return;
const message = input;
setInput("");
await sendMessage(message);
};
return (
<div className="flex flex-col h-full">
{/* Messages */}
<div className="flex-1 overflow-auto p-4 space-y-4">
{messages.map((msg, i) => (
<div
key={i}
className={msg.role === "user" ? "text-right" : "text-left"}
>
<span className={`inline-block p-3 rounded-lg ${
msg.role === "user" ? "bg-blue-500 text-white" : "bg-gray-100"
}`}>
{typeof msg.content === "string" ? msg.content : "..."}
</span>
</div>
))}
{isLoading && <div className="text-gray-500">Thinking...</div>}
{error && <div className="text-red-500">Error: {error.message}</div>}
<div ref={messagesEndRef} />
</div>
{/* Input */}
<div className="border-t p-4 flex gap-2">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleSend()}
placeholder="Type a message..."
className="flex-1 border rounded px-3 py-2"
/>
<button
onClick={isLoading ? abort : handleSend}
className="bg-blue-500 text-white px-4 py-2 rounded"
>
{isLoading ? "Stop" : "Send"}
</button>
<button
onClick={newSession}
className="border px-4 py-2 rounded"
>
New Chat
</button>
</div>
</div>
);
}Tip
This example shows basic chat functionality. For a more complete component (with Tool Cards, Rules menu), see the "Chat Component" docs.