svrnty-hermes-webui-plugin/CONNECTION-MAP.md
Svrnty d61f9e8d3f
Some checks failed
plugin-tests / test (push) Failing after 6s
feat(bte panel): wire grid to live /api/query/assetDtos (replaces 404'd assetGrid)
JP question: 'is there any way to see the generated images by the cmo inside the bte panel app'.

The Command Center PRD §5.4 specifies `/api/query/assetGrid` for the grid;
that endpoint isn't implemented yet on BTE. But `/api/query/assetDtos`
WORKS today and returns every brand-scoped asset including the ones CMO
just generated via bte_image_generate (asset ids 664787c4-... + dbe21e15-...).

Changes:
- routes/bte_proxy.py: allowlist /api/query/assetDtos + /api/assets/{id}/image
  (the latter so panel can render real PNG thumbnails — not just /thumb stubs)
- static/bte.js: _refreshGrid now POSTs assetDtos with {pageSize:48, sortBy:createdAt desc}.
  AssetDto rows normalized to panel's existing asset shape (id, thumbUrl,
  lifecycle, scores, prompt, dims). thumbUrl points at the live image bytes
  via the new proxy allowlist entry. _renderGrid stays untouched — same
  shape it expected.

Result: BTE panel grid now shows every Plan B asset including freshly-
generated CMO images. Polling stops when no in-flight renders remain.

When BTE Command Center §5.4 ships the real assetGrid endpoint, swap
the path back — frontend won't need any other change.

Karpathy 4 rules: smallest possible adapter (normalize one shape to another,
no abstraction added), surgical (one new allowlist entry, one function body
rewritten, no other panel logic touched), verified via curl that assetDtos
returns 10 assets including the CMO-generated ones before committing.
2026-05-24 14:15:22 -04:00

66 lines
3.7 KiB
Markdown

# CONNECTION MAP — svrnty-hermes-webui-plugin → nesquena/hermes-webui
**Upstream version:** v0.51.118
**Plugin version:** 0.5.0
**Total dependencies:** 33 (24 public API · 0 forced internal · 9 frontend)
> **Auto-generated by `scripts/ast-connection-map.py`. Do not hand-edit.**
> To change a justification, edit the `# CONNECTION:` comment above the
> relevant import and re-run the script.
---
## Public API dependencies (via loader-provided `api`)
| Plugin location | Upstream symbol | Snippet |
|---|---|---|
| `plugin.py:29` | `api.logger` | `log = api.logger("svrnty.plugin")` |
| `plugin.py:34` | `api.register_static` | `api.register_static(STATIC_PREFIX, str(STATIC_DIR))` |
| `plugin.py:35` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/app.css")` |
| `plugin.py:36` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/app.js")` |
| `plugin.py:39` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/svrnty_nav.js")` |
| `plugin.py:42` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/adwright.css")` |
| `plugin.py:43` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/adwright.js")` |
| `plugin.py:45` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/bte.css")` |
| `plugin.py:46` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/bte.js")` |
| `routes/adwright.py:68` | `api.logger` | `log = api.logger("svrnty.routes.adwright")` |
| `routes/adwright.py:69` | `api.register_route` | `api.register_route(` |
| `routes/adwright.py:71` | `api.register_route` | `api.register_route(` |
| `routes/bte_proxy.py:90` | `api.logger` | `log = api.logger("svrnty.routes.bte_proxy")` |
| `routes/bte_proxy.py:91` | `api.register_route` | `api.register_route("/api/bte/proxy", "GET", _handle_proxy)` |
| `routes/bte_proxy.py:92` | `api.register_route` | `api.register_route("/api/bte/proxy", "POST", _handle_proxy)` |
| `routes/transcribe.py:37` | `api.logger` | `log = api.logger("svrnty.routes.transcribe")` |
| `routes/transcribe.py:38` | `api.register_route` | `api.register_route("/api/transcribe", "POST", _handle_transcribe)` |
| `routes/transcribe.py:39` | `api.register_audio_attachment_processor` | `api.register_audio_attachment_processor(_transcribe_audio_attachments)` |
| `routes/umbrella.py:30` | `api.logger` | `log = api.logger("svrnty.routes.umbrella")` |
| `routes/umbrella.py:31` | `api.register_route` | `api.register_route("/umbrella", "GET", _handle_panel_html)` |
| `routes/umbrella.py:32` | `api.register_route` | `api.register_route("/api/umbrella", "GET", _handle_graph_json)` |
| `routes/umbrella.py:33` | `api.register_route` | `api.register_route("/api/umbrella/doc", "GET", _handle_doc_body)` |
| `routes/vault_status.py:19` | `api.logger` | `log = api.logger("svrnty.routes.vault_status")` |
| `routes/vault_status.py:20` | `api.register_route` | `api.register_route("/api/vault/status", "GET", _handle_vault_status)` |
---
## Forced internal dependencies (Rule 2 escape hatch)
Each row requires a `# CONNECTION: <reason>` comment in source.
_None. Plugin uses only the public API._
---
## Frontend dependencies (static/*.js → /api/* URLs)
| File | Line | URL |
|---|---|---|
| `static/bte.js` | 329 | `/api/command/requestPhotoshoot` |
| `static/bte.js` | 360 | `/api/query/assetDtos` |
| `static/bte.js` | 372 | `/api/assets/` |
| `static/bte.js` | 481 | `/api/command/rateAsset` |
| `static/adwright.js` | 168 | `/api/profile/switch` |
| `static/adwright.js` | 189 | `/api/profile/active` |
| `static/adwright.js` | 539 | `/api/adwright/provision-creds` |
| `static/umbrella.js` | 41 | `/api/umbrella` |
| `static/app.js` | 165 | `/api/vault/status` |