Architecture: How should Vitto gain awareness of form state, available act...
Documentation for Sessions
🏗️ Architecture: How should Vitto gain awareness of form state, available act...
Date: 2026-03-04
Time: 16:32:23 UTC
Session: gspace1-175.6
Agent: angular
Confidence: 91%
Status: ✅ Documented
📋 Decision Context
Question:
How should Vitto gain awareness of form state, available actions, and per-page context so it can read fields, execute actions, and provide route-scoped suggestions?
Task: Session 175: Super Vitto Context Plan — Phase C: Form-Aware Context + VittoPageContextRegistry
🎯 Decision Made
Chosen:
Created VittoPageContextRegistry as a root-level injectable service in @libs-ai/vitto-core. Each routed component registers/unregisters via ngOnInit/ngOnDestroy with a VittoPageContextProvider containing: pageDescription signal, readableState (form fields), actions array (VittoPageAction with handler functions), suggestions array, and scopedTools. Created VittoPageAction interface with name, description, parameters schema, and handler function. Registered 4 context providers: SkillBuilder (fillSkillForm, saveSkill, clearForm actions), WorkflowBuilder (createWorkflow action), ChannelManager, MemoryManager. Enhanced VittoChatContextService.systemPromptEnrichment to merge registry contextEnrichment. Added action execution pipeline in VittoChatEngineService.detectAndExecutePageActions() that parses ```action blocks from LLM responses.
Options Considered:
- Centralized VittoPageContextRegistry with per-route providers (chosen — CopilotKit pattern)
- Decorator-based approach (@VittoContext on component class)
- postMessage bridge between chat iframe and content components
- Global signal store with convention-based keys per route
💭 Reasoning
The registry pattern (inspired by CopilotKit's useCopilotReadable/useCopilotAction) is the most Angular-native approach. Components register themselves using inject() and standard lifecycle hooks — no decorators, no magic. The registry uses a Map<string, Provider> with exact-route-then-parent-route matching. Signals give zero-overhead reactivity: when a form field changes, the computed contextEnrichment signal updates automatically, and VittoChatContextService picks it up in its own systemPromptEnrichment computed. This is fundamentally faster than any postMessage bridge because there's no serialization — it's direct signal reads within the same Angular DI tree. The action execution pipeline uses a simple ```action code block convention that the LLM can generate, parsed by detectAndExecutePageActions().
📁 Files Involved
libs/libs-ai/vitto-core/src/lib/services/vitto-page-context-registry.service.tslibs/libs-ai/vitto-core/src/index.tslibs/libs-ai/vitto-hub/src/lib/components/skill-studio/skill-builder/skill-builder.component.tslibs/libs-ai/vitto-hub/src/lib/components/workflow-builder-page/workflow-builder-page.component.tslibs/libs-ai/vitto-hub/src/lib/components/channel-manager/channel-manager.component.tslibs/libs-ai/vitto-hub/src/lib/components/memory-manager/memory-manager.component.tslibs/libs-ai/vitto-chat/src/lib/services/vitto-chat-context.service.tslibs/libs-ai/vitto-chat/src/lib/services/vitto-chat-engine.service.tslibs/libs-ai/vitto-chat/src/lib/plugins/suggestions.plugin.ts
🔗 Related
- Decision ID:
dev_1772641943066_wxyu7gz - Session: 175
- Workspace: gspace1
Auto-generated by MCP Smart Consolidation