Architecture
Wholisphere has two independent surfaces: the scan-and-report pipeline (which finds WCAG issues and renders an honest VPAT from what it found), and the assistive agent — an opt-in tool that adapts a page for the individual end user. It never remediates the site itself and never injects fixes into a visitor’s browser for compliance; it serves the reader who chose to turn it on. Two layers:
┌──────────────────────────────────────────────────────────┐│ ASSISTIVE RUNTIME CLIENT (end-user tool) ││ • Browser extension OR embed script (one engine) ││ • Floating Shadow-DOM landmark widget (AAA) ││ • Local TTS / STT (Web Speech) — sub-50ms, no network ││ • Calls the backend only for vision / LLM reasoning │└──────────────────────────────────────────────────────────┘ │ on demand ▼┌──────────────────────────────────────────────────────────┐│ BACKEND API (Cloudflare Workers) ││ • /v1/describe, /v1/read-page, /v1/intent, … ││ • Content-addressed response cache (KV): identical ││ requests (same image + context) skip the paid call ││ • Multi-model LLM router (Gemini + Claude + Mock) │└──────────────────────────────────────────────────────────┘Why the response cache
A naive deploy would call the LLM on every user interaction — slow and expensive at scale. Because an image’s description is identical for everyone, the backend caches each result by a content hash of the image plus its context: the first request for a given image pays for the vision call, and every request after it is served from cache in milliseconds.
| Property | Naive (LLM on every call) | Wholisphere (content-addressed cache) |
|---|---|---|
| Repeat-image latency | 800–2500 ms | cache hit, milliseconds |
| Vision cost | one paid call per view | one paid call per distinct image |
Multi-model LLM routing
Same prompt, multiple providers. Today: Gemini Flash + Claude Sonnet + Mock. Routing strategy:
fast/balanced→ Gemini Flash (~30× cheaper per image; fine for 80% of calls)accurate/vision→ Claude Sonnet (better small-element + low-contrast OCR)
The router falls through providers on retryable errors (5xx, 429, 529). Adding OpenAI is a one-file change.
Coexistence with native AT
The widget is role="complementary" with aria-label="Accessibility tools". JAWS / NVDA / VoiceOver users find it via the standard landmark navigation key (D in NVDA, VO+U in VoiceOver). They can:
- Ignore it entirely and continue using their native AT
- Engage one specific tool (“describe this image please”)
- Delegate the whole page to the agent
We never override or fake screen-reader output. We’re additive, not replacement.
Audit trail
Every agent action is logged: timestamp, URL, capability invoked, outcome, duration. Logs live in D1 (12 months hot) and R2 (5 years cold). Customers can export as JSON or stream via webhooks. Court-defensible.