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

# HostedAgent Compute Runtimes

> Run the whole agent loop in Docker, E2B, Modal, Daytona, Fly.io, or Tenki — one class, one string

HostedAgent hosts the whole agent loop in any registered compute runtime — pick one with a single string.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    H[🌐 HostedAgent<br/>provider=...] --> R[🔀 Backend Registry]
    R --> A[☁️ anthropic]
    R --> D[📦 docker]
    R --> E[🖥️ e2b]
    R --> M[⚡ modal]
    R --> Y[🗄️ daytona]
    R --> F[✈️ flyio]
    R --> T[🌩️ tenki]

    classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef registry fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef provider fill:#10B981,stroke:#7C90A0,color:#fff

    class H input
    class R registry
    class A,D,E,M,Y,F,T provider
```

## Quick Start

<Steps>
  <Step title="Anthropic-hosted loop">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai import HostedAgent

    agent = Agent(backend=HostedAgent(provider="anthropic"))
    agent.start("Summarise today's meeting notes.")
    ```
  </Step>

  <Step title="Daytona-hosted loop">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai import HostedAgent, HostedAgentConfig

    agent = Agent(backend=HostedAgent(
        provider="daytona",
        config=HostedAgentConfig(model="gpt-4o-mini", name="RemoteDev"),
    ))
    agent.start("Set up a Python project and run pytest.")
    ```
  </Step>
</Steps>

***

## Which provider should I pick?

The scenario picks the string.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{What do you need?}
    Q -->|Anthropic's managed cloud| AN[provider=anthropic]
    Q -->|My own Docker daemon| DK[provider=docker]
    Q -->|Persistent dev workspace| DY[provider=daytona]
    Q -->|Instant cloud VM| E2[provider=e2b]
    Q -->|Serverless burst| MO[provider=modal]
    Q -->|Fly Machines| FL[provider=flyio]
    Q -->|Tenki cloud| TK[provider=tenki]

    classDef question fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef answer fill:#10B981,stroke:#7C90A0,color:#fff

    class Q question
    class AN,DK,DY,E2,MO,FL,TK answer
```

***

## How it resolves — the backend registry

`HostedAgent(provider=...)` is a factory: it looks the provider up in `ManagedBackendRegistry` and returns the resolved backend.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant HostedAgent
    participant Registry
    participant Backend

    User->>HostedAgent: HostedAgent(provider="daytona")
    HostedAgent->>Registry: is_available("daytona")?
    Registry-->>HostedAgent: True
    HostedAgent->>Backend: resolve + build
    Backend-->>User: backend instance
```

`anthropic` is a builtin; every registered compute runtime — `docker` included as of [PR #4077](https://github.com/MervinPraison/PraisonAI/pull/4077) — resolves through the same registry and runs on one generic backend.

***

## Provider matrix

| Provider    | Extra install                      | Env var             | Persistent | Best for                  |
| ----------- | ---------------------------------- | ------------------- | :--------: | ------------------------- |
| `anthropic` | (builtin)                          | `ANTHROPIC_API_KEY` |      ❌     | Anthropic-hosted loops    |
| `docker`    | `pip install "praisonai[docker]"`  | (local daemon)      |      ❌     | Local isolation           |
| `e2b`       | `pip install "praisonai[e2b]"`     | `E2B_API_KEY`       |      ❌     | Instant cloud VM          |
| `modal`     | `pip install "praisonai[modal]"`   | Modal auth          |      ❌     | Serverless burst          |
| `daytona`   | `pip install "praisonai[daytona]"` | `DAYTONA_API_KEY`   |      ✅     | Persistent dev workspaces |
| `flyio`     | Fly.io token                       | `FLY_API_TOKEN`     |      ❌     | Fly Machines              |
| `tenki`     | `pip install "praisonai[tenki]"`   | Tenki auth          |      ❌     | Tenki cloud               |

***

## Custom image / template

Since [PR #4077](https://github.com/MervinPraison/PraisonAI/pull/4077) the generic backend honours `image=` — one string maps to each provider's native concept.

| Provider                    | `image=` honoured as                                           |
| --------------------------- | -------------------------------------------------------------- |
| `docker`                    | Docker image ref                                               |
| `e2b`                       | E2B template name (unless `metadata["e2b_template"]` is set)   |
| `modal`                     | Registry image ref via `Image.from_registry(...)`              |
| `daytona`, `flyio`, `tenki` | Not applicable (uses provider-native workspace/image handling) |

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai import HostedAgent, HostedAgentConfig

# Same string across providers — each maps it to the right native concept.
agent = Agent(backend=HostedAgent(
    provider="modal",
    config=HostedAgentConfig(model="gpt-4o-mini"),
    image="ghcr.io/my-org/my-runtime:latest",
))
agent.start("Do something in my custom image.")
```

The default image is `python:3.12-slim`; `image=` is honoured only when set to something other than that default.

***

## Daytona notes

Two Daytona defects were fixed in [PR #4074](https://github.com/MervinPraison/PraisonAI/pull/4074).

<Note>
  **Memory unit.** `ComputeConfig` takes `memory_mb` (megabytes). Daytona's native unit is GiB, so the provider converts automatically — `memory_gib = max(1, round((memory_mb or 1024) / 1024))`. The default `ComputeConfig()` now provisions 1 GiB instead of asking for 1024 GiB. Sub-1024 MB requests floor to 1 GiB (never 0).
</Note>

<Note>
  **File uploads.** Uploading a local file copies the file's *contents* to the remote destination (`upload_file(content, remote_path)`). Earlier versions swapped the arguments and wrote the path string into a file named after the content.
</Note>

***

## What HostedAgent will NOT accept

`openai`, `gemini`, `ollama`, and `local` are LLM routing names, not runtimes. HostedAgent raises `ValueError("... not yet available. Use LocalAgent ...")`.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai import LocalAgent, LocalAgentConfig

agent = LocalAgent(config=LocalAgentConfig(model="openai/gpt-4o"))
agent.start("Draft a release note.")
```

***

## Common Patterns

### Swap the provider without touching agent code

The provider is one string; the agent stays the same.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai import HostedAgent, HostedAgentConfig

def build(provider: str) -> Agent:
    return Agent(backend=HostedAgent(
        provider=provider,
        config=HostedAgentConfig(model="gpt-4o-mini"),
    ))

agent = build("daytona")
agent.start("Run the test suite.")
```

### Pick the provider per environment

Read the provider from an env var to switch cloud vs local.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import os
from praisonaiagents import Agent
from praisonai import HostedAgent

provider = os.environ.get("HOSTED_PROVIDER", "anthropic")
agent = Agent(backend=HostedAgent(provider=provider))
agent.start("Summarise the changelog.")
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Prefer anthropic for zero-setup hosted loops">
    `provider="anthropic"` needs only `ANTHROPIC_API_KEY` — no extra install, no daemon. Reach for a compute runtime when you need your own isolation, persistence, or a specific cloud.
  </Accordion>

  <Accordion title="Keep the provider swappable">
    Pass the provider as a plain string from config or an env var. Every registered runtime shares the same `HostedAgent(provider=..., config=...)` shape, so switching clouds never touches agent code.
  </Accordion>

  <Accordion title="Use LocalAgent for LLM-only routing">
    `openai`, `gemini`, `ollama`, and `local` are not runtimes. Use `LocalAgent(config=LocalAgentConfig(model="..."))` for those, and add `compute="..."` when you want cloud-sandboxed tools with a local loop.
  </Accordion>

  <Accordion title="Daytona for persistent workspaces">
    `daytona` is the only runtime in the matrix that persists between runs — pick it when you want a dev workspace to survive across sessions. Remember `memory_mb` is megabytes; the provider converts to GiB.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Hosted Agent" icon="cloud" href="/docs/features/hosted-agent">
    The base class and its Anthropic path.
  </Card>

  <Card title="Placement — where does my agent run?" icon="map-pin" href="/docs/features/placement">
    Short form: `Agent(run_on="daytona")`.
  </Card>

  <Card title="Managed Backend Plugins" icon="puzzle-piece" href="/docs/features/managed-backend-plugins">
    Register your own runtime via entry points.
  </Card>

  <Card title="Self-Hosted Agent (Docker)" icon="docker" href="/docs/features/run-on-docker">
    `provider="docker"` runs the whole loop in a container you own.
  </Card>
</CardGroup>
