FAQ
Frequently asked questions about Lens OS SDK.
Answers to common questions about integrating and using Lens OS SDK.
General Questions
What's the difference between Lens OS SDK and using OpenAI API directly?
Lens OS SDK provides:
| Feature | OpenAI API | Lens OS SDK |
|---|---|---|
| Tool Calling | Manual implementation | Built-in support |
| Session Management | Manual implementation | Built-in support |
| SSE Streaming | Manual handling | Automatic |
| Multi-tenant Config | None | Console-managed |
| Rules System | None | Built-in support |
Which LLM providers are supported?
Any provider compatible with OpenAI API format:
- OpenAI (GPT-4o, GPT-4o-mini)
- Azure OpenAI
- DeepSeek
- Other OpenAI-compatible APIs
Where is my data sent?
Your data is sent to:
- Lens OS API (
osapi.ask-lens.ai): For config and session storage - LLM Provider: Based on your
LENS_MODEL_BASE_URLsetting
Your data is not sent anywhere else.
Integration Questions
Can I use this with non-Next.js projects?
Yes, but you need:
- Backend: Node.js compatible environment
- Frontend: React 18+
Express.js example
import express from "express";
import { createAgentHandler } from "@lens-os/sdk/server";
const app = express();
const handler = createAgentHandler({ /* config */ });
app.post("/api/chat", async (req, res) => {
const response = await handler.POST(req);
// Handle SSE response
});Can I use multiple tools simultaneously?
Yes, the Agent automatically decides whether to call multiple tools:
Multiple tools
// Define multiple tools
toolExecutors: {
product_search: { /* ... */ },
user_orders: { /* ... */ },
ai_page_generate: { /* ... */ },
}
// Agent will automatically choose based on user needs
// E.g., "Find TypeScript books and check my orders"
// → Will sequentially call product_search and user_ordersHow do I limit tool call count?
Use the maxTurns parameter:
Limit turns
createAgentHandler({
maxTurns: 5, // Max 5 tool calls
// ...
});Frontend Questions
How do I customize the chat UI?
useLensAgent only provides state and methods - UI is completely up to you:
Custom UI
const { messages, sendMessage, isLoading } = useLensAgent({ ... });
// Completely custom UI
return (
<YourCustomChatUI
messages={messages}
onSend={sendMessage}
loading={isLoading}
/>
);How do I handle network disconnections?
Retry mechanism
const { error, sendMessage } = useLensAgent({ ... });
const handleSend = async (message: string) => {
try {
await sendMessage(message);
} catch (err) {
// Show error + retry button
setShowRetry(true);
}
};Backend Questions
What if tool execution times out?
SDK default timeout is 30 seconds. For long operations:
Handle long operations
execute: async (params) => {
// 1. Return progress immediately
return {
success: true,
result: {
message: "Processing, estimated 1 minute...",
status: "processing",
taskId: "task-123",
},
};
// 2. Let user check status later
// "Is my task task-123 complete?"
}How do I log tool calls?
Logging
execute: async (params, context) => {
const startTime = Date.now();
console.log("[Tool] Started", {
tool: "product_search",
params,
userId: context?.userId,
sessionId: context?.sessionId,
});
try {
const result = await doWork(params);
console.log("[Tool] Completed", {
duration: Date.now() - startTime,
resultCount: result.length,
});
return { success: true, result };
} catch (err) {
console.error("[Tool] Failed", {
duration: Date.now() - startTime,
error: err.message,
});
return { success: false, error: err.message };
}
}Security Questions
Are API keys safe?
LENS_OS_API_KEY: Only used server-side, never exposed to frontendLENS_MODEL_API_KEY: Only used server-side
Frontend calls your API routes indirectly, never accessing these keys directly.
How do I prevent unauthorized access?
Add authentication
// chat/route.ts
import { auth } from "@/auth";
export async function POST(request: Request) {
const session = await auth();
if (!session?.user) {
return new Response("Unauthorized", { status: 401 });
}
// Continue processing...
}How do I implement rate limiting?
Simple rate limiting
const rateLimit = new Map<string, number[]>();
const LIMIT = 10; // 10 per minute
const WINDOW = 60000;
export async function POST(request: Request) {
const session = await auth();
const userId = session?.user?.id;
if (userId) {
const now = Date.now();
const userRequests = rateLimit.get(userId) || [];
const recentRequests = userRequests.filter(t => now - t < WINDOW);
if (recentRequests.length >= LIMIT) {
return new Response("Rate limit exceeded", { status: 429 });
}
rateLimit.set(userId, [...recentRequests, now]);
}
// Continue processing...
}Note
Need more help? Check the Troubleshooting guide or contact Lens OS support.