> ## 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.

# First-Run Provisioning

> How the Desktop app installs its own Python runtime on first launch

The first time you launch PraisonAI Desktop, it installs its own Python runtime and the `praisonaiagents` package into your user data folder — no terminal, no `pip`.

On later launches, the app compares a record of what it installed against the requirement shipped with the current build. If a fix in `praisonaiagents` raised the floor, or a new package was added, the app re-runs the install step once — the tray reads `Engine: updating…` while it runs — and starts the engine against the up-to-date venv. This is why raising the pin in one release actually reaches you on the next launch, instead of only reaching brand-new installs.

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

agent = Agent(
    name="Assistant",
    instructions="You are a helpful assistant.",
)
# The Desktop app provisions the environment that runs this agent for you.
agent.start("Hello")
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Uv[⬇️ Fetch uv] --> Py[🐍 Install Python 3.12]
    Py --> Venv[📦 Create environment]
    Venv --> Agents[✅ Install PraisonAI]

    classDef fetch fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef py fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef venv fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef done fill:#10B981,stroke:#7C90A0,color:#fff

    class Uv fetch
    class Py py
    class Venv venv
    class Agents done
```

## Quick Start

**1. Launch the app**

On a clean machine the app opens straight onto the first-run screen instead of the chat.

**2. Watch the four stages**

Each stage flips from pending to running to done as the runtime is built.

**3. Start chatting**

When the last stage completes, the window switches to chat — the environment is ready.

***

## How It Works

The app locates or fetches `uv`, has it install a pinned CPython, creates a venv in your data directory, then installs the engine's dependencies into it.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant You as 👤 You
    participant App as 🖥️ App
    participant Uv as ⬇️ uv
    participant Venv as 📦 venv

    You->>App: first launch
    App->>Uv: locate or fetch installer
    App->>Uv: install Python 3.12
    Uv->>Venv: create environment
    App->>Venv: install praisonaiagents
    Venv-->>You: ready to chat
```

The runtime is pinned, not "latest": the app installs **Python 3.12** and a floor of **`praisonaiagents>=1.7.2`** so a first run cannot land on a bad interpreter or a broken release.

> [!NOTE]
>
> On first launch (or any launch where setup is still needed), the app briefly forces the **Chat** view while the async engine health check runs. This prevents a saved **Train** view from hiding the setup wizard behind its CSS (`body.training #thread { display: none }`). The switch is not persisted, and as soon as setup completes the app re-applies your saved view **in the same session** — so a deliberate Train choice returns the instant the engine is ready, with no relaunch. Introduced in PraisonAI [#4471](https://github.com/MervinPraison/PraisonAI/pull/4471); the same-session restore was added in [#4623](https://github.com/MervinPraison/PraisonAI/pull/4623). Both close [#4441](https://github.com/MervinPraison/PraisonAI/issues/4441).

***

## Keeping the venv current

The venv is provisioned once, but its package set is not frozen. Each launch writes a small `.praisonai-packages` stamp inside the venv recording which requirements are currently installed. When the shipped requirement changes — a raised floor for `praisonaiagents`, an added dependency — the stamp no longer matches, and the app re-runs the install step exactly once before the engine starts. `uv` is near-instant when nothing changed, so a no-drift launch is not slowed. On failure the engine still starts and the UI reports whatever version is actually installed, so a bad update never blocks chat; the stamp is only written on install success, so a failed update is retried on the next launch rather than silently recorded as done.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Launch[🚀 Launch] --> Read{Stamp<br/>matches?}
    Read -->|yes| Start[✅ Engine: starting…]
    Read -->|no / missing| Update[⚙️ Engine: updating…]
    Update --> Install{Install ok?}
    Install -->|yes| Stamp[💾 Rewrite stamp]
    Install -->|no| Fallback[⚠️ Start with what is installed]
    Stamp --> Start
    Fallback --> Start

    classDef q fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef work fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff
    classDef bad fill:#8B0000,stroke:#7C90A0,color:#fff

    class Launch,Read,Install q
    class Update,Stamp work
    class Start ok
    class Fallback bad
```

***

## Event Stream

The first-run screen renders `provision` events from the `provision_engine` command. Each event carries an `id`, a `label`, a `state`, and an optional `detail`.

| Stage `id` | Label |
| - | - |
| `uv` | Fetching the installer |
| `python` | Installing Python |
| `venv` | Creating the environment |
| `deps` | Installing PraisonAI |

Each stage moves through four states:

| `state` | Meaning |
| - | - |
| `pending` | Not started yet |
| `running` | In progress |
| `done` | Finished successfully |
| `error` | Failed — the **Retry** button re-invokes `provision_engine` |

> [!NOTE]
>
> The dependencies stage installs the whole set in **one** `uv pip install` invocation, so `uv` resolves the packages together rather than one at a time.

***

## Where Things Go

The environment is built inside your user data folder, never inside the read-only app bundle.

The data folder itself is created when the app opens, ahead of provisioning. The venv and engine files land inside it when you click **Get started**.

| Path | Contents |
| - | - |
| `<data folder>/venv/` | The provisioned Python environment |
| `<data folder>/venv/bin/python3` (`Scripts\python.exe` on Windows) | The interpreter the engine runs from |

The `<data folder>` is the per-platform data directory — see [Data & Privacy](https://praison.ai/docs/features/desktop/data.md#where-data-lives) for each path. Override it with `PRAISONAI_DESKTOP_HOME` if you want the venv somewhere else.

> [!NOTE]
>
> Automatic reconciliation of a drifted venv landed in PraisonAI [#4670](https://github.com/MervinPraison/PraisonAI/pull/4670) (closes [#4668](https://github.com/MervinPraison/PraisonAI/issues/4668)). On earlier releases the venv was frozen at whatever the first-run set installed, so a library fix shipped in `praisonaiagents` never reached existing installs unless you deleted the venv by hand.

***

## Bring Your Own Runtime

If you already have `praisonaiagents`, you can skip provisioning entirely.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{Do you already have<br/>praisonaiagents?} -->|Yes| Own[Set PRAISONAI_PYTHON<br/>skip provisioning]
    Q -->|No| Manage[Let first-run finish<br/>app manages the runtime]

    classDef q fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef own fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef manage fill:#10B981,stroke:#7C90A0,color:#fff

    class Q q
    class Own own
    class Manage manage
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Point the engine at your own interpreter and skip the managed venv.
export PRAISONAI_PYTHON=/absolute/path/to/venv/bin/python3
```

Reconciliation only touches the venv the app provisioned itself (`<data folder>/venv`). If `PRAISONAI_PYTHON` points the engine at your own interpreter, the app never rewrites its packages — you own that environment and its versions.

***

## Best Practices

> [accordion] Let the first run finish uninterrupted
>
> Provisioning downloads an interpreter and resolves packages. Leave the window open until all four stages are done — quitting mid-run leaves a partial venv.

> [accordion] Retry from where it stopped
>
> If a stage errors (usually a network drop while fetching `uv` or Python), the **Retry** button re-runs `provision_engine` from the current stage rather than starting over.

> [accordion] Own the runtime for reproducible installs
>
> Set `PRAISONAI_PYTHON` to a venv you control when you need a pinned, reproducible environment. The app then runs the engine against your interpreter and never provisions its own.

***

## Related

> [card] [Window & Lifecycle](https://praison.ai/docs/features/desktop/window-and-lifecycle.md)
>
> Tray, single-instance, and orphan reclamation

> [card] [Troubleshooting](https://praison.ai/docs/features/desktop/troubleshooting.md)
>
> Read the engine log and fix startup failures


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.