forked from CopilotKit/CopilotKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchips-explainer.tsx
More file actions
122 lines (114 loc) · 4.19 KB
/
Copy pathchips-explainer.tsx
File metadata and controls
122 lines (114 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"use client";
/**
* ChipsExplainer — collapsible "What do these chips mean?" panel that sits
* above StatsBar on the Cells tab. Default-collapsed; persists open/closed
* state across navigations via `localStorage["chip-explainer-open"]`.
*
* The Cells tab is consulted dozens of times a day by operators who already
* know what D0–D6 mean; the explainer is for first-time viewers / rare
* refreshers, so the trigger is small and the default is collapsed.
*/
import { useEffect, useId, useState } from "react";
const STORAGE_KEY = "chip-explainer-open";
const NOTION_URL =
"https://www.notion.so/copilotkit/34e3aa38185281d7bf2ac3ea9d474b36";
interface LayerDef {
id: string;
body: string;
}
const LAYERS: LayerDef[] = [
{ id: "D0", body: "is this feature wired up at all in this integration?" },
{
id: "D1",
body: "does the integration's server respond to a basic health ping?",
},
{ id: "D2", body: "does it respond to a basic Copilot API call?" },
{ id: "D3", body: "does the demo page even load in a browser?" },
{
id: "D4",
body: "can a human send a single chat message and get a sensible response?",
},
{
id: "D5",
body: "does the integration actually do its complex agentic stuff correctly? (multi-turn memory, tool-card rendering, shared-state read/write, HITL flows, gen-UI components, MCP/subagent chaining)",
},
{
id: "D6",
body: "does its behaviour match the reference (LangGraph Python), or has it drifted? (DOM elements, tool-call sequence, stream cadence, contract shape — informational; weekly rotation)",
},
];
/**
* Read the persisted open flag synchronously on mount. Guarded against SSR
* (no `window` / `localStorage` on the server) — defaults to collapsed there.
*/
function readPersistedOpen(): boolean {
if (typeof window === "undefined") return false;
try {
return window.localStorage.getItem(STORAGE_KEY) === "true";
} catch {
// localStorage can throw in private-mode Safari; fall back to default.
return false;
}
}
export function ChipsExplainer() {
// Initialize from localStorage so the first paint matches the persisted
// state (no flash from collapsed → expanded on revisit). The same read
// also runs on the server during SSR but returns false safely.
const [open, setOpen] = useState<boolean>(readPersistedOpen);
const panelId = useId();
// Persist on every change. Wrapped in a try/catch so quota / private-mode
// failures don't break the UI.
useEffect(() => {
if (typeof window === "undefined") return;
try {
window.localStorage.setItem(STORAGE_KEY, open ? "true" : "false");
} catch {
// ignore — UI state still works without persistence.
}
}, [open]);
const chevron = open ? "\u25BE" : "\u25B8"; // ▾ / ▸
return (
<div data-testid="chips-explainer" className="px-4 pt-2">
<button
type="button"
aria-expanded={open}
aria-controls={panelId}
onClick={() => setOpen((v) => !v)}
className="inline-flex items-center gap-1.5 text-xs text-[var(--text-muted)] hover:text-[var(--text)] focus:outline-none focus-visible:ring-1 focus-visible:ring-[var(--accent)] rounded"
>
<span aria-hidden="true" className="tabular-nums">
{chevron}
</span>
<span>What do these chips mean?</span>
</button>
{open && (
<div
id={panelId}
data-testid="chips-explainer-panel"
className="mt-2 rounded-md border border-[var(--text-muted)]/20 bg-[var(--text-muted)]/5 px-4 py-3 text-xs text-[var(--text)]"
>
<ul className="space-y-1.5">
{LAYERS.map((layer) => (
<li key={layer.id}>
<span className="font-semibold text-[var(--accent)]">
{layer.id}:
</span>{" "}
<span>{layer.body}</span>
</li>
))}
</ul>
<div className="mt-3">
<a
href={NOTION_URL}
target="_blank"
rel="noopener noreferrer"
className="text-[var(--accent)] hover:underline"
>
More detail →
</a>
</div>
</div>
)}
</div>
);
}