Metadata-Version: 2.4
Name: session-based-sandbox
Version: 0.1.0
Summary: A local-first session-based sandbox runtime for AI agents.
Author: session-based-sandbox contributors
License-Expression: MIT
Keywords: sandbox,runtime,agents,fastapi,local-first
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Classifier: Topic :: System :: Shells
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi<1.0,>=0.110
Requires-Dist: pydantic<3.0,>=2.6
Requires-Dist: uvicorn<1.0,>=0.27
Provides-Extra: dev
Requires-Dist: httpx<1.0,>=0.26; extra == "dev"
Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
Requires-Dist: pytest-cov<7.0,>=4.1; extra == "dev"
Requires-Dist: build<2.0,>=1.0; extra == "dev"
Requires-Dist: twine<7.0,>=5.0; extra == "dev"
Dynamic: license-file

# session-based-sandbox

Local-first sandbox runtime: **one HTTP session maps to one temp workdir**, run **bash** or **Python** steps with **timeouts**, explicit **`sandbox_id`** routing, and **DELETE** to tear down.

Contributing: see [CONTRIBUTING.md](CONTRIBUTING.md). License: [MIT](LICENSE). Releases: see [CHANGELOG.md](CHANGELOG.md). Detailed MVP design for implementers: [Implementation specification](#implementation-specification-mvp-design) below.

## Quickstart

Requires **Python 3.11+**.

```bash
git clone <repository-url>
cd session-based-sandbox
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -U pip setuptools wheel
pip install -e ".[dev]"

sbs run
# same server: session-based-sandbox run
```

Then open **http://127.0.0.1:8000/docs** for interactive API documentation.

When the package is published to PyPI:

```bash
pip install session-based-sandbox
sbs run
```

## HTTP API (current behavior)

Default base URL: `http://127.0.0.1:8000`.

### `POST /sessions`

Creates a session and isolated working directory. **Body:** empty JSON object `{}` is fine.

**Response:** `{"session_id": "<uuid>"}`

### `POST /sessions/{session_id}/step`

**JSON body (required fields):**

| Field | Description |
|-------|-------------|
| `sandbox_id` | Must equal `session_id` from the URL (explicit routing). |
| `type` | `"bash"` or `"python"`. |
| `payload` | Bash: `{"cmd": "<shell string>"}`. Python: `{"code": "<source passed to python -c>"}`. |

**Response:** `{"output": "...", "error": "...", "exit_code": <int>}`  
If the step exceeds the configured wall-clock limit, **`exit_code` is 124** and `error` describes the timeout.

### `DELETE /sessions/{session_id}`

**204** with no body. Removes the session and its workdir. Later steps for that id return **404**.

### curl smoke (single-line friendly)

After `sbs run`, in another terminal:

```bash
BASE=http://127.0.0.1:8000 && SID=$(curl -sS -X POST "$BASE/sessions" | python3 -c "import sys,json; print(json.load(sys.stdin)['session_id'])") && curl -sS -X POST "$BASE/sessions/$SID/step" -H 'Content-Type: application/json' -d "{\"sandbox_id\":\"$SID\",\"type\":\"bash\",\"payload\":{\"cmd\":\"pwd\"}}" && echo && curl -sS -o /dev/null -w "DELETE %{http_code}\n" -X DELETE "$BASE/sessions/$SID"
```

## CLI

Both console scripts call the same `uvicorn` app:

| Entry point | Notes |
|-------------|--------|
| `sbs run` | Short alias. |
| `session-based-sandbox run` | Same behavior as `sbs`. |

Options: `--host` (default `127.0.0.1`), `--port` (default `8000`).

```bash
sbs run --help
session-based-sandbox run --host 127.0.0.1 --port 8001
```

## Configuration

| Variable | Meaning |
|----------|---------|
| `SBS_STEP_TIMEOUT_SEC` | Max seconds per step (default **30**, minimum **1**). Read when the **server process** starts; restart after changing. |

## Safety

- Isolation is **temp directories + subprocesses**, not containers or VMs. Host resources (CPU, disk, network) can still be affected by malicious or heavy workloads.
- Steps execute as the **same OS user** as the server, using host **Python** and **`/bin/bash`** (where available).
- Timeouts and **DELETE** attempt to **terminate** the child process; behavior under concurrent load is best-effort for this MVP.
- There is **no authentication**. Prefer binding to **`127.0.0.1`** and do not expose the API to untrusted networks without a separate auth layer.

## Development setup

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

Repository scripts used in release checks:

```bash
bash scripts/verify_editable_install.sh
bash scripts/verify_cli_entrypoints.sh
bash scripts/verify_package_build.sh
bash scripts/verify_release_ready.sh
```

## Testing

```bash
pytest tests/
pytest tests/ -v
pytest tests/ --cov=session_based_sandbox --cov-report=term-missing
pytest tests/system/test_cli_server_entrypoints.py -v
```

On GitHub, **CI** runs the same test suite on **Python 3.11 and 3.12** for pushes/PRs to **`main`** or **`master`** (see `.github/workflows/ci.yml`).

---

## Implementation specification (MVP design)

## Project Goal

Build a production-quality MVP for a **Session-Based Sandbox Runtime** using **Python + FastAPI**.

This is a local-first execution runtime for AI agents that provides:

* session-based execution
* stateful sandbox environments
* isolated runtime environments
* explicit execution routing
* deterministic behavior

This is NOT a full platform.

This is a minimal, robust, extensible open-source tool.

The goal is to let users or AI agents safely execute coding tasks, shell commands, and workflows inside isolated local sandboxes without polluting the host machine.

---

# Product Context

## User Scenario

A user wants an AI agent to help with:

* coding
* running scripts
* installing packages
* debugging
* data analysis
* executing terminal commands

But they do NOT want the agent directly operating inside the host machine environment.

They want a safer, simpler, more controllable local runtime.

---

# User Pain Points

## Pain Point 1

The user has no technical background.

They do not know what a sandbox is, but they want their AI agent to code for them.

---

## Pain Point 2

The user has technical background, but existing tools are too complex to configure.

They do not want to spend hours configuring Docker / infra / orchestration.

---

## Pain Point 3

The user has technical background, but they do not want agents running dangerous commands directly on their machine.

They want strong isolation and cleanup.

---

## Pain Point 4

The user notices the agent repeatedly makes the same execution mistakes.

For example:

* re-running failed scripts
* repeating broken environment setup
* retrying commands that already failed

They want session-based state and future persistent memory support.

---

# What SBS Solves

`sbs` (session-based-sandbox) solves this by providing:

## 1. Easy Installation

Users can install via common package managers:

```bash
pip install session-based-sandbox
```

and later potentially:

```bash
npm install ...
brew install ...
```

(Phase 1 only requires Python packaging.)

---

## 2. Agent-Friendly Usage

Tools like:

* ClaudeHub
* Hermes
* OpenHands
* other coding agents

can read the SBS skill documentation and learn how to use it.

This makes SBS usable by both:

* humans
* AI agents

---

## 3. Safe Local Runtime

Users and agents can:

* create isolated sessions
* execute python/bash
* preserve state inside the session
* destroy the environment after completion

without polluting the host machine.

---

# Core Design Principle

# 1 Session → 1 Sandbox

This is the most important architecture rule.

## Correct Model

```text
1 Session → 1 Sandbox
```

Meaning:

A single session owns exactly one sandbox.

---

## Definitions

### Session

Logical task lifecycle manager.

Responsible for:

* lifecycle management
* state management
* step routing
* execution history
* cleanup trigger

Think of it as:

```text
task controller
```

---

### Sandbox

Actual execution environment.

Responsible for:

* command execution
* file isolation
* subprocess management
* cwd management
* runtime isolation

Think of it as:

```text
the actual worker machine
```

---

## Important Rule

### Session ≠ Sandbox

But:

```text
Session owns exactly one Sandbox
```

which means:

```text
1 Session → 1 Sandbox
```

---

## Why This Rule Exists

Because shared environments cause chaos.

Bad example:

```text
Session A:
pip install pandas==1.5

Session B:
pip install pandas==2.2
```

Result:

```text
everything breaks
```

No determinism.

No safety.

No traceability.

No cleanup.

---

## Benefits

### Strong Isolation

Sessions do not affect each other.

---

### Deterministic Behavior

Each task runs inside its own isolated environment.

---

### Easy Cleanup

```http
DELETE /sessions/{id}
```

removes the entire environment.

---

### Stateful Execution

Same session can continue previous work.

Example:

```text
yesterday installed packages
today still available
```

This is not stateless command execution.

This is stateful runtime execution.

---

# MVP Scope

Build ONLY the minimum production-quality MVP.

Do NOT build a platform.

Do NOT over-engineer.

Do NOT add future features.

---

# Tech Stack

Use:

* Python 3.11+
* FastAPI
* Uvicorn
* Pydantic
* Pytest

Optional:

* asyncio
* subprocess
* tempfile
* pathlib
* uuid
* signal
* shutil
* logging

Do NOT use:

* Docker
* Celery
* Redis
* PostgreSQL
* SQLAlchemy
* Kubernetes
* RabbitMQ
* external infra

Everything must run fully on localhost.

---

# Required Features

Implement ONLY the following.

---

# 1. Session Lifecycle

## Create Session

### Endpoint

```http
POST /sessions
```

### Behavior

Must:

* create a new session
* generate unique `session_id`
* create exactly one local sandbox
* create isolated working directory using `tempfile.mkdtemp()`
* set session status = ACTIVE

### Return

```json
{
  "session_id": "uuid"
}
```

---

# 2. Step Execution

## Endpoint

```http
POST /sessions/{session_id}/step
```

---

## Required Step Schema

Every request MUST include:

```json
{
  "sandbox_id": "session_id",
  "type": "python | bash",
  "payload": {}
}
```

---

## Validation Rules

Must enforce:

* `sandbox_id` is mandatory
* `sandbox_id` MUST equal `session_id`
* otherwise return validation error

No implicit routing allowed.

Explicit execution target only.

---

## Supported Step Types

### Python

```json
{
  "sandbox_id": "session_id",
  "type": "python",
  "payload": {
    "code": "print(123)"
  }
}
```

---

### Bash

```json
{
  "sandbox_id": "session_id",
  "type": "bash",
  "payload": {
    "cmd": "ls -la"
  }
}
```

---

## Execution Requirements

Execution must:

* run inside that session’s isolated cwd
* capture stdout
* capture stderr
* capture exit_code
* enforce timeout

If timeout occurs:

* kill process
* return timeout error clearly

### Return

```json
{
  "output": "...",
  "error": "...",
  "exit_code": 0
}
```

---

# 3. Close Session

## Endpoint

```http
DELETE /sessions/{session_id}
```

## Behavior

Must:

* mark session CLOSED
* terminate alive subprocesses
* delete temp working directory
* block future execution for this session

---

# Failure Modes (Must Handle)

Must explicitly handle:

---

## Sandbox Crash

Return structured execution error.

---

## Infinite Loop

Use timeout + force kill.

---

## Closed Session

Execution must be blocked.

---

## Sandbox Isolation

No cross-session shared state.

---

## Resource Cleanup

Must destroy resources after close.

No:

* orphan subprocesses
* leaked temp directories

---

# Project Structure

Use exactly this structure:

```text
session-based-sandbox/
│
├── session_based_sandbox/
│   ├── cli.py
│   ├── server.py
│   │
│   ├── runtime/
│   │   ├── runtime.py
│   │   ├── session.py
│   │   ├── executor.py
│   │   ├── router.py
│   │   └── state.py
│   │
│   ├── sandbox/
│   │   └── local.py
│   │
│   └── api/
│       ├── http.py
│       └── ws.py
│
├── tests/
│   ├── unit/
│   ├── integration/
│   ├── system/
│   └── failure_modes/
│
└── pyproject.toml
```

---

# Logging

Use simple structured logs for:

* session_created
* step_received
* step_started
* step_finished
* execution_failed
* session_closed

Requirements:

* keep logging simple
* standard logging only
* no tracing system

---

# Testing (Required)

Write real pytest tests.

No placeholder tests.

Tests must actually run.

---

## Required Coverage

Must test:

* session lifecycle
* step routing correctness
* sandbox isolation
* timeout handling
* crash handling
* closed session execution blocked

---

# Installation Requirements

Must support:

```bash
pip install -e .
```

and

```bash
pip install session-based-sandbox
```

Must work as:

* local editable install
* normal published package install

---

# CLI Requirements

Must expose both commands:

```bash
session-based-sandbox run
```

and

```bash
sbs run
```

Both must start the same FastAPI server.

Default server:

```text
http://127.0.0.1:8000
```

---

# pyproject.toml Entry Points

Must define:

```toml
[project.scripts]
session-based-sandbox = "session_based_sandbox.cli:run"
sbs = "session_based_sandbox.cli:run"
```

No wrappers.

No extra launch layers.

Simple and explicit only.

---

# Strong Constraints

Do NOT implement:

* Docker sandbox
* WebSocket streaming
* persistent storage
* distributed workers
* tracing UI
* SDK
* auth system
* user system
* database
* queue system
* scheduler
* background workers

These are future features.

They must be excluded.

---

# Code Quality Rules

Code must be:

* clean
* typed
* readable
* maintainable
* minimal
* testable

Avoid:

* giant files
* hidden magic
* unnecessary inheritance
* speculative abstractions

Prefer:

* explicit code
* small modules
* simple control flow

---

# Deliverables

Must produce:

1. Full project code
2. All required tests
3. `pyproject.toml`
4. CLI runnable entrypoint
5. Proper package metadata for publishable installation

Must support:

```bash
pip install -e .
pip install session-based-sandbox

session-based-sandbox run
sbs run
```

Server must run at:

```text
http://127.0.0.1:8000
```

---

# Recommended Development Order

Build in this order:

```text
1. Create project structure
2. pyproject.toml
3. cli.py
4. server.py
5. api/http.py skeleton
6. runtime/state.py
7. runtime/session.py
8. sandbox/local.py
9. runtime/executor.py
10. runtime/router.py
11. runtime/runtime.py
12. tests
13. local install validation
14. CLI validation
15. pytest validation
```

---

# Final Requirement

This is the most important rule:

Build the MVP exactly.

Do not improve scope.

Do not add platform features.

Do not redesign architecture.

Strictly execute the specification.
