Python: serving the SPA

How agency-django boots the Agency desktop SPA and pushes live catalog rows. Schema shape: UI Schema. Vue components: Frontend components (agency-ui).

Bootstrap shell

agency.views.ui renders templates/agency/ui/index.html with:

  • Vite manifest → hashed JS/CSS under /static/agency/ui/

  • #agency-bootstrap JSON: user, prefs (workspaceId + desktop), apiBase, websocket, ui (desktop document)

Product URL: /. Login: /login/ (mode: login bootstrap). The shell is an installable PWA: /manifest.webmanifest + /sw.js (scope /). /health/ returns boot_id / ui_build so the SPA can reload after a backend restart. /offline.html is the cached wait screen. Preferences API: GET/PATCH /api/me/prefs/. Window geometry and chrome pose for the session are mirrored into prefs.desktop (see UI). agency.ui.pose.parse_pose accepts numbers only.

Desktop schema

Default desktop layout: agency/data/default_desktop.json (dock icons, window defs). Window ids use the address grammar (agents, documents, …).

Host apps can extend via their own schema producers; live geometry lives in the frontend windowsStore and is persisted via user prefs, not in the schema document.

Live lists (observe)

Register a model once:

from agency.channel.observe import observe

observe(
    Execution,
    resource="execution",
    card=execution_catalog_card,
    fetch=lambda pk: Execution.objects.select_related("mission", "agent").get(pk=pk),
)

On save/delete → catalog bus envelope on /channel/ (group users) → SPA catalog projector updates explorer lists without polling. Card shape = list serializer fields.

Catalog hydrates (agent, mission, tool, model, provider) walk every DRF page (fetchList). Default PAGE_SIZE is 10 — keeping only results drops rows such as tools.tavily.internet_search. Timelines (executions, tasks) stay paged.

To add a resource:

  1. Django: observe(...) + list API

  2. agency-ui: registerObserveBucket in the owning Pinia store

  3. No new resource-specific event — same catalog envelope (<resource>.<id>.catalog.<action>)

Wire details: Connections.