Generative UI Personalization
Status: future vision. This document describes the long-term direction for personalizing SkillNet’s interface via agents. It is not an immediate implementation plan — it is the north star that guides architecture decisions.
The thesis
The UI adapts to the user, not the user to the UI. An agent observes how each person uses the platform and generates, proposes, or modifies the interface in real time using OpenUI Lang — the same engine that already generates lessons.
Three levels
Level 1 — Basic preferences (partially implemented)
The agent can change app settings via tool calls over SSE.
set_locale(locale)— changes the interface languageset_sidebar_collapsed(collapsed)— collapses/expands the sidebar
Existing infrastructure (2026-08-07):
- Zustand store (
stores/preferences.ts) persisted in localStorage - Tool registry (
lib/toolRegistry.ts) dispatched from SSEactionevents - Backend:
chat_service.pyparsesACTION:lines from the LLM and emits SSE events - Prompts:
llm/prompts/tools.pyteaches the LLM the available tools - i18n: react-intl with es/en catalogs, IntlProvider in App.tsx
Pending for level 1:
- Predefined color themes (3-5 sets of CSS variables)
- Layout variants (left sidebar, top bar, no sidebar)
- Backend persistence (
PATCH /users/me/preferences) for cross-device support
Level 2 — Custom widgets (the leap)
The admin or the employee can “pin” chat-generated artifacts to their dashboard.
Example: The admin asks the chat “what’s my team’s compliance %”. The chat generates a metric with OpenUI Lang and shows it inline. The admin says “keep it there” and the widget is persisted as an OpenUI program in their personalized dashboard.
Architecture:
User talks to the chat
-> The agent generates an OpenUI Lang program (as it already does for lessons)
-> The frontend renders it inline in the chat
-> The user says "pin it" (or the agent proposes it)
-> The program is persisted in `user_dashboard_widgets`
-> The dashboard renders it with the same <Renderer> used for lessons
Each user’s dashboard is a collection of OpenUI programs, each generated by the agent at some point and pinned by the user. There is no fixed dashboard for everyone — each person sees what matters to them.
Industry reference: A2UI (Google, 2026) defines createSurface / updateComponents
so agents can generate UI regions. AG-UI (CopilotKit, backed by Microsoft) defines the
transport protocol. SkillNet already has both de facto: SSE as transport and OpenUI Lang
as the surface format.
Level 3 — Proactive agent
An agent that runs in the background, observes usage patterns, and proposes personalizations without the user asking for them.
Examples:
- “This admin checks the compliance % every Monday” -> generates the widget for them and offers it the next time they open the app.
- “This employee always asks about allergens before starting their shift” -> adds a quick cheat sheet to their dashboard.
- “This admin never uses the skill map” -> offers to hide it from their sidebar.
- “This employee always fails the same type of question” -> the tutor adjusts the content without the admin having to intervene.
Mechanism:
- A cron or per-session trigger that analyzes
learning_eventsandllm_usage_log - The agent generates a proposal (widget, adjustment, recommendation)
- The proposal is shown as a notification or a proactive message from the buddy
- The user accepts, rejects, or modifies it
Inspiration: Brilliant’s Koji observes what you do and adjusts its level of help. Here it’s the same idea but for the whole platform, not just a single lesson.
Design principle
“Good personalization makes itself invisible. The user does not configure the app — the app learns the user.”
Personalization is not a settings panel with 50 options. It’s an agent that observes, proposes, and executes. The user always has control (they can reject, revert, request changes) but never has to hunt for the option in a menu.
Recommended implementation order
- Complete level 1: color themes + layout variants + backend persistence
- Minimal level 2: one pinnable widget from the chat (proof of concept)
- Full level 2: personalized dashboard with multiple widgets
- Level 3: proactive agent with a usage-analysis cron
Technical dependencies
- OpenUI Lang — already implemented, it’s the rendering engine
- SSE action events — already implemented, it’s the transport
- Tool registry — already implemented, it’s the dispatch
- Zustand store — already implemented, it’s the local persistence
- react-intl — already implemented, it’s the basic i18n
- Dashboard widget table — to be created (model + API + frontend)
- Usage analytics agent — to be created (cron + LangGraph + trigger rules)
User authority over presentation
Inferred personalization never contradicts an explicit request. If a person asks for an
explanation with images, audio, video, or text and the kit has that modality available,
that choice prevails over the format_vector, the heuristics, and the agent’s
recommendations.
That doesn’t force the whole experience into a single form. Within the requested modality, SkillNet can combine distinct pedagogical functions — for example, visual explanation, active retrieval, self-explanation, and scenario — as long as it does not hide or replace what the person asked for. The system can suggest alternatives, but the change requires acceptance.
The separation between presentation preference, accessibility, pedagogical strategy, and
component is defined in adaptive-learning.md.