Merge pull request #2 from lfglabs-dev/feature/agent-tree

Feature/agent tree
This commit is contained in:
Thomas Marchand
2025-12-16 08:13:08 +03:00
committed by GitHub
2 changed files with 152 additions and 178 deletions

152
.cursor/rules/deployment.md Normal file
View File

@@ -0,0 +1,152 @@
# Open Agent - Deployment Guide
## Production Server
| Property | Value |
|----------|-------|
| **Host** | `95.216.112.253` |
| **SSH Access** | `ssh root@95.216.112.253` |
| **Backend URL** | `https://agent-backend.thomas.md` |
| **Dashboard URL** | `https://agent.thomas.md` (Vercel deployment) |
| **Environment file** | `/etc/open_agent/open_agent.env` |
| **Binary location** | `/usr/local/bin/open_agent` |
| **Systemd service** | `open_agent` |
| **Source code** | `/root/open_agent` |
## Port Configuration
| Service | Local Port | Production URL |
|---------|-----------|----------------|
| Backend API | 3000 | https://agent-backend.thomas.md |
| Dashboard | 3001 | https://agent.thomas.md |
## Local Development
- **Backend API**: `http://127.0.0.1:3000` (Rust server via `cargo run`)
- **Dashboard**: `http://127.0.0.1:3001` (Next.js via `bun run dev`)
- **Environment files**:
- Backend: `.env` in project root
- Dashboard: `dashboard/.env.local`
## Common Operations
### Check Service Status
```bash
ssh root@95.216.112.253 'systemctl status open_agent'
```
### View Logs
```bash
ssh root@95.216.112.253 'journalctl -u open_agent -f'
```
### Restart Service
```bash
ssh root@95.216.112.253 'systemctl restart open_agent'
```
### Edit Environment Variables
```bash
ssh root@95.216.112.253 'vim /etc/open_agent/open_agent.env'
# Then restart:
ssh root@95.216.112.253 'systemctl restart open_agent'
```
## Full Redeployment
To redeploy from scratch:
```bash
# 1. SSH into server
ssh root@95.216.112.253
# 2. Go to source directory
cd /root/open_agent
# 3. Pull latest changes
git pull
# 4. Build release binary
cargo build --release
# 5. Copy binary to /usr/local/bin
cp target/release/open_agent /usr/local/bin/open_agent
# 6. Restart service
systemctl restart open_agent
# 7. Check status
systemctl status open_agent
```
## SSH Key for Git Access
The VPS has a cursor SSH key at `~/.ssh/cursor` which has read access to private GitHub repositories. The git remote should be configured to use SSH:
```bash
# Check remote URL
git remote -v
# If needed, switch to SSH:
git remote set-url origin git@github.com:owner/open_agent.git
```
Make sure the SSH config uses the cursor key for github.com:
```bash
# ~/.ssh/config on VPS
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/cursor
```
## Systemd Service Configuration
The service file is typically at `/etc/systemd/system/open_agent.service`:
```ini
[Unit]
Description=Open Agent
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/root/open_agent
EnvironmentFile=/etc/open_agent/open_agent.env
ExecStart=/usr/local/bin/open_agent
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
## Nginx Reverse Proxy
The backend is proxied through nginx at `agent-backend.thomas.md`. The nginx config typically includes:
```nginx
server {
server_name agent-backend.thomas.md;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# SSL managed by certbot
}
```
## Security Notes
- The API requires authentication when `DEV_MODE=false`
- JWT tokens are used for dashboard authentication
- Keep `.env` and `open_agent.env` out of version control
- The agent has full machine access - be careful with what tasks you submit

View File

@@ -1,178 +0,0 @@
# Open Agent - Cursor Rules & Project Philosophy
## Project Overview
Open Agent is a minimal autonomous coding agent implemented in Rust. It is designed to be:
- **AI-maintainable**: Rust's strong type system and compiler provide immediate feedback
- **Self-contained**: No external dependencies beyond OpenRouter for LLM access
- **Full-access**: Has complete access to the local machine (filesystem, terminal, network)
- **Provable**: Code structured for future formal verification in Lean
## Architecture (v2: Hierarchical Agent Tree)
### Agent Hierarchy
```
┌─────────────┐
│ RootAgent │
└──────┬──────┘
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────┐
│ Complexity │ │ Model │ │ Task │ │ Verifier │
│ Estimator │ │ Selector │ │ Executor │ │ │
└───────────────┘ └─────────────┘ └─────────────┘ └──────────┘
```
### Agent Types
| Type | Role | Children |
|------|------|----------|
| **RootAgent** | Top-level orchestrator, receives API tasks | All leaf types |
| **NodeAgent** | Intermediate orchestrator for subtasks | Executor, Verifier |
| **ComplexityEstimator** | Estimates task difficulty (0-1 score) | None (leaf) |
| **ModelSelector** | Picks optimal model (U-curve optimization) | None (leaf) |
| **TaskExecutor** | Executes tasks using tools | None (leaf) |
| **Verifier** | Validates completion (hybrid) | None (leaf) |
### Task Flow
1. Receive task via HTTP API
2. **Estimate Complexity** (ComplexityEstimator)
3. If complex: **Split into subtasks** with budget allocation
4. **Select Model** for each (sub)task (U-curve cost optimization)
5. **Execute** using tools (TaskExecutor)
6. **Verify** completion (Verifier: programmatic → LLM fallback)
7. Aggregate results and return
### U-Curve Model Selection
```
Cost
^
| * *
| * *
| * * *
| * * * *
| * *
+-------------------------> Model Capability
(cheap/weak) (optimal) (expensive/strong)
```
- Cheap models: low per-token cost, high failure rate, more retries
- Expensive models: high per-token cost, low failure rate
- **Optimal**: minimizes expected total cost
## Module Structure
```
src/
├── agents/ # Hierarchical agent system
│ ├── mod.rs # Agent traits (Agent, OrchestratorAgent, LeafAgent)
│ ├── types.rs # AgentId, AgentType, AgentResult, Complexity
│ ├── context.rs # Shared context for agent tree
│ ├── tree.rs # Tree structure management
│ ├── orchestrator/ # Orchestrator agents
│ │ ├── root.rs # RootAgent (top-level)
│ │ └── node.rs # NodeAgent (intermediate)
│ └── leaf/ # Leaf agents (specialized workers)
│ ├── complexity.rs # ComplexityEstimator
│ ├── model_select.rs # ModelSelector with U-curve
│ ├── executor.rs # TaskExecutor (tools in a loop)
│ └── verifier.rs # Hybrid verification
├── task/ # Task types with invariants
│ ├── task.rs # Task, TaskId, TaskStatus
│ ├── subtask.rs # Subtask, SubtaskPlan
│ └── verification.rs # VerificationCriteria, ProgrammaticCheck
├── budget/ # Cost tracking and pricing
│ ├── budget.rs # Budget with spend/allocate invariants
│ ├── pricing.rs # OpenRouter pricing client
│ └── allocation.rs # Budget allocation strategies
├── agent/ # Original simple agent (legacy)
├── api/ # HTTP interface
├── llm/ # LLM client (OpenRouter)
├── tools/ # Tool implementations
└── config.rs # Configuration
```
## Design for Provability
### Conventions for Future Lean Proofs
1. **Pre/Postconditions**: Document as `/// Precondition:` and `/// Postcondition:` comments
2. **Invariants**: Document struct invariants, enforce in constructors
3. **Algebraic Types**: Use enums with exhaustive matching, no `_` catch-all
4. **Pure Functions**: Separate pure logic from IO where possible
5. **Result Types**: Never panic, always return `Result`
### Example
```rust
/// Allocate budget for a subtask.
///
/// # Precondition
/// `amount <= self.remaining_cents()`
///
/// # Postcondition
/// `self.allocated_cents` increases by exactly `amount`
pub fn allocate(&mut self, amount: u64) -> Result<(), BudgetError>
```
## Adding a New Leaf Agent
1. Create `src/agents/leaf/your_agent.rs`
2. Implement `Agent` trait:
- `id()`, `agent_type()`, `execute()`
3. Implement `LeafAgent` trait:
- `capability()` → add variant to `LeafCapability` enum
4. Register in `RootAgent::new()` or relevant orchestrator
5. Document pre/postconditions for provability
## API Contract
```
POST /api/task - Submit task (uses hierarchical agent)
GET /api/task/{id} - Get task status and result
GET /api/task/{id}/stream - Stream progress via SSE
GET /api/health - Health check
```
## Environment Variables
```
OPENROUTER_API_KEY - Required. Your OpenRouter API key
DEFAULT_MODEL - Optional. Default: openai/gpt-4.1-mini
WORKSPACE_PATH - Optional. Default: current directory
HOST - Optional. Default: 127.0.0.1
PORT - Optional. Default: 3000
MAX_ITERATIONS - Optional. Default: 50
```
## Deployment
### Production Server
- **Host**: `95.216.112.253`
- **SSH Access**: `ssh root@95.216.112.253` (key-based auth available to agent)
- **Environment files**: Located in `/root/open_agent/.env` on the server
### Local Development
- **Backend API**: `http://127.0.0.1:3000` (Rust server via `cargo run`)
- **Dashboard**: `http://127.0.0.1:3001` (Next.js via `bun run dev`)
- **Environment files**:
- Backend: `.env` in project root
- Dashboard: `dashboard/.env.local`
## Security Considerations
This agent has **full machine access**. It can:
- Read/write any file the process can access
- Execute any shell command
- Make network requests
When deploying:
- Run as a limited user
- Use workspace isolation
- Consider a sandbox for terminal commands
- Never expose the API publicly without authentication
## Future Work
- [ ] Formal verification in Lean (extract pure logic)
- [ ] WebSocket for bidirectional streaming
- [ ] Semantic code search (embeddings-based)
- [x] Multi-model support (U-curve optimization)
- [x] Cost tracking (Budget system)