mirror of https://github.com/kortix-ai/suna.git
fix new page opening in browser; latest container wip
This commit is contained in:
parent
0b51c6507c
commit
fead1c831b
17
README.md
17
README.md
|
@ -88,7 +88,7 @@ You'll need the following components:
|
|||
- Redis database for caching and session management
|
||||
- Daytona sandbox for secure agent execution
|
||||
- Python 3.11 for the API backend
|
||||
- API keys for LLM providers (Anthropic)
|
||||
- API keys for LLM providers (Anthropic, OpenRouter)
|
||||
- Tavily API key for enhanced search capabilities
|
||||
- Firecrawl API key for web scraping capabilities
|
||||
|
||||
|
@ -99,23 +99,16 @@ You'll need the following components:
|
|||
- Save your project's API URL, anon key, and service role key for later use
|
||||
- Install the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started)
|
||||
|
||||
2. **Redis**: Set up a Redis instance using one of these options:
|
||||
- [Upstash Redis](https://upstash.com/) (recommended for cloud deployments)
|
||||
- Local installation:
|
||||
- [Mac](https://formulae.brew.sh/formula/redis): `brew install redis`
|
||||
- [Linux](https://redis.io/docs/getting-started/installation/install-redis-on-linux/): Follow distribution-specific instructions
|
||||
- [Windows](https://redis.io/docs/getting-started/installation/install-redis-on-windows/): Use WSL2 or Docker
|
||||
- Docker Compose (included in our setup):
|
||||
- If you're using our Docker Compose setup, Redis is included and configured automatically
|
||||
- No additional installation is needed
|
||||
- Save your Redis connection details for later use (not needed if using Docker Compose)
|
||||
2. **Redis**:
|
||||
- Go to the `/backend` folder
|
||||
- Run `docker compose up redis`
|
||||
|
||||
3. **Daytona**:
|
||||
- Create an account on [Daytona](https://app.daytona.io/)
|
||||
- Generate an API key from your account settings
|
||||
- Go to [Images](https://app.daytona.io/dashboard/images)
|
||||
- Click "Add Image"
|
||||
- Enter `adamcohenhillel/kortix-suna:0.0.20` as the image name
|
||||
- Enter `kortix/suna:0.1` as the image name
|
||||
- Set `/usr/bin/supervisord -n -c /etc/supervisor/conf.d/supervisord.conf` as the Entrypoint
|
||||
|
||||
4. **LLM API Keys**:
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# Agent Sandbox
|
||||
|
||||
This directory contains the agent sandbox implementation - a Docker-based virtual environment that agents use as their own computer to execute tasks, access the web, and manipulate files.
|
||||
|
||||
## Overview
|
||||
|
||||
The sandbox provides a complete containerized Linux environment with:
|
||||
- Chrome browser for web interactions
|
||||
- VNC server for accessing the Web User
|
||||
- Web server for serving content (port 8080) -> loading html files from the /workspace directory
|
||||
- Full file system access
|
||||
- Full sudo access
|
||||
|
||||
## Customizing the Sandbox
|
||||
|
||||
You can modify the sandbox environment for development or to add new capabilities:
|
||||
|
||||
1. Edit files in the `docker/` directory
|
||||
2. Build a custom image:
|
||||
```
|
||||
cd backend/sandbox/docker
|
||||
docker-compose build
|
||||
```
|
||||
3. Test your changes locally using docker-compose
|
||||
|
||||
## Using a Custom Image
|
||||
|
||||
To use your custom sandbox image:
|
||||
|
||||
1. Change the `image` parameter in `docker-compose.yml` (that defines the image name `kortix/suna:___`)
|
||||
2. Update the same image name in `backend/sandbox/sandbox.py` in the `create_sandbox` function
|
||||
3. If using Daytona for deployment, update the image reference there as well
|
|
@ -7,7 +7,6 @@ from pydantic import BaseModel
|
|||
|
||||
from utils.logger import logger
|
||||
from utils.auth_utils import get_optional_user_id
|
||||
from sandbox.sandbox import get_or_start_sandbox
|
||||
from services.supabase import DBConnection
|
||||
from agent.api import get_or_create_project_sandbox
|
||||
|
||||
|
@ -97,14 +96,8 @@ async def get_sandbox_by_id_safely(client, sandbox_id: str):
|
|||
|
||||
try:
|
||||
# Get the sandbox
|
||||
sandbox, retrieved_sandbox_id, sandbox_pass = await get_or_create_project_sandbox(client, project_id)
|
||||
|
||||
# Verify we got the right sandbox
|
||||
if retrieved_sandbox_id != sandbox_id:
|
||||
logger.warning(f"Retrieved sandbox ID {retrieved_sandbox_id} doesn't match requested ID {sandbox_id} for project {project_id}")
|
||||
# Fall back to the direct method if IDs don't match (shouldn't happen but just in case)
|
||||
sandbox = await get_or_start_sandbox(sandbox_id)
|
||||
|
||||
sandbox = await get_or_create_project_sandbox(client, project_id)
|
||||
|
||||
return sandbox
|
||||
except Exception as e:
|
||||
logger.error(f"Error retrieving sandbox {sandbox_id}: {str(e)}")
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from fastapi import FastAPI, APIRouter, HTTPException, Body
|
||||
from playwright.async_api import async_playwright, Browser, Page
|
||||
from playwright.async_api import async_playwright, Browser, Page, ElementHandle
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, List, Dict, Any
|
||||
from typing import Optional, List, Dict, Any, Union
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
import base64
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
|
@ -356,13 +357,13 @@ class BrowserAutomation:
|
|||
self.current_page_index = 0
|
||||
except Exception as page_error:
|
||||
print(f"Error finding existing page, creating new one. ( {page_error})")
|
||||
page = await self.browser.new_page()
|
||||
# page = await self.browser.new_page()
|
||||
print("New page created successfully")
|
||||
self.pages.append(page)
|
||||
# self.pages.append(page)
|
||||
self.current_page_index = 0
|
||||
# Navigate to about:blank to ensure page is ready
|
||||
# await page.goto("google.com", timeout=30000)
|
||||
print("Navigated to google.com")
|
||||
# print("Navigated to google.com")
|
||||
|
||||
print("Browser initialization completed successfully")
|
||||
except Exception as e:
|
||||
|
|
|
@ -6,7 +6,7 @@ services:
|
|||
dockerfile: ${DOCKERFILE:-Dockerfile}
|
||||
args:
|
||||
TARGETPLATFORM: ${TARGETPLATFORM:-linux/amd64}
|
||||
image: adamcohenhillel/kortix-suna:0.0.20
|
||||
image: kortix/suna:0.1
|
||||
ports:
|
||||
- "6080:6080" # noVNC web interface
|
||||
- "5901:5901" # VNC port
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
fastapi==0.115.12
|
||||
uvicorn==0.34.0
|
||||
pyautogui==0.9.54
|
||||
pillow==10.2.0
|
||||
pydantic==2.6.1
|
||||
pytesseract==0.3.13
|
||||
fastapi
|
||||
uvicorn
|
||||
pillow
|
||||
pydantic
|
||||
pytesseract
|
||||
|
|
|
@ -97,7 +97,7 @@ def create_sandbox(password: str, project_id: str = None):
|
|||
labels = {'id': project_id}
|
||||
|
||||
params = CreateSandboxParams(
|
||||
image="adamcohenhillel/kortix-suna:0.0.20",
|
||||
image="kortix/suna:0.1",
|
||||
public=True,
|
||||
labels=labels,
|
||||
env_vars={
|
||||
|
@ -169,7 +169,7 @@ class SandboxToolsBase(Tool):
|
|||
self._sandbox_pass = sandbox_info.get('pass')
|
||||
|
||||
# Get or start the sandbox
|
||||
self._sandbox = await get_or_start_sandbox(self._sandbox_id)
|
||||
# self._sandbox = await get_or_start_sandbox(self._sandbox_id)
|
||||
|
||||
# # Log URLs if not already printed
|
||||
# if not SandboxToolsBase._urls_printed:
|
||||
|
|
Loading…
Reference in New Issue