2026 03 23 Command Center Single Pipe Design

Documentation for Plans

Command Center Single-Pipe Architecture — Option B Design

Date: 2026-03-23 Session: S262 Status: Approved Scope: Consolidate Command Center to use Vitto SSE as the single real-time pipe. Remove WebSocket. Forward MCP decision events from ai-api into Vitto's SSE stream.


Problem

The Command Center has two real-time connections: SSE (Vitto engine events) + WebSocket (MCP decision events). The WebSocket path is effectively dead — nothing reliably pushes events to it. The MCP workflow panels show stale autoFlashState data from previous sessions, not live data.

Meanwhile, 12K+ MCP decisions in ai-api's MongoDB are valuable but invisible in real-time because nothing bridges them to the SSE stream.

Solution

1. Add event injection endpoint to vitto-api

New endpoint: POST /engine/events/external

Accepts events from trusted internal services (ai-api) and injects them into the SSE subject. Protected by a system token (not user JWT — this is service-to-service).

// vitto-core.controller.ts
@Post('events/external')
injectExternalEvent(@Body() event: { type: string; data: Record<string, unknown> }) {
  this.engine.injectExternalEvent(event);
  return { success: true };
}
// vitto-engine.service.ts
injectExternalEvent(event: { type: string; data: Record<string, unknown> }) {
  this.sseSubject.next({
    type: event.type as SSEEventType,
    taskId: 'external',
    data: event.data,
    timestamp: new Date().toISOString(),
  });
}

2. Forward decision events from ai-api to vitto-api

In decision.service.ts, after persisting a decision, POST to vitto-api's new endpoint:

// After this.decisionModel.create(...)
this.forwardToVittoSSE('decision.created', {
  decisionId, question, chosen, confidence, type, agentId
});

Uses HttpService (Axios) to call http://localhost:3003/vitto-api/engine/events/external.

3. Add decision event handlers to VittoMonitorService

New SSE event types handled:

4. Remove WebSocket from Command Center component

Delete:

Keep:

5. Add REST init calls for decision data

On component init, fetch current stats from ai-api:

These provide initial state. SSE provides real-time updates thereafter.

Files Modified

File Change
APIs/backend-vitto-api/src/app/engine/vitto-engine.service.ts Add injectExternalEvent() method
APIs/backend-vitto-api/src/app/engine/controllers/vitto-core.controller.ts Add POST events/external endpoint
APIs/backend-vitto-api/src/app/types/vitto.types.ts Extend SSEEventType with decision.* types
APIs/backend-ai-api/src/app/infrastructure/services/decision.service.ts Add forwarding to vitto-api after persist
libs/libs-ai/vitto-hub/src/lib/services/vitto-monitor.service.ts Add handlers for decision.created
libs/libs-ai/gograb-ai-lib/src/lib/services/vitto-monitor.service.ts Same (duplicate copy)
libs/libs-ai/gograb-ai-lib/src/lib/components/command-center/command-center.component.ts Remove WebSocket, remove stale autoFlashState signals, simplify
libs/libs-ai/gograb-ai-lib/src/lib/components/command-center/command-center.component.html Remove MCP pipeline/memory/timeline panels