> ## Documentation Index
> Fetch the complete documentation index at: https://vendo-mintlify-24213046.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How the panel works

> One question in the panel, end to end: your route, your identity, your API, and the screen that streams back.

The panel is the only Vendo code in your browser. Every turn goes to a route
inside your own app and streams back to that panel.

<svg viewBox="0 0 704 208" width="100%" role="img" aria-labelledby="vendo-path-title">
  <title id="vendo-path-title">A question travels from the panel to your route, through the turn and the guard, to your API, and streams back to the panel.</title>

  <defs>
    <marker id="vendo-flow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor" />
    </marker>

    <marker id="vendo-flow-brand" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="#6c3bff" />
    </marker>
  </defs>

  <rect x="364" y="8" width="160" height="44" rx="10" fill="none" stroke="#6c3bff" strokeOpacity="0.55" strokeDasharray="4 4" />

  <text x="444" y="27" textAnchor="middle" fontSize="12" fontWeight="600" fill="#6c3bff">Vendo Cloud</text>
  <text x="444" y="42" textAnchor="middle" fontSize="10" fill="#6c3bff" fillOpacity="0.8">model · sandbox · store</text>

  <path d="M 444 52 L 444 80" stroke="#6c3bff" strokeOpacity="0.55" strokeWidth="1.5" strokeDasharray="4 4" fill="none" markerEnd="url(#vendo-flow-brand)" />

  <rect x="16" y="84" width="112" height="52" rx="10" fill="none" stroke="currentColor" strokeOpacity="0.25" />

  <text x="72" y="106" textAnchor="middle" fontSize="12.5" fontWeight="600" fill="currentColor">Panel</text>
  <text x="72" y="122" textAnchor="middle" fontSize="10" fill="currentColor" fillOpacity="0.6">your page</text>

  <rect x="184" y="84" width="124" height="52" rx="10" fill="none" stroke="currentColor" strokeOpacity="0.25" />

  <text x="246" y="106" textAnchor="middle" fontSize="12.5" fontWeight="600" fill="currentColor">Your route</text>
  <text x="246" y="122" textAnchor="middle" fontSize="10" fill="currentColor" fillOpacity="0.6">/api/vendo</text>

  <rect x="364" y="84" width="160" height="52" rx="10" fill="none" stroke="currentColor" strokeOpacity="0.25" />

  <text x="444" y="106" textAnchor="middle" fontSize="12.5" fontWeight="600" fill="currentColor">The turn</text>
  <text x="444" y="122" textAnchor="middle" fontSize="10" fill="currentColor" fillOpacity="0.6">harness, then guard</text>

  <rect x="580" y="84" width="112" height="52" rx="10" fill="none" stroke="currentColor" strokeOpacity="0.25" />

  <text x="636" y="106" textAnchor="middle" fontSize="12.5" fontWeight="600" fill="currentColor">Your API</text>
  <text x="636" y="122" textAnchor="middle" fontSize="10" fill="currentColor" fillOpacity="0.6">as this user</text>

  <path d="M 132 110 L 180 110" stroke="currentColor" strokeOpacity="0.45" strokeWidth="1.5" fill="none" markerEnd="url(#vendo-flow)" />

  <path d="M 312 110 L 360 110" stroke="currentColor" strokeOpacity="0.45" strokeWidth="1.5" fill="none" markerEnd="url(#vendo-flow)" />

  <path d="M 528 110 L 576 110" stroke="currentColor" strokeOpacity="0.45" strokeWidth="1.5" fill="none" markerEnd="url(#vendo-flow)" />

  <text x="156" y="100" textAnchor="middle" fontSize="9.5" fill="currentColor" fillOpacity="0.55">asks</text>
  <text x="336" y="100" textAnchor="middle" fontSize="9.5" fill="currentColor" fillOpacity="0.55">runs</text>
  <text x="552" y="100" textAnchor="middle" fontSize="9.5" fill="currentColor" fillOpacity="0.55">calls</text>

  <path d="M 444 136 L 444 172 L 72 172 L 72 140" stroke="#6c3bff" strokeOpacity="0.7" strokeWidth="1.5" fill="none" markerEnd="url(#vendo-flow-brand)" />

  <text x="258" y="190" textAnchor="middle" fontSize="10.5" fill="#6c3bff">text, tool beats, and a live screen, streamed back through your route</text>
</svg>

## The path of one question

<Steps>
  <Step title="The panel posts the question">
    The panel sends `POST /api/vendo/threads` and reads the reply as a stream.
    `baseUrl` on the provider decides that path. The body carries the question and
    a snapshot of what the user is looking at, and nothing else leaves the browser.
  </Step>

  <Step title="Your route answers who is asking">
    `vendo init` writes two files, both ordinary source you can read and change: a
    composition module that calls `createVendo`, and a thin route that serves it.

    ```ts lib/vendo.ts theme={null}
    import { clerk } from "@vendoai/vendo/auth/clerk";
    import { createVendo, guard } from "@vendoai/vendo/server";

    export const vendo = createVendo({
      auth: clerk(),
      guard: guard({ policy: {} }),
    });
    ```

    ```ts app/api/vendo/[...vendo]/route.ts theme={null}
    import { nextVendoHandler } from "@vendoai/vendo/server";
    import { vendo } from "@/lib/vendo";

    export const { GET, POST, PUT, PATCH, DELETE } = nextVendoHandler(vendo);
    ```

    `auth` is the one key everything identity-shaped hangs off. Init detects Auth.js,
    Clerk, Supabase, or Auth0 and writes the matching preset there, or the same
    object with a `principal` for you to fill in when it finds no library. Vendo
    mints no identity of its own, so a visitor your resolver cannot place is refused
    the turn.
  </Step>

  <Step title="The turn runs on your server">
    The harness runs the loop in your own process, and its tools are your API
    (extracted into `.vendo/tools.json` by `vendo init`, refreshed by `vendo sync`)
    plus Vendo's own tools for building screens. `VENDO_API_KEY` answers the model
    over the Vendo Cloud gateway, and a `models:` selection sends the call to your
    own provider instead. [Model credentials](/production/model-credentials) has both.
  </Step>

  <Step title="The guard grades every call">
    Every tool call passes the guard before it runs. Reads and writes run;
    destructive calls, and anything sync could not grade, park the turn on an
    approval card showing the exact request, and approving it resumes that same
    turn. The decision is server-side, and [approvals](/howto/approvals) has the
    rules.
  </Step>

  <Step title="Your API runs the call">
    The call reaches your own endpoint as the person who is signed in. The agent
    can do what that person could already do by clicking, and nothing more.
  </Step>

  <Step title="A screen comes back instead of a paragraph">
    When the answer is one to look at, the agent calls `vendo_make` and Vendo
    assembles a screen — or, with the person's yes, builds a small app once in a
    disposable Cloud sandbox and seals the result. It streams into the transcript
    as it forms and lands interactive, bound to live data from your own tools,
    ready to pin into a
    [`VendoSlot`](/product/mount-the-surface#slots) on your page.
  </Step>
</Steps>

## What runs where

| Piece                         | Where it runs                                                                                    |
| ----------------------------- | ------------------------------------------------------------------------------------------------ |
| Panel, slots                  | Your browser, out of your own bundle                                                             |
| The route and the composition | Your server, in your process                                                                     |
| Your API and your database    | Yours, untouched                                                                                 |
| The model                     | The Vendo Cloud gateway keyed by `VENDO_API_KEY`, or your own provider when `models` selects one |
| Threads, apps, grants, audit  | Hosted Postgres behind the same key                                                              |
| Building a generated app      | A disposable Cloud sandbox behind the same key                                                   |

One key fills the model, store, and sandbox slots your composition left unset —
nothing to provision, and nothing to run.

## What the agent can see

Each send carries a small `[Context]` bundle for that turn only.

* The accessibility tree of the visible page, with the URL and title on top,
  capped at 8 KB.
* Anything you publish yourself with [`useVendoContext`](/customize/context).
* It rides the request and never enters the transcript.
* Elements marked `data-vendo-ignore` are left out, and
  `captureScreen={false}` on the provider turns the page snapshot off entirely.
