feat(graph): continual-learning graph data model + dark-Bauhaus viz
Adds the team_model graph layer (the "it learned" view) and its visualization,
per docs/graph.md. Demo-backed first; built on origin/main conventions.
- shared: PodGraph / node / edge / metric types + GraphNodeDoc / GraphEdgeDoc
- backend/src/graph: demo graph data; Mongo store (loadPodGraph w/ demo
fallback, seedGraph, reachFrom via $graphLookup); graph:seed script
- backend/src/server.ts: additive GET /api/pods/:id/graph + /graph/reach/:node
- frontend: dark-Bauhaus GraphView + fetch helper, reachable from a
"Team memory" toggle in App.tsx
- docs/graph.md: spec (data model, $graphLookup, API, demo-first plan)
Demo-backed: the route serves a grounded demo graph when team_model has no
graph yet; graph:seed writes team_model + graph_nodes/graph_edges so the
$graphLookup traversal is real. Swap loadPodGraph to live team_model later.
Known follow-ups before merge: branch is based on 65a0791; origin/main is now
at 1294b84, so this needs a rebase + App.tsx conflict resolution (teammate
rewrote App.tsx with live room view / one-click join).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+19
-7
@@ -6,6 +6,7 @@ import * as api from './lib/api.js';
|
||||
import { PodCard } from './components/PodCard.js';
|
||||
import { CreatePodForm } from './components/CreatePodForm.js';
|
||||
import { PodView } from './components/PodView.js';
|
||||
import { GraphView } from './components/GraphView.js';
|
||||
|
||||
const SESSION_KEY = 'podman.session';
|
||||
|
||||
@@ -22,6 +23,7 @@ export default function App() {
|
||||
const [devMode, setDevMode] = useState(false);
|
||||
const [room, setRoom] = useState<Room | null>(null);
|
||||
const [restoring, setRestoring] = useState(false);
|
||||
const [graphPodId, setGraphPodId] = useState<string | null>(null);
|
||||
|
||||
const joinedPod = joinedPodId ? (pods.find((p) => p.id === joinedPodId) ?? null) : null;
|
||||
|
||||
@@ -209,19 +211,29 @@ export default function App() {
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
) : graphPodId ? (
|
||||
<GraphView podId={graphPodId} onClose={() => setGraphPodId(null)} />
|
||||
) : (
|
||||
<main className="flex flex-col gap-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="text-sm font-medium text-slate-400">
|
||||
Pods {loading ? '…' : `(${pods.length})`}
|
||||
</h2>
|
||||
<button
|
||||
className="text-xs text-slate-400 hover:text-slate-200 disabled:opacity-50"
|
||||
onClick={() => void refresh()}
|
||||
disabled={loading}
|
||||
>
|
||||
↻ Refresh
|
||||
</button>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
className="text-xs text-slate-400 hover:text-slate-200"
|
||||
onClick={() => setGraphPodId(pods[0]?.id ?? 'demo-pod')}
|
||||
>
|
||||
◇ Team memory
|
||||
</button>
|
||||
<button
|
||||
className="text-xs text-slate-400 hover:text-slate-200 disabled:opacity-50"
|
||||
onClick={() => void refresh()}
|
||||
disabled={loading}
|
||||
>
|
||||
↻ Refresh
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
|
||||
Reference in New Issue
Block a user