mirror of
https://github.com/browser-use/browser-use
synced 2026-05-06 17:52:15 +02:00
Reorder examples
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
# FastAPI Browser Agent Example
|
||||
|
||||
This example demonstrates how to create a web interface for controlling a Browser Agent using FastAPI.
|
||||
|
||||
## Requirements
|
||||
|
||||
```bash
|
||||
uv pip install fastapi uvicorn sse-starlette langchain-openai
|
||||
```
|
||||
|
||||
## Running the Example
|
||||
|
||||
1. Navigate to the fastapi example directory:
|
||||
```bash
|
||||
cd examples/fastapi
|
||||
```
|
||||
|
||||
2. Run the FastAPI application:
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
3. Open your web browser and navigate to `http://localhost:8000`
|
||||
|
||||
|
||||
## API Endpoints
|
||||
|
||||
- `GET /` - Serves the web interface
|
||||
- `POST /agent/run` - Creates and runs an agent with the specified task
|
||||
- `POST /agent/pause` - Pauses the current agent
|
||||
- `POST /agent/resume` - Resumes the paused agent
|
||||
- `POST /agent/stop` - Stops the current agent
|
||||
- `GET /agent/status` - Gets the current status of the agent
|
||||
- `GET /logs` - Server-sent events endpoint for real-time logs
|
||||
@@ -1,284 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from queue import Queue
|
||||
from threading import Lock
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import psutil
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from langchain_openai import ChatOpenAI
|
||||
from pydantic import BaseModel
|
||||
from sse_starlette.sse import EventSourceResponse
|
||||
|
||||
from browser_use import Agent
|
||||
|
||||
# Create logs directory if it doesn't exist
|
||||
LOGS_DIR = os.path.join(os.path.dirname(__file__), 'logs')
|
||||
os.makedirs(LOGS_DIR, exist_ok=True)
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Create a rotating file handler (10MB per file, keep 5 backup files)
|
||||
file_handler = RotatingFileHandler(
|
||||
os.path.join(LOGS_DIR, 'agent_manager.log'),
|
||||
maxBytes=10 * 1024 * 1024, # 10MB
|
||||
backupCount=5,
|
||||
encoding='utf-8',
|
||||
)
|
||||
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
# Create a separate file for agent-specific logs
|
||||
agent_file_handler = RotatingFileHandler(
|
||||
os.path.join(LOGS_DIR, 'agents.log'),
|
||||
maxBytes=10 * 1024 * 1024, # 10MB
|
||||
backupCount=5,
|
||||
encoding='utf-8',
|
||||
)
|
||||
agent_file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
||||
|
||||
# Create a queue for real-time log messages
|
||||
log_queue = Queue()
|
||||
log_lock = Lock()
|
||||
|
||||
|
||||
class LogHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
log_entry = self.format(record)
|
||||
with log_lock:
|
||||
log_queue.put(log_entry)
|
||||
|
||||
|
||||
# Add handlers to the browser_use logger
|
||||
browser_use_logger = logging.getLogger('browser_use')
|
||||
browser_use_logger.addHandler(LogHandler())
|
||||
browser_use_logger.addHandler(agent_file_handler)
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
# Enable CORS
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=['*'], # Allows all origins
|
||||
allow_credentials=True,
|
||||
allow_methods=['*'], # Allows all methods
|
||||
allow_headers=['*'], # Allows all headers
|
||||
)
|
||||
|
||||
# Create static directory if it doesn't exist
|
||||
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
|
||||
os.makedirs(STATIC_DIR, exist_ok=True)
|
||||
|
||||
# Serve static files
|
||||
app.mount('/static', StaticFiles(directory=STATIC_DIR), name='static')
|
||||
|
||||
|
||||
class TaskRequest(BaseModel):
|
||||
agent_id: str
|
||||
task: str
|
||||
|
||||
|
||||
class AgentManager:
|
||||
def __init__(self):
|
||||
self.agents: Dict[str, Dict[str, Any]] = {}
|
||||
self.max_agents = 40 # Increased to 100 agents
|
||||
self._lock = asyncio.Lock()
|
||||
self.process = psutil.Process()
|
||||
self.start_time = time.time()
|
||||
logger.info(f'AgentManager initialized with max_agents={self.max_agents}')
|
||||
|
||||
async def create_agent(self, agent_id: str, task: str):
|
||||
async with self._lock:
|
||||
if len(self.agents) >= self.max_agents:
|
||||
current_memory = self.process.memory_info().rss / 1024 / 1024 # MB
|
||||
logger.error(f'Max agents reached. Current memory usage: {current_memory:.2f}MB')
|
||||
raise ValueError(f'Maximum number of agents ({self.max_agents}) reached. Memory usage: {current_memory:.2f}MB')
|
||||
|
||||
if agent_id in self.agents:
|
||||
logger.warning(f'Agent {agent_id} already exists')
|
||||
raise ValueError(f'Agent {agent_id} already exists')
|
||||
|
||||
try:
|
||||
llm = ChatOpenAI(model='gpt-4o-mini')
|
||||
agent = {
|
||||
'instance': Agent(task=task, llm=llm),
|
||||
'task': task,
|
||||
'running': False,
|
||||
'created_at': time.time(),
|
||||
'last_active': time.time(),
|
||||
}
|
||||
self.agents[agent_id] = agent
|
||||
logger.info(f'Created agent {agent_id}. Total agents: {len(self.agents)}')
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to create agent {agent_id}: {str(e)}')
|
||||
raise
|
||||
|
||||
def get_system_stats(self) -> dict:
|
||||
stats = {
|
||||
'total_agents': len(self.agents),
|
||||
'memory_usage_mb': self.process.memory_info().rss / 1024 / 1024,
|
||||
'cpu_percent': self.process.cpu_percent(),
|
||||
'uptime_seconds': time.time() - self.start_time,
|
||||
'thread_count': self.process.num_threads(),
|
||||
}
|
||||
logger.info(f'System stats: {stats}')
|
||||
return stats
|
||||
|
||||
def get_agent(self, agent_id: str) -> Agent:
|
||||
if agent_id not in self.agents:
|
||||
raise ValueError(f'Agent {agent_id} not found')
|
||||
return self.agents[agent_id]['instance']
|
||||
|
||||
def get_agent_status(self, agent_id: str):
|
||||
if agent_id not in self.agents:
|
||||
return 'not_created'
|
||||
|
||||
agent_data = self.agents[agent_id]
|
||||
agent = agent_data['instance']
|
||||
|
||||
if agent._stopped:
|
||||
return 'stopped'
|
||||
elif agent._paused:
|
||||
return 'paused'
|
||||
elif agent_data['running']:
|
||||
return 'running'
|
||||
return 'ready'
|
||||
|
||||
def set_running(self, agent_id: str, value: bool):
|
||||
if agent_id in self.agents:
|
||||
self.agents[agent_id]['running'] = value
|
||||
|
||||
def list_agents(self):
|
||||
return {
|
||||
agent_id: {'task': data['task'], 'status': self.get_agent_status(agent_id)} for agent_id, data in self.agents.items()
|
||||
}
|
||||
|
||||
|
||||
# Create a singleton instance
|
||||
agent_manager = AgentManager()
|
||||
|
||||
|
||||
@app.get('/')
|
||||
async def read_root():
|
||||
return FileResponse(os.path.join(STATIC_DIR, 'index.html'))
|
||||
|
||||
|
||||
@app.post('/agent/run')
|
||||
async def run_agent(request: TaskRequest):
|
||||
try:
|
||||
start_time = time.time()
|
||||
if request.agent_id not in agent_manager.agents:
|
||||
await agent_manager.create_agent(request.agent_id, request.task)
|
||||
|
||||
agent = agent_manager.get_agent(request.agent_id)
|
||||
agent_manager.set_running(request.agent_id, True)
|
||||
|
||||
# Run in background task to not block
|
||||
task = asyncio.create_task(agent.run())
|
||||
|
||||
# Add completion callback for debugging
|
||||
def done_callback(future):
|
||||
try:
|
||||
future.result()
|
||||
except Exception as e:
|
||||
logger.error(f'Agent {request.agent_id} failed: {str(e)}')
|
||||
finally:
|
||||
agent_manager.set_running(request.agent_id, False)
|
||||
|
||||
task.add_done_callback(done_callback)
|
||||
|
||||
setup_time = time.time() - start_time
|
||||
return {
|
||||
'status': 'running',
|
||||
'agent_id': request.agent_id,
|
||||
'task': request.task,
|
||||
'setup_time_ms': setup_time * 1000,
|
||||
'total_agents': len(agent_manager.agents),
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f'Error running agent {request.agent_id}: {str(e)}')
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
|
||||
@app.get('/ping')
|
||||
async def ping():
|
||||
return {'status': 'ok'}
|
||||
|
||||
|
||||
@app.post('/agent/{agent_id}/pause')
|
||||
async def pause_agent(agent_id: str):
|
||||
try:
|
||||
agent = agent_manager.get_agent(agent_id)
|
||||
agent.pause()
|
||||
return {'status': 'paused', 'agent_id': agent_id}
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
|
||||
@app.post('/agent/{agent_id}/resume')
|
||||
async def resume_agent(agent_id: str):
|
||||
try:
|
||||
agent = agent_manager.get_agent(agent_id)
|
||||
agent.resume()
|
||||
return {'status': 'resumed', 'agent_id': agent_id}
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
|
||||
@app.post('/agent/{agent_id}/stop')
|
||||
async def stop_agent(agent_id: str):
|
||||
try:
|
||||
agent = agent_manager.get_agent(agent_id)
|
||||
agent.stop()
|
||||
agent_manager.set_running(agent_id, False)
|
||||
return {'status': 'stopped', 'agent_id': agent_id}
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
|
||||
@app.get('/agent/{agent_id}/status')
|
||||
async def get_agent_status(agent_id: str):
|
||||
try:
|
||||
status = agent_manager.get_agent_status(agent_id)
|
||||
task = agent_manager.agents[agent_id]['task'] if agent_id in agent_manager.agents else None
|
||||
return {'status': status, 'agent_id': agent_id, 'task': task}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
|
||||
@app.get('/agents')
|
||||
async def list_agents():
|
||||
return agent_manager.list_agents()
|
||||
|
||||
|
||||
@app.get('/logs')
|
||||
async def event_stream():
|
||||
async def generate():
|
||||
while True:
|
||||
if not log_queue.empty():
|
||||
with log_lock:
|
||||
while not log_queue.empty():
|
||||
log_entry = log_queue.get()
|
||||
yield {'event': 'log', 'data': log_entry}
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
return EventSourceResponse(generate())
|
||||
|
||||
|
||||
@app.get('/system/stats')
|
||||
async def get_system_stats():
|
||||
return agent_manager.get_system_stats()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(app, host='0.0.0.0', port=8000)
|
||||
@@ -1,224 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Browser Agent Controller</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background-color: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.control-panel {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
button {
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
button:disabled {
|
||||
background-color: #cccccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
button:hover:not(:disabled) {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
#status {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.status-running { background-color: #d4edda; color: #155724; }
|
||||
.status-paused { background-color: #fff3cd; color: #856404; }
|
||||
.status-stopped { background-color: #f8d7da; color: #721c24; }
|
||||
.status-not-created { background-color: #e2e3e5; color: #383d41; }
|
||||
.status-ready { background-color: #cce5ff; color: #004085; }
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
resize: vertical;
|
||||
}
|
||||
#logContainer {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ddd;
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.log-entry {
|
||||
margin: 2px 0;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
.button-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Browser Agent Controller</h1>
|
||||
|
||||
<div class="control-panel">
|
||||
<textarea id="taskInput" rows="3" placeholder="Enter your task here..."></textarea>
|
||||
<div class="button-group">
|
||||
<button id="runBtn" onclick="runAgent()">Run Agent</button>
|
||||
<button id="pauseBtn" onclick="pauseAgent()" disabled>Pause</button>
|
||||
<button id="resumeBtn" onclick="resumeAgent()" disabled>Resume</button>
|
||||
<button id="stopBtn" onclick="stopAgent()" disabled>Stop</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="status" class="status-not-created">
|
||||
Status: Not Created
|
||||
</div>
|
||||
|
||||
<div id="logContainer">
|
||||
<div id="logs"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let statusCheckInterval;
|
||||
let eventSource;
|
||||
|
||||
function setupLogging() {
|
||||
if (eventSource) {
|
||||
eventSource.close();
|
||||
}
|
||||
|
||||
eventSource = new EventSource('/logs');
|
||||
const logsDiv = document.getElementById('logs');
|
||||
|
||||
eventSource.addEventListener('log', function(event) {
|
||||
const logEntry = document.createElement('div');
|
||||
logEntry.className = 'log-entry';
|
||||
logEntry.textContent = event.data;
|
||||
logsDiv.appendChild(logEntry);
|
||||
logsDiv.scrollTop = logsDiv.scrollHeight;
|
||||
});
|
||||
|
||||
eventSource.onerror = function(error) {
|
||||
console.error('EventSource failed:', error);
|
||||
eventSource.close();
|
||||
setTimeout(setupLogging, 5000); // Try to reconnect after 5 seconds
|
||||
};
|
||||
}
|
||||
|
||||
async function runAgent() {
|
||||
const task = document.getElementById('taskInput').value;
|
||||
if (!task) {
|
||||
alert('Please enter a task');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/agent/run', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ task }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
startStatusCheck();
|
||||
document.getElementById('taskInput').disabled = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
alert('Failed to run agent');
|
||||
}
|
||||
}
|
||||
|
||||
async function pauseAgent() {
|
||||
try {
|
||||
await fetch('/agent/pause', { method: 'POST' });
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
alert('Failed to pause agent');
|
||||
}
|
||||
}
|
||||
|
||||
async function resumeAgent() {
|
||||
try {
|
||||
await fetch('/agent/resume', { method: 'POST' });
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
alert('Failed to resume agent');
|
||||
}
|
||||
}
|
||||
|
||||
async function stopAgent() {
|
||||
try {
|
||||
await fetch('/agent/stop', { method: 'POST' });
|
||||
document.getElementById('taskInput').disabled = false;
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
alert('Failed to stop agent');
|
||||
}
|
||||
}
|
||||
|
||||
async function checkStatus() {
|
||||
try {
|
||||
const response = await fetch('/agent/status');
|
||||
const data = await response.json();
|
||||
|
||||
const statusDiv = document.getElementById('status');
|
||||
statusDiv.className = `status-${data.status}`;
|
||||
statusDiv.textContent = `Status: ${data.status.charAt(0).toUpperCase() + data.status.slice(1)}`;
|
||||
|
||||
// Update buttons based on status
|
||||
document.getElementById('runBtn').disabled = data.status === 'running';
|
||||
document.getElementById('pauseBtn').disabled = data.status !== 'running';
|
||||
document.getElementById('resumeBtn').disabled = data.status !== 'paused';
|
||||
document.getElementById('stopBtn').disabled = data.status === 'stopped' || data.status === 'not_created';
|
||||
|
||||
if (data.task) {
|
||||
statusDiv.textContent += `\nTask: ${data.task}`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking status:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function startStatusCheck() {
|
||||
// Check status immediately
|
||||
checkStatus();
|
||||
// Then check every 2 seconds
|
||||
if (!statusCheckInterval) {
|
||||
statusCheckInterval = setInterval(checkStatus, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Initial setup
|
||||
setupLogging();
|
||||
checkStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,44 +0,0 @@
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
import aiohttp
|
||||
|
||||
|
||||
async def test_agent(session, agent_id, task):
|
||||
# Start agent
|
||||
async with session.post('http://localhost:8000/agent/run', json={'agent_id': f'agent_{agent_id}', 'task': task}) as response:
|
||||
print(f'Started agent_{agent_id}:', await response.json())
|
||||
|
||||
# Monitor status
|
||||
while True:
|
||||
async with session.get(f'http://localhost:8000/agent/{agent_id}/status') as response:
|
||||
status = (await response.json())['status']
|
||||
print(f'Agent {agent_id} status:', status)
|
||||
if status in ['stopped', 'error']:
|
||||
break
|
||||
await asyncio.sleep(2)
|
||||
|
||||
|
||||
async def main():
|
||||
tasks = [
|
||||
'Search for Python programming tutorials',
|
||||
'Find information about machine learning',
|
||||
'Look up web development resources',
|
||||
'Research data science tools',
|
||||
'Find AI programming examples',
|
||||
'Search for software testing methods',
|
||||
'Look up database optimization techniques',
|
||||
'Research cloud computing platforms',
|
||||
'Find cybersecurity best practices',
|
||||
'Search for DevOps tutorials',
|
||||
]
|
||||
tasks = tasks * 10
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
# Start 10 agents simultaneously
|
||||
agent_tasks = [test_agent(session, i, tasks[i]) for i in range(50)]
|
||||
await asyncio.gather(*agent_tasks)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
@@ -17,9 +17,7 @@ from browser_use.controller.service import Controller
|
||||
|
||||
def get_llm(provider: str):
|
||||
if provider == 'anthropic':
|
||||
return ChatAnthropic(
|
||||
model_name='claude-3-5-sonnet-20240620', timeout=25, stop=None, temperature=0.0
|
||||
)
|
||||
return ChatAnthropic(model_name='claude-3-5-sonnet-20240620', timeout=25, stop=None, temperature=0.0)
|
||||
elif provider == 'openai':
|
||||
return ChatOpenAI(model='gpt-4o', temperature=0.0)
|
||||
|
||||
@@ -27,6 +25,7 @@ def get_llm(provider: str):
|
||||
raise ValueError(f'Unsupported provider: {provider}')
|
||||
|
||||
|
||||
# NOTE: This example is to find your current user agent string to use it in the browser_context
|
||||
task = 'go to https://whatismyuseragent.com and find the current user agent string '
|
||||
|
||||
|
||||
@@ -54,18 +53,13 @@ browser = Browser(
|
||||
)
|
||||
)
|
||||
|
||||
browser_context = BrowserContext(
|
||||
config=BrowserContextConfig(
|
||||
user_agent="foobarfoo"
|
||||
),
|
||||
browser=browser
|
||||
)
|
||||
browser_context = BrowserContext(config=BrowserContextConfig(user_agent='foobarfoo'), browser=browser)
|
||||
|
||||
agent = Agent(
|
||||
task=args.query,
|
||||
llm=llm,
|
||||
controller=controller,
|
||||
# browser=browser,
|
||||
# browser=browser,
|
||||
browser_context=browser_context,
|
||||
use_vision=True,
|
||||
max_actions_per_step=1,
|
||||
@@ -34,7 +34,6 @@ async def done(params: DoneResult):
|
||||
result = ActionResult(is_done=True, extracted_content=params.model_dump_json())
|
||||
print(result)
|
||||
# NOTE: this is clearly wrong - to demonstrate the validator
|
||||
# return result
|
||||
return 'blablabla'
|
||||
|
||||
|
||||
@@ -55,9 +55,7 @@ class DiscordBot(commands.Bot):
|
||||
intents.members = True # Enable members intent for user info
|
||||
|
||||
# Initialize the bot with a command prefix and intents.
|
||||
super().__init__(
|
||||
command_prefix='!', intents=intents
|
||||
) # You may not need prefix, just here for flexibility
|
||||
super().__init__(command_prefix='!', intents=intents) # You may not need prefix, just here for flexibility
|
||||
|
||||
# self.tree = app_commands.CommandTree(self) # Initialize command tree for slash commands.
|
||||
|
||||
@@ -86,12 +84,8 @@ class DiscordBot(commands.Bot):
|
||||
print(f'Error sending start message: {e}')
|
||||
|
||||
try:
|
||||
agent_message = await self.run_agent(
|
||||
message.content.replace(f'{self.prefix} ', '').strip()
|
||||
)
|
||||
await message.channel.send(
|
||||
content=f'{agent_message}', reference=message, mention_author=True
|
||||
)
|
||||
agent_message = await self.run_agent(message.content.replace(f'{self.prefix} ', '').strip())
|
||||
await message.channel.send(content=f'{agent_message}', reference=message, mention_author=True)
|
||||
except Exception as e:
|
||||
await message.channel.send(
|
||||
content=f'Error during task execution: {str(e)}',
|
||||
|
||||
@@ -35,12 +35,12 @@ Five Steps to create and invite a Discord bot:
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from integrations.discord_api import DiscordBot
|
||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||
from pydantic import SecretStr
|
||||
|
||||
from browser_use import BrowserConfig
|
||||
from browser_use.agent.service import Agent
|
||||
from examples.integrations.discord_api import DiscordBot
|
||||
|
||||
load_dotenv()
|
||||
|
||||
25
examples/simple.py
Normal file
25
examples/simple.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import asyncio
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from browser_use import Agent
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Initialize the model
|
||||
llm = ChatOpenAI(
|
||||
model='gpt-4o',
|
||||
temperature=0.0,
|
||||
)
|
||||
|
||||
# Create agent with the model
|
||||
agent = Agent(task='Go to amazon.com and search for "laptop"', llm=llm)
|
||||
|
||||
|
||||
async def main():
|
||||
await agent.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
@@ -33,8 +33,13 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
# full screen mode
|
||||
controller = Controller()
|
||||
|
||||
# NOTE: This is the path to your cv file
|
||||
CV = Path.cwd() / 'cv_04_24.pdf'
|
||||
|
||||
if not CV.exists():
|
||||
raise FileNotFoundError(f'You need to set the path to your cv file in the CV variable. CV file not found at {CV}')
|
||||
|
||||
|
||||
class Job(BaseModel):
|
||||
title: str
|
||||
@@ -45,9 +50,7 @@ class Job(BaseModel):
|
||||
salary: Optional[str] = None
|
||||
|
||||
|
||||
@controller.action(
|
||||
'Save jobs to file - with a score how well it fits to my profile', param_model=Job
|
||||
)
|
||||
@controller.action('Save jobs to file - with a score how well it fits to my profile', param_model=Job)
|
||||
def save_jobs(job: Job):
|
||||
with open('jobs.csv', 'a', newline='') as f:
|
||||
writer = csv.writer(f)
|
||||
@@ -23,8 +23,8 @@ browser = Browser(
|
||||
# chrome_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
||||
)
|
||||
)
|
||||
|
||||
context = BrowserContext(browser=browser, config=BrowserContextConfig(cookies_file='twitter_cookies.txt'))
|
||||
file_path = os.path.join(os.path.dirname(__file__), 'twitter_cookies.txt')
|
||||
context = BrowserContext(browser=browser, config=BrowserContextConfig(cookies_file=file_path))
|
||||
|
||||
|
||||
async def run_search():
|
||||
Reference in New Issue
Block a user