### Quick Start Agent with Add and Done Tools Source: https://github.com/browser-use/agent-sdk/blob/main/README.md A Python example demonstrating how to set up a basic agent using the BU Agent SDK. It defines 'add' and 'done' tools and then queries the agent to add two numbers. ```python 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()) ``` -------------------------------- ### Install BU Agent SDK Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Instructions for installing the BU Agent SDK using uv. This involves either synchronizing dependencies or adding the SDK package. ```bash uv sync ``` ```bash uv add bu-agent-sdk ``` -------------------------------- ### Quick Start Agent with Native Tool Calling (Python) Source: https://github.com/browser-use/agent-sdk/blob/main/bu_agent_sdk/agent/README.md Demonstrates how to initialize an Agent with a language model and tools, then query it. Requires the 'bu_agent_sdk' library. ```python 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?") ``` -------------------------------- ### Install bu-agent-sdk using uv Source: https://context7.com/browser-use/agent-sdk/llms.txt This snippet shows how to add the bu-agent-sdk package to your project using the 'uv' package manager. Ensure 'uv' is installed in your environment. ```bash uv add bu-agent-sdk ``` -------------------------------- ### Python Agent Core Loop with Tool Calling Source: https://context7.com/browser-use/agent-sdk/llms.txt Demonstrates the core agent loop using the `Agent` class. It shows how to define tools, initialize the agent with an LLM and tools, and perform queries. Includes examples of single-turn and multi-turn conversations, clearing history, and retrieving usage statistics. Requires `bu-agent-sdk` and an LLM provider like Anthropic. ```python import asyncio from bu_agent_sdk import Agent from bu_agent_sdk.agent import TaskComplete from bu_agent_sdk.llm import ChatAnthropic from bu_agent_sdk.tools import tool @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], system_prompt="You are a helpful math assistant.", max_iterations=200, tool_choice="auto", # "auto", "required", or "none" ) async def main(): # Single query result = await agent.query("What is 2 + 3?") print(result) # Output: "The sum of 2 + 3 is 5" # Multi-turn conversation (history preserved) await agent.query("My name is Alice") response = await agent.query("What's my name?") # Remembers "Alice" # Clear history to start fresh agent.clear_history() # Get usage statistics usage = await agent.get_usage() print(f"Tokens: {usage.total_tokens}, Cost: ${usage.total_cost:.4f}") asyncio.run(main()) ``` -------------------------------- ### Retrieve Token Usage Information (Python) Source: https://github.com/browser-use/agent-sdk/blob/main/bu_agent_sdk/agent/README.md Provides an example of how to retrieve and display the total token count and cost associated with agent interactions. Assumes an initialized 'agent' object. ```python usage = await agent.get_usage() print(f"Tokens: {usage.total_tokens}, Cost: ${usage.total_cost:.4f}") ``` -------------------------------- ### Python Sandboxed Coding Assistant with Filesystem Tools Source: https://context7.com/browser-use/agent-sdk/llms.txt Demonstrates dependency injection for a sandboxed coding assistant using the bu-agent-sdk. It includes tools for executing shell commands, reading/writing files, and finding files via glob patterns within a defined sandbox. The example utilizes asyncio for asynchronous operations and integrates with an LLM provider (Anthropic) for agent capabilities. ```python import asyncio import subprocess from dataclasses import dataclass from pathlib import Path from typing import Annotated from bu_agent_sdk import Agent from bu_agent_sdk.agent import FinalResponseEvent, ToolCallEvent, ToolResultEvent from bu_agent_sdk.llm import ChatAnthropic from bu_agent_sdk.tools import Depends, tool @dataclass class SandboxContext: root_dir: Path working_dir: Path def resolve_path(self, path: str) -> Path: resolved = (self.working_dir / path).resolve() resolved.relative_to(self.root_dir) # Raises if escapes sandbox return resolved def get_sandbox() -> SandboxContext: raise RuntimeError("Override via dependency_overrides") @tool("Execute shell command") async def bash( command: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)] ) -> str: result = subprocess.run( command, shell=True, capture_output=True, text=True, cwd=ctx.working_dir, timeout=30 ) return result.stdout + result.stderr or "(no output)" @tool("Read file contents") async def read( path: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)] ) -> str: file_path = ctx.resolve_path(path) lines = file_path.read_text().splitlines() return "\n".join(f"{i+1:4d} {line}" for i, line in enumerate(lines)) @tool("Write file contents") async def write( path: str, content: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)] ) -> str: file_path = ctx.resolve_path(path) file_path.parent.mkdir(parents=True, exist_ok=True) file_path.write_text(content) return f"Wrote {len(content)} bytes to {path}" @tool("Find files by glob pattern") async def glob( pattern: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)] ) -> str: matches = list(ctx.working_dir.glob(pattern)) files = [str(f.relative_to(ctx.root_dir)) for f in matches if f.is_file()] return "\n".join(files) or "No matches found" async def main(): # Create sandbox root = Path("./sandbox").resolve() root.mkdir(exist_ok=True) ctx = SandboxContext(root_dir=root, working_dir=root) agent = Agent( llm=ChatAnthropic(model="claude-sonnet-4-20250514"), tools=[bash, read, write, glob], system_prompt=f"Coding assistant. Working dir: {ctx.working_dir}", dependency_overrides={get_sandbox: lambda: ctx}, ) async for event in agent.query_stream("Create a hello.py that prints 'Hello!'"): match event: case ToolCallEvent(tool=name, args=args): print(f"[{name}] {args}") case ToolResultEvent(result=result): print(f" -> {result[:100]}") case FinalResponseEvent(content=text): print(f"\n{text}") asyncio.run(main()) ``` -------------------------------- ### Unified Interface for Multiple LLM Providers Source: https://context7.com/browser-use/agent-sdk/llms.txt Showcases the framework's unified interface for various LLM providers, all implementing the `BaseChatModel` protocol. Examples include OpenAI, Anthropic, Google Gemini, Azure OpenAI, and local models via Ollama. It also demonstrates direct LLM invocation without using the `Agent`. ```python from bu_agent_sdk.llm import ( ChatOpenAI, ChatAnthropic, ChatGoogle, ChatAzureOpenAI, ChatGroq, ChatOllama, ChatDeepSeek, ChatMistral, ) # OpenAI openai_llm = ChatOpenAI( model="gpt-4o", api_key="sk-...", # Or set OPENAI_API_KEY env var temperature=0.2, max_completion_tokens=4096, ) # Anthropic Claude anthropic_llm = ChatAnthropic( model="claude-sonnet-4-20250514", api_key="sk-ant-...", # Or set ANTHROPIC_API_KEY env var max_tokens=8192, temperature=None, # Use model default ) # Google Gemini google_llm = ChatGoogle( model="gemini-2.5-flash", api_key="...", # Or set GOOGLE_API_KEY env var temperature=0.5, thinking_budget=0, # Disable thinking for flash models ) # Azure OpenAI azure_llm = ChatAzureOpenAI( model="gpt-4o", api_key="...", azure_endpoint="https://your-resource.openai.azure.com", api_version="2024-02-15-preview", ) # Local models via Ollama ollama_llm = ChatOllama( model="llama3.2", base_url="http://localhost:11434", ) # Direct LLM invocation (without Agent) from bu_agent_sdk.llm import UserMessage, ToolDefinition response = await openai_llm.ainvoke( messages=[UserMessage(content="Hello!")], tools=[ ToolDefinition( name="greet", description="Greet someone", parameters={"type": "object", "properties": {"name": {"type": "string"}}} ) ], tool_choice="auto", ) print(response.content) if response.has_tool_calls: for tc in response.tool_calls: print(f"Tool call: {tc.function.name}({tc.function.arguments})") ``` -------------------------------- ### Python Tool Decorator for Automatic Schema Generation Source: https://context7.com/browser-use/agent-sdk/llms.txt Demonstrates the use of the `@tool` decorator to define tools from Python async functions. This decorator automatically generates JSON schemas from function signatures, type hints, and docstrings, enabling type-safe tool usage. Includes examples with basic types, optional parameters, and Literal types. ```python from typing import Literal from pydantic import BaseModel, Field from bu_agent_sdk.tools import tool # Simple tool with basic types @tool("Add two numbers together") async def add(a: int, b: int) -> int: """Add two integers. Args: a: First number to add b: Second number to add """ return a + b # Tool with optional parameters and Literal types @tool("Search the web with options") async def search( query: str, max_results: int = 10, sort_by: Literal["relevance", "date"] = "relevance", ) -> str: return f"Found {max_results} results for '{query}' sorted by {sort_by}" ``` -------------------------------- ### Dependency Injection with FastAPI-Style `Depends` and `Annotated` Source: https://context7.com/browser-use/agent-sdk/llms.txt Illustrates FastAPI-style dependency injection for shared resources like database connections. It shows how to define a shared resource (`Database`), a provider function (`get_database`), and tools that utilize these dependencies. Dependency overrides for testing are also demonstrated. ```python import asyncio from dataclasses import dataclass from typing import Annotated from bu_agent_sdk import Agent from bu_agent_sdk.llm import ChatOpenAI from bu_agent_sdk.tools import Depends, tool # Define a shared resource @dataclass class Database: users: dict[int, dict] def get_user(self, user_id: int) -> dict | None: return self.users.get(user_id) def list_users(self) -> list[dict]: return list(self.users.values()) # Dependency provider function def get_database() -> Database: return Database(users={ 1: {"id": 1, "name": "Alice", "role": "admin"}, 2: {"id": 2, "name": "Bob", "role": "user"}, }) # Tools using dependency injection @tool("Get a user by ID") async def get_user( user_id: int, db: Annotated[Database, Depends(get_database)] ) -> str: user = db.get_user(user_id) if user: return f"User: {user['name']} (Role: {user['role']})" return f"No user found with ID {user_id}" @tool("List all users") async def list_users(db: Annotated[Database, Depends(get_database)]) -> str: users = db.list_users() return "\n".join(f"- {u['name']} (ID: {u['id']})" for u in users) async def main(): # Use dependency overrides for testing or scoped contexts mock_db = Database(users={99: {"id": 99, "name": "Test", "role": "test"}}) agent = Agent( llm=ChatOpenAI(model="gpt-4o"), tools=[get_user, list_users], dependency_overrides={get_database: lambda: mock_db}, # Override the dependency ) result = await agent.query("List all users") print(result) asyncio.run(main()) ``` -------------------------------- ### Using Different LLM Providers Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Shows how to integrate various LLM providers (Anthropic, OpenAI, Google) with the BU Agent SDK in Python. All providers implement the same `BaseChatModel` interface. ```python from bu_agent_sdk.llm import ChatAnthropic, ChatOpenAI, ChatGoogle # All implement BaseChatModel agent = Agent(llm=ChatAnthropic(model="claude-sonnet-4-20250514"), tools=tools) agent = Agent(llm=ChatOpenAI(model="gpt-4o"), tools=tools) agent = Agent(llm=ChatGoogle(model="gemini-2.0-flash"), tools=tools) ``` -------------------------------- ### Define Tool with Pydantic Model Parameters (Python) Source: https://github.com/browser-use/agent-sdk/blob/main/bu_agent_sdk/agent/README.md Illustrates using Pydantic models to define structured parameters for tools, improving clarity and validation. Requires 'pydantic'. ```python 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}" ``` -------------------------------- ### Track Token Usage and Costs with BU Agent SDK Source: https://context7.com/browser-use/agent-sdk/llms.txt Demonstrates how to track token usage and calculate costs for LLM invocations using the BU Agent SDK. The `include_cost=True` flag enables cost calculation, and the `get_usage()` method provides detailed summaries of token counts and expenses, both overall and per model. ```python import asyncio from bu_agent_sdk import Agent from bu_agent_sdk.llm import ChatOpenAI from bu_agent_sdk.tools import tool @tool("Generate text") async def generate(prompt: str) -> str: return f"Generated content for: {prompt}" agent = Agent( llm=ChatOpenAI(model="gpt-4o"), tools=[generate], include_cost=True, # Enable cost calculation ) async def main(): await agent.query("Generate a short story") await agent.query("Now make it longer") # Get usage summary usage = await agent.get_usage() print(f"Total tokens: {usage.total_tokens}") print(f"Prompt tokens: {usage.total_prompt_tokens}") print(f"Completion tokens: {usage.total_completion_tokens}") print(f"Cached tokens: {usage.total_prompt_cached_tokens}") print(f"Total cost: ${usage.total_cost:.4f}") # Get per-model breakdown for model, stats in usage.by_model.items(): print(f"{model}: {stats.total_tokens} tokens, ${stats.cost:.4f}") asyncio.run(main()) ``` -------------------------------- ### Python Agent Streaming Events for Real-time Visibility Source: https://context7.com/browser-use/agent-sdk/llms.txt Illustrates how to use the `query_stream` method to receive real-time events during agent execution. This provides visibility into tool calls, results, and intermediate thinking steps. Requires `bu-agent-sdk` and an LLM provider like OpenAI. The `match` statement handles different event types. ```python import asyncio from bu_agent_sdk import Agent from bu_agent_sdk.agent import ( ToolCallEvent, ToolResultEvent, TextEvent, ThinkingEvent, FinalResponseEvent, StepStartEvent, StepCompleteEvent, ) from bu_agent_sdk.llm import ChatOpenAI from bu_agent_sdk.tools import tool @tool("Search the web") async def search(query: str) -> str: return f"Results for: {query}" agent = Agent( llm=ChatOpenAI(model="gpt-4o"), tools=[search], ) async def main(): async for event in agent.query_stream("Search for Python tutorials"): match event: case StepStartEvent(step_id=id, title=title, step_number=n): print(f"Step {n} started: {title}") case ToolCallEvent(tool=name, args=args, tool_call_id=id): print(f"Calling {name} with {args}") case ToolResultEvent(tool=name, result=result, is_error=error): status = "ERROR" if error else "OK" print(f"{name} [{status}]: {result[:100]}") case StepCompleteEvent(step_id=id, status=status, duration_ms=ms): print(f"Step completed: {status} ({ms:.0f}ms)") case TextEvent(content=text): print(f"Assistant: {text}") case ThinkingEvent(content=thinking): print(f"Thinking: {thinking[:80]}...") case FinalResponseEvent(content=text): print(f"Final: {text}") asyncio.run(main()) ``` -------------------------------- ### Dependency Injection for Shared Resources (Python) Source: https://github.com/browser-use/agent-sdk/blob/main/bu_agent_sdk/agent/README.md Demonstrates injecting shared resources like database connections into tools using Annotated and Depends. Requires 'bu_agent_sdk'. ```python from typing import Annotated from bu_agent_sdk.tools import Depends def get_db() -> Database: return Database() @tool("Query database") async def query(sql: str, db: Annotated[Database, Depends(get_db)]) -> str: return await db.execute(sql) ``` -------------------------------- ### Dependency Injection in Tools Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Demonstrates dependency injection in Python tools using `Annotated` and `Depends`. This allows for type-safe injection of services like a database connection into tool functions. ```python from typing import Annotated from bu_agent_sdk import Depends def get_db(): return Database() @tool("Query users") async def get_user(id: int, db: Annotated[Database, Depends(get_db)]) -> str: return await db.find(id) ``` -------------------------------- ### Define Tools with Pydantic Models and Ephemeral Settings Source: https://context7.com/browser-use/agent-sdk/llms.txt Demonstrates how to define tools using Pydantic models for complex parameters and how to configure tools as ephemeral to limit their output persistence. The `EmailParams` model defines the structure for email parameters, while the `get_browser_state` tool is set to keep only the last 3 outputs. ```python from pydantic import BaseModel, Field from typing import Literal from bu_agent_sdk.tools import tool class EmailParams(BaseModel): to: str = Field(description="Recipient email address") subject: str = Field(description="Email subject line") body: str = Field(description="Email body content") priority: Literal["low", "normal", "high"] = "normal" @tool("Send an email") async def send_email(params: EmailParams) -> str: return f"Email sent to {params.to} with subject: {params.subject}" # Ephemeral tool - output removed from context after N uses to save tokens @tool("Get browser state", ephemeral=3) # Keep last 3 outputs only async def get_browser_state() -> str: return "" ``` -------------------------------- ### Implement Done Tool Pattern for Task Completion Source: https://context7.com/browser-use/agent-sdk/llms.txt Illustrates the 'Done Tool Pattern' using the `TaskComplete` exception to explicitly signal task completion in autonomous agents. This pattern ensures the agent stops only when the `done()` tool is invoked, providing a summary of accomplishments. ```python import asyncio from bu_agent_sdk import Agent from bu_agent_sdk.agent import TaskComplete from bu_agent_sdk.llm import ChatAnthropic from bu_agent_sdk.tools import tool @tool("Search for information") async def search(query: str) -> str: return f"Found info about: {query}" @tool("Signal task completion") async def done(message: str) -> str: """Call this when the task is finished with a summary of what was accomplished.""" raise TaskComplete(message) # Autonomous mode - agent runs until done() is called agent = Agent( llm=ChatAnthropic(model="claude-sonnet-4-20250514"), tools=[search, done], require_done_tool=True, # Agent won't stop until done() is called ) async def main(): result = await agent.query("Research Python web frameworks and summarize findings") print(f"Task completed: {result}") asyncio.run(main()) ``` -------------------------------- ### Agent Completion with Done Tool Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Illustrates the 'Done Tool Pattern' in Python for explicitly signaling task completion. This prevents agents from finishing prematurely by requiring a dedicated 'done' tool call. ```python @tool("Signal completion") async def done(message: str) -> str: raise TaskComplete(message) agent = Agent( llm=llm, tools=[..., done], require_done_tool=True, # Autonomous mode ) ``` -------------------------------- ### Enable Context Compaction with BU Agent SDK Source: https://context7.com/browser-use/agent-sdk/llms.txt Demonstrates how to configure and use automatic context compaction in the BU Agent SDK to summarize conversation history. Compaction is enabled by default but can be customized with a threshold ratio and a custom summary prompt. It can also be disabled entirely. ```python import asyncio from bu_agent_sdk import Agent from bu_agent_sdk.agent.compaction import CompactionConfig from bu_agent_sdk.llm import ChatAnthropic from bu_agent_sdk.tools import tool @tool("Process data") async def process(data: str) -> str: return f"Processed: {data}" agent = Agent( llm=ChatAnthropic(model="claude-sonnet-4-20250514"), tools=[process], # Compaction is enabled by default (threshold_ratio=0.80) compaction=CompactionConfig( enabled=True, threshold_ratio=0.80, # Compact at 80% of context window # Custom summary prompt (optional) summary_prompt="Summarize the conversation so far...", ), ) # Or disable compaction entirely agent_no_compact = Agent( llm=ChatAnthropic(model="claude-sonnet-4-20250514"), tools=[process], compaction=CompactionConfig(enabled=False), ) async def main(): # Long-running task - compaction happens automatically for i in range(100): await agent.query(f"Process batch {i} of data") asyncio.run(main()) ``` -------------------------------- ### Python Sandboxed Coding Assistant with Agent SDK Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Implements a sandboxed coding assistant using Python and the Agent SDK. It defines a `SandboxContext` for managing file operations within a restricted directory and provides tools for executing shell commands, reading/writing files, and finding files using glob patterns. The assistant is configured with an Anthropic LLM and dependency injection for the sandbox context. ```python import asyncio import subprocess from dataclasses import dataclass from pathlib import Path from typing import Annotated from bu_agent_sdk import Agent from bu_agent_sdk.llm import ChatAnthropic from bu_agent_sdk.tools import Depends, tool @dataclass class SandboxContext: """All file operations restricted to root_dir.""" root_dir: Path working_dir: Path def resolve_path(self, path: str) -> Path: resolved = (self.working_dir / path).resolve() resolved.relative_to(self.root_dir) # Raises if escapes return resolved def get_sandbox() -> SandboxContext: raise RuntimeError("Override via dependency_overrides") @tool("Execute shell command") async def bash(command: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)]) -> str: result = subprocess.run(command, shell=True, capture_output=True, text=True, cwd=ctx.working_dir) return result.stdout + result.stderr or "(no output)" @tool("Read file contents") async def read(path: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)]) -> str: return ctx.resolve_path(path).read_text() @tool("Write file contents") async def write(path: str, content: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)]) -> str: ctx.resolve_path(path).write_text(content) return f"Wrote {len(content)} bytes" @tool("Find files by glob pattern") async def glob(pattern: str, ctx: Annotated[SandboxContext, Depends(get_sandbox)]) -> str: files = [str(f.relative_to(ctx.root_dir)) for f in ctx.working_dir.glob(pattern)] return "\n".join(files) or "No matches" @tool("Signal task completion") async def done(message: str) -> str: from bu_agent_sdk.agent import TaskComplete raise TaskComplete(message) async def main(): # Create sandbox root = Path("./sandbox") root.mkdir(exist_ok=True) ctx = SandboxContext(root_dir=root.resolve(), working_dir=root.resolve()) agent = Agent( llm=ChatAnthropic(model="claude-sonnet-4-20250514"), tools=[bash, read, write, glob, done], system_prompt=f"Coding assistant. Working dir: {ctx.working_dir}", dependency_overrides={get_sandbox: lambda: ctx}, ) print("Agent ready. Ctrl+C to exit.") while True: task = input("\n> ") async for event in agent.query_stream(task): if hasattr(event, "tool"): print(f" → {event.tool}") elif hasattr(event, "content") and event.content: print(f"\n{event.content}") asyncio.run(main()) ``` -------------------------------- ### Context Compaction Configuration Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Configures context compaction in Python for the BU Agent SDK. This feature automatically summarizes the conversation when it approaches context limits, using a specified threshold ratio. ```python from bu_agent_sdk.agent import CompactionConfig agent = Agent( llm=llm, tools=tools, compaction=CompactionConfig(threshold_ratio=0.80), ) ``` -------------------------------- ### Streaming Agent Events (Python) Source: https://github.com/browser-use/agent-sdk/blob/main/bu_agent_sdk/agent/README.md Shows how to stream agent events like tool calls, results, and final responses using an async iterator. This helps in observing the agent's execution flow. ```python 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}") ``` -------------------------------- ### Multi-turn Conversation Management (Python) Source: https://github.com/browser-use/agent-sdk/blob/main/bu_agent_sdk/agent/README.md Shows how the Agent SDK preserves conversation history across multiple queries and how to manually clear it. Assumes an initialized 'agent' object. ```python await agent.query("My name is Alice") await agent.query("What's my name?") # Remembers "Alice" agent.clear_history() # Reset ``` -------------------------------- ### Streaming Agent Events Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Shows how to stream events from an agent query in Python. This allows for real-time processing of `ToolCallEvent`, `ToolResultEvent`, and `FinalResponseEvent` as they occur. ```python 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}") case ToolResultEvent(tool=name, result=result): print(f"{name} -> {result[:50]}") case FinalResponseEvent(content=text): print(f"Done: {text}") ``` -------------------------------- ### Ephemeral Messages for Tool Outputs Source: https://github.com/browser-use/agent-sdk/blob/main/README.md Demonstrates the 'Ephemeral Messages' feature in Python, which limits the number of recent tool outputs stored in the context. This is useful for managing large outputs like browser states or screenshots. ```python @tool("Get browser state", ephemeral=3) # Keep last 3 only async def get_state() -> str: return massive_dom_and_screenshot ``` -------------------------------- ### Utilize Typed Message Classes in BU Agent SDK Source: https://context7.com/browser-use/agent-sdk/llms.txt Shows how to use the framework's typed message classes for constructing conversation history, including text, multi-modal, tool results, and developer messages. These classes help in managing and loading conversation history for resuming interactions. ```python from bu_agent_sdk.llm import ( UserMessage, SystemMessage, AssistantMessage, ToolMessage, DeveloperMessage, ContentText, ContentImage, ImageURL, ) # Text messages user_msg = UserMessage(content="Hello!") system_msg = SystemMessage(content="You are a helpful assistant.", cache=True) assistant_msg = AssistantMessage(content="Hi there!") # Multi-modal user message with image image_msg = UserMessage(content=[ ContentText(text="What's in this image?"), ContentImage(image_url=ImageURL( url="data:image/png;base64,iVBORw0KGgo...", media_type="image/png", detail="high", )), ]) # Tool result message tool_result = ToolMessage( tool_call_id="call_abc123", tool_name="search", content="Search results: Python is a programming language...", is_error=False, ) # Developer message (for OpenAI o1+ models) dev_msg = DeveloperMessage(content="Follow these guidelines...") # Load history to resume a conversation agent.load_history([system_msg, user_msg, assistant_msg]) response = await agent.query("Continue from where we left off") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.