[perplexity] feat: Nexus v2 — Cognitive Awareness & Introspection Engine (#1090)
Extends the Nexus from a chat-only interface into a full cognitive awareness space with real-time introspection, persistent sessions, and sovereignty health monitoring. New modules (src/timmy/nexus/): - introspection.py — Aggregates CognitiveTracker, ThinkingEngine, and session analytics into a unified IntrospectionSnapshot. Surfaces mood, engagement, focus, commitments, and recent thoughts. - persistence.py — SQLite-backed NexusStore so conversations survive process restarts. WAL mode, auto-pruning at 500 messages, session-tag isolation for future per-operator sessions. - sovereignty_pulse.py — Reads the SovereigntyMetricsStore (PR #1331) and distils a live health pulse: per-layer sovereignty %, API independence rate, crystallization velocity. Enhanced routes (src/dashboard/routes/nexus.py): - GET /nexus — now serves introspection + pulse alongside chat - POST /nexus/chat — persists messages; tracks memory hits - DELETE /nexus/history — clears both in-memory and SQLite stores - GET /nexus/introspect — JSON API for introspection + sovereignty data - WS /nexus/ws — live push of cognitive state, thought stream, and sovereignty pulse every 5 seconds Enhanced template (nexus.html): - Cognitive State panel (mood, engagement, focus, depth, commitments) - Thought Stream viewer (5 most recent, seed type, timestamps) - Sovereignty Pulse badge + detail panel (per-layer bars, stats) - Session Analytics grid (message count, avg response, duration) - WebSocket client with auto-reconnect for live updates CSS (mission-control.css): - Full Nexus v2 design system: pulse badges, health indicators, cognitive grid, thought stream cards, sovereignty bar meters, analytics grid, scrollable sidebar Tests: 58 total (all green) - 20 introspection tests (data models, snapshot, fallback, cognitive/thought readers) - 18 persistence tests (CRUD, ordering, session tags, pruning, reopen) - 12 sovereignty pulse tests (classify health, snapshot, API independence) - 8 route/template tests (new panels, WebSocket script, introspect API) Refs: #1090
This commit is contained in:
@@ -2665,25 +2665,27 @@
|
||||
}
|
||||
.vs-btn-save:hover { opacity: 0.85; }
|
||||
|
||||
/* ── Nexus ────────────────────────────────────────────────── */
|
||||
.nexus-layout { max-width: 1400px; margin: 0 auto; }
|
||||
/* ── Nexus v2 ─────────────────────────────────────────────── */
|
||||
.nexus-layout { max-width: 1600px; margin: 0 auto; }
|
||||
|
||||
.nexus-header { border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; }
|
||||
.nexus-title { font-size: 1.4rem; font-weight: 700; color: var(--purple); letter-spacing: 0.1em; }
|
||||
.nexus-subtitle { font-size: 0.8rem; color: var(--text-dim); margin-top: 0.2rem; }
|
||||
|
||||
.nexus-grid {
|
||||
/* v2 grid: wider sidebar for awareness panels */
|
||||
.nexus-grid-v2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 320px;
|
||||
grid-template-columns: 1fr 360px;
|
||||
gap: 1rem;
|
||||
align-items: start;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.nexus-grid { grid-template-columns: 1fr; }
|
||||
@media (max-width: 1000px) {
|
||||
.nexus-grid-v2 { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.nexus-chat-panel { height: calc(100vh - 180px); display: flex; flex-direction: column; }
|
||||
.nexus-chat-panel .card-body { overflow-y: auto; flex: 1; }
|
||||
.nexus-msg-count { font-size: 0.7rem; color: var(--text-dim); letter-spacing: 0.05em; }
|
||||
|
||||
.nexus-empty-state {
|
||||
color: var(--text-dim);
|
||||
@@ -2693,6 +2695,177 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Sidebar scrollable on short screens */
|
||||
.nexus-sidebar-col { max-height: calc(100vh - 140px); overflow-y: auto; }
|
||||
|
||||
/* ── Sovereignty Pulse Badge (header) ── */
|
||||
.nexus-pulse-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 0.3rem 0.7rem;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.nexus-pulse-dot {
|
||||
width: 8px; height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
.nexus-pulse-dot.nexus-pulse-sovereign { background: var(--green); box-shadow: 0 0 6px var(--green); }
|
||||
.nexus-pulse-dot.nexus-pulse-degraded { background: var(--amber); box-shadow: 0 0 6px var(--amber); }
|
||||
.nexus-pulse-dot.nexus-pulse-dependent { background: var(--red); box-shadow: 0 0 6px var(--red); }
|
||||
.nexus-pulse-dot.nexus-pulse-unknown { background: var(--text-dim); }
|
||||
.nexus-pulse-label { color: var(--text-dim); }
|
||||
.nexus-pulse-value { color: var(--text-bright); font-weight: 600; }
|
||||
|
||||
/* ── Cognitive State Panel ── */
|
||||
.nexus-cognitive-panel .card-body { font-size: 0.78rem; }
|
||||
.nexus-engagement-badge {
|
||||
font-size: 0.65rem;
|
||||
letter-spacing: 0.08em;
|
||||
padding: 0.15rem 0.5rem;
|
||||
border-radius: 3px;
|
||||
background: rgba(168,85,247,0.12);
|
||||
color: var(--purple);
|
||||
}
|
||||
.nexus-cog-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.nexus-cog-item {
|
||||
background: rgba(255,255,255,0.02);
|
||||
border-radius: 4px;
|
||||
padding: 0.35rem 0.5rem;
|
||||
}
|
||||
.nexus-cog-label {
|
||||
font-size: 0.62rem;
|
||||
color: var(--text-dim);
|
||||
letter-spacing: 0.08em;
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.nexus-cog-value {
|
||||
color: var(--text-bright);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.nexus-cog-focus {
|
||||
font-size: 0.72rem;
|
||||
color: var(--text);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 140px;
|
||||
}
|
||||
.nexus-commitments { font-size: 0.72rem; }
|
||||
.nexus-commitment-item {
|
||||
color: var(--text);
|
||||
padding: 0.2rem 0;
|
||||
border-bottom: 1px solid rgba(59,26,92,0.4);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* ── Thought Stream Panel ── */
|
||||
.nexus-thoughts-panel .card-body { max-height: 200px; overflow-y: auto; }
|
||||
.nexus-thought-item {
|
||||
border-left: 2px solid var(--purple);
|
||||
padding: 0.3rem 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 0.76rem;
|
||||
background: rgba(168,85,247,0.04);
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.nexus-thought-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.nexus-thought-seed {
|
||||
color: var(--purple);
|
||||
font-size: 0.65rem;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.nexus-thought-time { color: var(--text-dim); font-size: 0.62rem; }
|
||||
.nexus-thought-content { color: var(--text); line-height: 1.4; }
|
||||
|
||||
/* ── Sovereignty Pulse Detail Panel ── */
|
||||
.nexus-health-badge {
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.08em;
|
||||
padding: 0.15rem 0.5rem;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.nexus-health-sovereign { background: rgba(0,232,122,0.12); color: var(--green); }
|
||||
.nexus-health-degraded { background: rgba(255,184,0,0.12); color: var(--amber); }
|
||||
.nexus-health-dependent { background: rgba(255,68,85,0.12); color: var(--red); }
|
||||
.nexus-health-unknown { background: rgba(107,74,138,0.12); color: var(--text-dim); }
|
||||
|
||||
.nexus-pulse-layer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
margin-bottom: 0.35rem;
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
.nexus-pulse-layer-label {
|
||||
color: var(--text-dim);
|
||||
min-width: 80px;
|
||||
letter-spacing: 0.06em;
|
||||
font-size: 0.65rem;
|
||||
}
|
||||
.nexus-pulse-bar-track {
|
||||
flex: 1;
|
||||
height: 6px;
|
||||
background: rgba(59,26,92,0.5);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.nexus-pulse-bar-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, var(--purple), var(--green));
|
||||
border-radius: 3px;
|
||||
transition: width 0.6s ease;
|
||||
}
|
||||
.nexus-pulse-layer-pct {
|
||||
color: var(--text-bright);
|
||||
font-size: 0.68rem;
|
||||
min-width: 36px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.nexus-pulse-stats { font-size: 0.72rem; }
|
||||
.nexus-pulse-stat {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.2rem 0;
|
||||
border-bottom: 1px solid rgba(59,26,92,0.3);
|
||||
}
|
||||
.nexus-pulse-stat-label { color: var(--text-dim); }
|
||||
.nexus-pulse-stat-value { color: var(--text-bright); }
|
||||
|
||||
/* ── Session Analytics Panel ── */
|
||||
.nexus-analytics-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.4rem;
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
.nexus-analytics-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.25rem 0.4rem;
|
||||
background: rgba(255,255,255,0.02);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.nexus-analytics-label { color: var(--text-dim); }
|
||||
.nexus-analytics-value { color: var(--text-bright); }
|
||||
|
||||
/* Memory sidebar */
|
||||
.nexus-memory-hits { font-size: 0.78rem; }
|
||||
.nexus-memory-label { color: var(--text-dim); font-size: 0.72rem; margin-bottom: 0.4rem; letter-spacing: 0.05em; }
|
||||
|
||||
Reference in New Issue
Block a user