Supported LLMs in Browser Use
mainThe bu-agent-sdk officially supports the following LLM providers:
- OpenAI
- Anthropic
- Groq
- Ollama
- DeepSeek
- Mistral
repository·main·Indexed 20 days ago
https://github.com/browser-use/agent-sdkA minimalist agent framework designed around a simple for-loop of tool calls. It provides a lightweight Agent class with native tool calling, support for multiple LLM providers (OpenAI, Anthropic, Google, Groq, Ollama, DeepSeek, Mistral), and features for context management including ephemeral messages and CompactionConfig. The SDK supports Pydantic models for tool parameters, FastAPI-style dependency injection via Depends, and real-time event streaming through agent.query_stream().
The bu-agent-sdk officially supports the following LLM providers:
The Agent preserves conversation history between consecutive .query() calls.
.query() multiple times.agent.clear_history() to wipe the conversation memory.await agent.query("My name is Alice")
await agent.query("What's my name?") # Remembers "Alice"
agent.clear_history() # ResetTo prevent agents from finishing prematurely, use the 'Done Tool Pattern'. Define a tool that raises TaskComplete and set require_done_tool=True in the Agent configuration. This forces the agent to use the explicit completion tool to finish.
@tool("Signal completion")
async def done(message: str) -> str:
raise TaskComplete(message)
agent = Agent(
llm=llm,
tools=[..., done],
require_done_tool=True, # Forces autonomous mode to use the done tool
)While not officially supported, you can use LangChain models by utilizing the ChatLangchain class. This is possible due to the underlying implementation of LLMs in the SDK.
For a concrete implementation pattern, refer to the LangChain example in the repository: /examples/models/langchain/example.py.
The Agent provides a simple agentic loop with native tool calling. To use it, initialize an Agent with an LLM (e.g., ChatOpenAI) and a list of functions decorated with @tool.
from bu_agent_sdk import Agent
from bu_agent_sdk.llm import ChatOpenAI
from bu_agent_sdk.tools import tool
@tool("Add two numbers")
async def add(a: int, b: int) -> int:
return a + b
agent = Agent(
llm=ChatOpenAI(model="gpt-4o"),
tools=[add],
)
result = await agent.query("What is 2 + 2?")You can install the bu-agent-sdk using uv:
uv syncOr add it to your project using:
uv add bu-agent-sdkuv add bu-agent-sdkTo create a basic agent, define asynchronous functions decorated with @tool and pass them along with an LLM provider to the Agent class. Use agent.query() to execute a task.
Note: To signal explicit task completion, raise a TaskComplete exception from within a tool.
import asyncio
from bu_agent_sdk import Agent, tool, TaskComplete
from bu_agent_sdk.llm import ChatAnthropic
@tool("Add two numbers")
async def add(a: int, b: int) -> int:
return a + b
@tool("Signal task completion")
async def done(message: str) -> str:
raise TaskComplete(message)
agent = Agent(
llm=ChatAnthropic(model="claude-sonnet-4-20250514"),
tools=[add, done],
)
async def main():
result = await agent.query("What is 2 + 3?")
print(result)
asyncio.run(main())Use CompactionConfig to automatically summarize conversation history when the context approaches its limit. Set the threshold_ratio to determine when compaction should trigger.
from bu_agent_sdk.agent import CompactionConfig
agent = Agent(
llm=llm,
tools=tools,
compaction=CompactionConfig(threshold_ratio=0.80),
)To group related parameters for a tool, pass a Pydantic BaseModel as a single argument to the tool function. This allows for structured and validated tool inputs.
from pydantic import BaseModel, Field
class EmailParams(BaseModel):
to: str = Field(description="Recipient")
subject: str
body: str
@tool("Send an email")
async def send_email(params: EmailParams) -> str:
return f"Sent to {params.to}"To use Mistral, use the ChatMistral class.
Configuration:
MISTRAL_API_KEY environment variable.MISTRAL_BASE_URL environment variable.Behavioral Notes:
minLength, maxLength, pattern, and format to ensure compatibility.max_tokens and supports an optional safe_prompt flag.Use agent.query_stream() to iterate over real-time events occurring during the agent's execution. You can use pattern matching to handle different event types:
ToolCallEvent: Triggered when the agent decides to call a tool. Contains tool (name) and args.ToolResultEvent: Triggered when a tool execution completes. Contains tool (name) and result.FinalResponseEvent: Triggered when the agent provides its final answer. Contains content (text).from bu_agent_sdk.agent import ToolCallEvent, ToolResultEvent, FinalResponseEvent
async for event in agent.query_stream("do something"):
match event:
case ToolCallEvent(tool=name, args=args):
print(f"Calling {name}: {args}")
case ToolResultEvent(tool=name, result=result):
print(f"{name} returned: {result}")
case FinalResponseEvent(content=text):
print(f"Done: {text}")To prevent large tool outputs (like browser states or screenshots) from consuming too much context, use the ephemeral parameter in the @tool decorator. This tells the agent to only keep the last N messages for that specific tool.
@tool("Get browser state", ephemeral=3) # Keep last 3 only
async def get_state() -> str:
return massive_dom_and_screenshot