Overview
Kernel is a platform that provides infrastructure for
running browser and computer using agents. You can run your browser agents on
Kernel to get top tier performance and developer experience. Kernel’s SDKs
are tightly integrated with Laminar, allowing you to trace your agents down
to the LLM calls and browser/computer actions.
Advantages of using Kernel
- Reliable infrastructure and quick computer startup times.
- Reusable sessions, cookies, browser history and more.
- Stealth mode for browser automation avoids blockers and CAPTCHAs.
- Framework agnostic automations – you can use any browser framework you want.
Prerequisites
- A Kernel account.
- A Laminar account or a self-hosted instance.
- API keys for both Kernel and Laminar set as
KERNEL_API_KEY and LMNR_PROJECT_API_KEY environment variables.
Getting Started
Installation
JavaScript/TypeScript
Python
npm install @lmnr-ai/lmnr @onkernel/sdk
Setting up API keys
- Signup on the Kernel dashboard.
- Create an API key during the onboarding process or in the API keys page.
- Store the API key in the
KERNEL_API_KEY environment variable.
- Create a Laminar project.
- Navigate to the project settings and create a new project API key.
export KERNEL_API_KEY=<your-kernel-api-key>
export LMNR_PROJECT_API_KEY=<your-laminar-project-api-key>
Running agents on Kernel
Browser Use
Laminar provides observability for Browser Use and Kernel, so if you host your Browser Use agents on Kernel,
you will get full observability of both the browser agent and the computer interactions.
Full guide on browser-use integration
import os
import asyncio
from lmnr import Laminar, observe
from browser_use import Agent, Browser, ChatGoogle
from kernel import Kernel
# Initialize Laminar
Laminar.initialize(project_api_key=os.environ["LMNR_PROJECT_API_KEY"])
@observe()
async def main():
# Initialize Kernel and create a browser
client = Kernel()
kernel_browser = client.browsers.create(
stealth=True,
viewport={'width': 1920, 'height': 1080},
)
print(f"Live view url: {kernel_browser.browser_live_view_url}")
# Configure Browser Use with Kernel's CDP URL
browser = Browser(
cdp_url=kernel_browser.cdp_ws_url,
headless=False,
window_size={'width': 1920, 'height': 1080},
viewport={'width': 1920, 'height': 1080},
device_scale_factor=1.0
)
# Initialize the model. Don't forget to set GOOGLE_API_KEY env variable.
llm = ChatGoogle(
model="gemini-2.5-flash",
)
# Create and run the agent with job extraction task
agent = Agent(
task="""
Go to duckduckgo.com and search for "browser agent observability".
""",
llm=llm,
browser_session=browser
)
result = await agent.run()
print(f"Job URLs found:\n{result.final_result()}")
# Delete the browser for those who left open the live view url
client.browsers.delete_by_id(kernel_browser.session_id)
asyncio.run(main())
# Flush traces to Laminar
Laminar.flush()
Playwright
You can use Laminar to trace your Playwright browser sessions hosted on Kernel.
JavaScript/TypeScript
Python
import { Laminar } from '@lmnr-ai/lmnr';
import Kernel from '@onkernel/sdk';
import { chromium } from 'playwright';
// Initialize Laminar with Playwright and Kernel instrumentations
Laminar.initialize({
instrumentModules: {
playwright: {
chromium
},
kernel: Kernel
}
});
// Initialize Kernel and create a cloud browser
const kernel = new Kernel();
const main = async () => {
const kernelBrowser = await kernel.browsers.create({
stealth: true,
});
console.log("Live view url:", kernelBrowser.browser_live_view_url);
// Connect Playwright to Kernel's browser via CDP
const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
// Use existing context and page or create a new one
const context = browser.contexts()[0] || (await browser.newContext());
const page = context.pages()[0] || (await context.newPage());
// Your automation code
await page.goto('https://www.duckduckgo.com/')
await page.waitForTimeout(2000)
await page.goto('https://www.github.com/trending');
// Wait for 2 seconds
await page.waitForTimeout(2000);
// Extract all trending repos
const trendingRepos = await page.locator("h2 a.Link").evaluateAll((repos) =>
repos.map((repo) => repo.textContent.trim().replace(/[\n\s]/g, ''))
);
console.log('Trending repos:', trendingRepos);
await page.waitForTimeout(2000);
// Clean up the browser and flush traces to Laminar
await browser.close();
await Laminar.flush();
// Delete the browser
await kernel.browsers.deleteByID(kernelBrowser.session_id);
}
main().catch(console.error);
Deploying Kernel apps and using Kernel’s Computer and Process APIs
When you use Kernel’s App platform
or use their Computer controls,
Laminar will trace the computer and process interactions.
In addition, you don’t have to observe your kernel app.actions and worry about manual trace flushing inside your Kernel apps.
Laminar will take care of trace lifecycle automatically.
As a result of the example below, you will see the following in the Laminar UI:
Example Kernel app with Laminar tracing
To deploy this example on Kernel, follow the steps in Kernel’s documentation.
JavaScript/TypeScript
Python
import { Laminar } from '@lmnr-ai/lmnr';
import { chromium } from 'playwright';
import { config } from 'dotenv';
import Kernel, { type KernelContext } from "@onkernel/sdk";
config();
Laminar.initialize({
instrumentModules: {
playwright: {
chromium,
},
kernel: Kernel,
}
});
const kernel = new Kernel();
const app = kernel.app('my-app-name');
app.action('my-action', async (ctx: KernelContext, payload) => {
const kernelBrowser = await kernel.browsers.create({
invocation_id: ctx.invocation_id,
});
const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
const context = browser.contexts[0] || (await browser.newContext());
const page = context.pages[0] || (await context.newPage());
// Your automation code
await page.goto('https://www.duckduckgo.com/')
await page.waitForTimeout(2000)
await page.goto('https://www.github.com/trending');
// Wait for 2 seconds
await page.waitForTimeout(2000);
// Extract all trending repos
const trendingRepos = await page.locator("h2 a.Link").evaluateAll((repos) =>
repos.map((repo) => repo.textContent.trim().replace(/[\n\s]/g, ''))
);
console.log('Trending repos:', trendingRepos);
await page.waitForTimeout(2000);
// Computer tool call
await kernel.browsers.computer.captureScreenshot(
kernelBrowser.session_id,
);
// Process tool call
await kernel.browsers.process.exec(
kernelBrowser.session_id,
{
command: 'ls',
args: ['-la'],
}
)
await browser.close();
await kernel.browsers.deleteByID(kernelBrowser.session_id);
});
Next steps