> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspace

> Sandbox agent file operations inside a safe, per-session directory

Workspace sandboxing provides secure, isolated file access for agents, ensuring file operations stay within designated boundaries.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Workspace Sandbox"
        A[🤖 Agent] --> T[🛠️ File Tools]
        T --> W[📁 Workspace Root]
        W --> OK[✅ Inside = Allowed]
        W --> NO[🚫 Outside = Rejected]
    end
    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef safe fill:#10B981,stroke:#7C90A0,color:#fff
    classDef danger fill:#F59E0B,stroke:#7C90A0,color:#fff
    class A agent
    class T,W tool
    class OK safe
    class NO danger
```

## Quick Start

<Steps>
  <Step title="Basic Bot with Workspace">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import TelegramBot

    agent = Agent(
        name="Assistant",
        instructions="You help users with files and tasks"
    )

    # Workspace is applied automatically when agent runs as a bot
    bot = TelegramBot(token="YOUR_TOKEN", agent=agent)
    ```
  </Step>

  <Step title="Custom Workspace Configuration">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import TelegramBot
    from praisonaiagents.bots import BotConfig

    config = BotConfig(
        token="YOUR_TOKEN",
        workspace_dir="./my-bot-workspace",  # custom path
        workspace_access="rw",                # "rw" | "ro" | "none"
        workspace_scope="session",            # "shared" | "session" | "user" | "agent"
    )

    bot = TelegramBot(config=config, agent=agent)
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant Workspace
    participant FileSystem
    
    User->>Agent: "Save this file"
    Agent->>Workspace: check path containment
    Workspace-->>Agent: ✅ path allowed
    Agent->>FileSystem: write file
    FileSystem-->>Agent: success
    Agent-->>User: "File saved in workspace"
```

Workspace containment operates through three key mechanisms:

| Mechanism             | Purpose                              | Implementation             |
| --------------------- | ------------------------------------ | -------------------------- |
| **Path Resolution**   | Resolve paths against workspace root | `workspace.resolve(path)`  |
| **Containment Check** | Verify paths stay within boundaries  | `workspace.contains(path)` |
| **Access Control**    | Enforce read/write permissions       | Access mode validation     |

***

## Configuration Options

### Workspace Access Modes

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TD
    Q1["What should the agent do with files?"]
    Q1 -->|"Read AND write"| RW["rw (default)"]
    Q1 -->|"Only read"| RO["ro"]
    Q1 -->|"Isolated scratch only"| NONE["none (sandbox)"]
    classDef q fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef a fill:#10B981,stroke:#7C90A0,color:#fff
    class Q1 q
    class RW,RO,NONE a
```

### Workspace Configuration

| Option        | Type                                         | Default     | Description                                              |
| ------------- | -------------------------------------------- | ----------- | -------------------------------------------------------- |
| `root`        | `Path`                                       | required    | Absolute workspace directory (auto-created; refuses `/`) |
| `access`      | `"rw"`, `"ro"`, `"none"`                     | `"rw"`      | Read-write, read-only, or copy-on-write sandbox          |
| `scope`       | `"shared"`, `"session"`, `"user"`, `"agent"` | `"session"` | Workspace scope level                                    |
| `session_key` | `Optional[str]`                              | `None`      | Session identifier for scope resolution                  |

### BotConfig Workspace Fields

| Option             | Type            | Default                                                  | Description             |
| ------------------ | --------------- | -------------------------------------------------------- | ----------------------- |
| `workspace_dir`    | `Optional[str]` | `None` → `~/.praisonai/workspaces/<scope>/<session_key>` | Override workspace path |
| `workspace_access` | `str`           | `"rw"`                                                   | Access mode             |
| `workspace_scope`  | `str`           | `"session"`                                              | Scope level             |

***

## Common Patterns

### Scope Selection Guide

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Shared workspace (all users/agents share files)
config = BotConfig(workspace_scope="shared")

# Session workspace (isolated per conversation)
config = BotConfig(workspace_scope="session")  # default

# User workspace (isolated per user)
config = BotConfig(workspace_scope="user")

# Agent workspace (isolated per agent instance)
config = BotConfig(workspace_scope="agent")
```

### Advanced Path Operations

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.workspace import Workspace
from pathlib import Path

workspace = Workspace(
    root=Path("./my-workspace").resolve(),
    access="rw"
)

# Check if path is contained
if workspace.contains("user-file.txt"):
    # Safe to access
    safe_path = workspace.resolve("user-file.txt")

# Handle path traversal attempts
try:
    bad_path = workspace.resolve("../../../etc/passwd")
except ValueError as e:
    print(f"Security violation: {e}")
```

### Read-Only Workspace

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Prevent any file modifications
config = BotConfig(
    workspace_access="ro",
    workspace_dir="./read-only-data"
)
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Choose the Right Scope">
    Use `"session"` (default) for most chat bots to isolate conversations. Use `"shared"` only when agents need to collaborate on files. Use `"user"` for personal assistants. Use `"agent"` for specialized single-purpose bots.
  </Accordion>

  <Accordion title="Security by Construction">
    Workspaces reject filesystem root access, resolve symlinks to prevent macOS issues, and validate all path operations. Never bypass workspace containment in production deployments.
  </Accordion>

  <Accordion title="Default Path Layout">
    The default workspace structure is `~/.praisonai/workspaces/<scope>/<session_key>/`. This ensures clean separation and predictable file organization across different deployment scenarios.
  </Accordion>

  <Accordion title="Backward Compatibility">
    File tools fall back to `os.getcwd()` when no workspace is configured, maintaining compatibility with existing code. Bots automatically apply workspace containment for security.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Bot Default Tools" icon="toolbox" href="/docs/features/bot-default-tools">
    Auto-injected tools that work with workspaces
  </Card>

  <Card title="Self-Improving Skills" icon="wand-magic-sparkles" href="/docs/features/skill-manage">
    How skills interact with workspace containment
  </Card>
</CardGroup>
