@copilotz/admin 0.9.38 → 0.9.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -45,6 +45,7 @@ __export(index_exports, {
45
45
  addUsageTotals: () => addUsageTotals,
46
46
  agentsModule: () => agentsModule,
47
47
  aggregateUsageRows: () => aggregateUsageRows,
48
+ brainModule: () => brainModule,
48
49
  buildUsageChartState: () => buildUsageChartState,
49
50
  canAccessAdminPermission: () => canAccessAdminPermission,
50
51
  collectAdminNavItems: () => collectAdminNavItems,
@@ -259,13 +260,16 @@ function createAdminClient(options = {}) {
259
260
  ),
260
261
  listAgents: async (listOptions = {}) => {
261
262
  const windowRange = getRangeWindow(listOptions.range ?? "7d");
262
- return await requestJson(`${paths.adminBase}/agents`, {
263
- search: listOptions.search,
264
- namespace: listOptions.namespace,
265
- from: windowRange.from,
266
- to: windowRange.to,
267
- limit: String(listOptions.limit ?? 25)
268
- });
263
+ return await requestJson(
264
+ `${paths.adminBase}/agents`,
265
+ {
266
+ search: listOptions.search,
267
+ namespace: listOptions.namespace,
268
+ from: windowRange.from,
269
+ to: windowRange.to,
270
+ limit: String(listOptions.limit ?? 25)
271
+ }
272
+ );
269
273
  },
270
274
  getThread: async (threadId) => await requestJson(
271
275
  `${paths.threadsBase}/${encodeURIComponent(threadId)}`
@@ -299,6 +303,19 @@ function createAdminClient(options = {}) {
299
303
  );
300
304
  return normalizeQueueEvent(payload);
301
305
  },
306
+ getBrain: async (filters = {}) => await requestJson(`${paths.adminBase}/brain`, {
307
+ namespace: filters.namespace,
308
+ memorySpaceId: filters.memorySpaceId,
309
+ checkpointId: filters.checkpointId,
310
+ agentId: filters.agentId,
311
+ threadId: filters.threadId,
312
+ layer: filters.layer === "all" ? void 0 : filters.layer,
313
+ kind: filters.kind === "all" ? void 0 : filters.kind,
314
+ status: filters.status === "all" ? void 0 : filters.status,
315
+ search: filters.search,
316
+ limit: String(filters.limit ?? 160),
317
+ offset: filters.offset ? String(filters.offset) : void 0
318
+ }),
302
319
  listCollections: async () => await requestJson(paths.collectionsBase),
303
320
  listCollectionItems: async (collection, listOptions = {}) => await requestJson(
304
321
  `${paths.collectionsBase}/${encodeURIComponent(collection)}`,
@@ -345,8 +362,8 @@ function createAdminClient(options = {}) {
345
362
  }
346
363
 
347
364
  // src/core/CopilotzAdmin.tsx
348
- var import_react10 = __toESM(require("react"), 1);
349
- var import_lucide_react13 = require("lucide-react");
365
+ var import_react11 = __toESM(require("react"), 1);
366
+ var import_lucide_react14 = require("lucide-react");
350
367
 
351
368
  // src/lib/utils.ts
352
369
  var import_clsx = require("clsx");
@@ -2001,19 +2018,491 @@ function AgentDetailPage({ context }) {
2001
2018
  ] });
2002
2019
  }
2003
2020
 
2004
- // src/modules/collections/index.tsx
2021
+ // src/modules/brain/index.tsx
2005
2022
  var import_react3 = __toESM(require("react"), 1);
2006
2023
  var import_lucide_react7 = require("lucide-react");
2007
2024
  var import_jsx_runtime21 = require("react/jsx-runtime");
2025
+ var BRAIN_LAYERS = ["all", "knowledge", "working"];
2026
+ var BRAIN_STATUSES = ["active", "all", "superseded", "archived"];
2027
+ var BRAIN_KINDS = [
2028
+ "all",
2029
+ "decision",
2030
+ "fact",
2031
+ "preference",
2032
+ "task",
2033
+ "constraint",
2034
+ "current_state",
2035
+ "challenge",
2036
+ "risk",
2037
+ "open_question",
2038
+ "next_action"
2039
+ ];
2040
+ function brainModule() {
2041
+ return {
2042
+ group: "data",
2043
+ icon: import_lucide_react7.Brain,
2044
+ id: "brain",
2045
+ label: "Brain",
2046
+ navItems: [{
2047
+ group: "data",
2048
+ icon: import_lucide_react7.Brain,
2049
+ id: "brain",
2050
+ label: "Brain",
2051
+ order: 10,
2052
+ routeId: "brain"
2053
+ }],
2054
+ routes: [{
2055
+ id: "brain",
2056
+ title: "Brain",
2057
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BrainPage, { context })
2058
+ }]
2059
+ };
2060
+ }
2061
+ function BrainPage({ context }) {
2062
+ const [search, setSearch] = import_react3.default.useState("");
2063
+ const [layer, setLayer] = import_react3.default.useState("all");
2064
+ const [status, setStatus] = import_react3.default.useState(
2065
+ "active"
2066
+ );
2067
+ const [kind, setKind] = import_react3.default.useState("all");
2068
+ const [agentId, setAgentId] = import_react3.default.useState("");
2069
+ const [response, setResponse] = import_react3.default.useState(
2070
+ null
2071
+ );
2072
+ const [selectedNode, setSelectedNode] = import_react3.default.useState(
2073
+ null
2074
+ );
2075
+ const [loading, setLoading] = import_react3.default.useState(false);
2076
+ const [error, setError] = import_react3.default.useState(null);
2077
+ const loadBrain = import_react3.default.useCallback(async () => {
2078
+ setLoading(true);
2079
+ setError(null);
2080
+ try {
2081
+ const next = await context.client.getBrain({
2082
+ namespace: context.scope.namespace || void 0,
2083
+ search: search.trim() || void 0,
2084
+ layer,
2085
+ status,
2086
+ kind,
2087
+ agentId: agentId.trim() || void 0,
2088
+ limit: 180
2089
+ });
2090
+ setResponse(next);
2091
+ setSelectedNode(
2092
+ (current) => current && next.nodes.some((node) => node.id === current.id) ? current : next.nodes[0] ?? null
2093
+ );
2094
+ } catch (cause) {
2095
+ setError(cause instanceof Error ? cause.message : "Failed to load brain");
2096
+ setResponse(null);
2097
+ setSelectedNode(null);
2098
+ } finally {
2099
+ setLoading(false);
2100
+ }
2101
+ }, [
2102
+ agentId,
2103
+ context.client,
2104
+ context.scope.namespace,
2105
+ kind,
2106
+ layer,
2107
+ search,
2108
+ status
2109
+ ]);
2110
+ import_react3.default.useEffect(() => {
2111
+ void loadBrain();
2112
+ }, [context.refreshKey, context.scope.namespace, loadBrain]);
2113
+ const data = response ?? emptyBrainResponse();
2114
+ const knowledgeCount = data.stats.byLayer.knowledge ?? 0;
2115
+ const workingCount = data.stats.byLayer.working ?? 0;
2116
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2117
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2118
+ PageHeader,
2119
+ {
2120
+ title: "Brain",
2121
+ description: "Unified knowledge and working state for the active namespace.",
2122
+ badges: [
2123
+ {
2124
+ label: context.scope.namespace ?? "all namespaces",
2125
+ variant: "secondary"
2126
+ }
2127
+ ],
2128
+ actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2129
+ Button,
2130
+ {
2131
+ disabled: loading,
2132
+ onClick: () => void loadBrain(),
2133
+ size: "sm",
2134
+ type: "button",
2135
+ variant: "outline",
2136
+ children: [
2137
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.RefreshCw, { className: cn("size-3", loading && "animate-spin") }),
2138
+ "Refresh"
2139
+ ]
2140
+ }
2141
+ )
2142
+ }
2143
+ ),
2144
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2145
+ MetricStrip,
2146
+ {
2147
+ items: [
2148
+ {
2149
+ label: "Brain nodes",
2150
+ value: data.stats.total,
2151
+ detail: `${data.pageInfo.returned} shown`,
2152
+ icon: import_lucide_react7.Brain
2153
+ },
2154
+ {
2155
+ label: "Knowledge",
2156
+ value: knowledgeCount,
2157
+ detail: "Durable nodes",
2158
+ icon: import_lucide_react7.CircleDot
2159
+ },
2160
+ {
2161
+ label: "Working",
2162
+ value: workingCount,
2163
+ detail: "Current state",
2164
+ icon: import_lucide_react7.Sparkles
2165
+ },
2166
+ {
2167
+ label: "Clusters",
2168
+ value: data.clusters.length,
2169
+ detail: "Layer and kind",
2170
+ icon: import_lucide_react7.Network
2171
+ }
2172
+ ]
2173
+ }
2174
+ ),
2175
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2176
+ FilterBar,
2177
+ {
2178
+ actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2179
+ Button,
2180
+ {
2181
+ disabled: loading,
2182
+ onClick: () => void loadBrain(),
2183
+ size: "sm",
2184
+ type: "button",
2185
+ children: [
2186
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Search, { className: "size-3" }),
2187
+ "Search"
2188
+ ]
2189
+ }
2190
+ ),
2191
+ onSearchChange: setSearch,
2192
+ searchPlaceholder: "Search brain",
2193
+ searchValue: search,
2194
+ children: [
2195
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2196
+ Select,
2197
+ {
2198
+ value: layer,
2199
+ onValueChange: (value) => setLayer(value),
2200
+ children: [
2201
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectTrigger, { className: "h-8 w-[140px] text-xs", "aria-label": "Layer", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectValue, {}) }),
2202
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectContent, { children: BRAIN_LAYERS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectItem, { value: option, children: option === "all" ? "All layers" : formatLabel(option) }, option)) })
2203
+ ]
2204
+ }
2205
+ ),
2206
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2207
+ Select,
2208
+ {
2209
+ value: status,
2210
+ onValueChange: (value) => setStatus(value),
2211
+ children: [
2212
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectTrigger, { className: "h-8 w-[140px] text-xs", "aria-label": "Status", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectValue, {}) }),
2213
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectContent, { children: BRAIN_STATUSES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectItem, { value: option, children: option === "all" ? "All statuses" : formatLabel(option) }, option)) })
2214
+ ]
2215
+ }
2216
+ ),
2217
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2218
+ Select,
2219
+ {
2220
+ value: kind,
2221
+ onValueChange: (value) => setKind(value),
2222
+ children: [
2223
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectTrigger, { className: "h-8 w-[170px] text-xs", "aria-label": "Kind", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectValue, {}) }),
2224
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectContent, { children: BRAIN_KINDS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectItem, { value: option, children: option === "all" ? "All kinds" : formatLabel(option) }, option)) })
2225
+ ]
2226
+ }
2227
+ ),
2228
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2229
+ Input,
2230
+ {
2231
+ className: "h-8 w-[190px]",
2232
+ onChange: (event) => setAgentId(event.target.value),
2233
+ onKeyDown: (event) => {
2234
+ if (event.key === "Enter") void loadBrain();
2235
+ },
2236
+ placeholder: "Agent ID",
2237
+ value: agentId
2238
+ }
2239
+ )
2240
+ ]
2241
+ }
2242
+ ),
2243
+ error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Unable to load brain", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2244
+ InspectorPanel,
2245
+ {
2246
+ side: selectedNode ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BrainNodeInspector, { node: selectedNode }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2247
+ EmptyState,
2248
+ {
2249
+ icon: import_lucide_react7.Brain,
2250
+ title: "No node selected",
2251
+ description: "Select a node from the map or table."
2252
+ }
2253
+ ),
2254
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2255
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2256
+ BrainMap,
2257
+ {
2258
+ clusters: data.clusters,
2259
+ edges: data.edges,
2260
+ loading,
2261
+ nodes: data.nodes,
2262
+ onSelectNode: setSelectedNode,
2263
+ selectedNodeId: selectedNode?.id ?? null
2264
+ }
2265
+ ),
2266
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2267
+ ResourceTable,
2268
+ {
2269
+ rows: data.nodes,
2270
+ getRowKey: (row) => row.id,
2271
+ onRowClick: setSelectedNode,
2272
+ empty: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2273
+ EmptyState,
2274
+ {
2275
+ icon: import_lucide_react7.Brain,
2276
+ title: loading ? "Loading brain" : "No brain nodes",
2277
+ description: loading ? "Fetching brain nodes for the active namespace." : "Knowledge and working-state nodes will appear here."
2278
+ }
2279
+ ),
2280
+ columns: [
2281
+ {
2282
+ id: "node",
2283
+ header: "Node",
2284
+ className: "max-w-[360px]",
2285
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "min-w-0", children: [
2286
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "truncate font-medium", children: row.name }),
2287
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: row.content || "-" })
2288
+ ] })
2289
+ },
2290
+ {
2291
+ id: "layer",
2292
+ header: "Layer",
2293
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: row.layer })
2294
+ },
2295
+ {
2296
+ id: "kind",
2297
+ header: "Kind",
2298
+ render: (row) => formatLabel(row.kind)
2299
+ },
2300
+ {
2301
+ id: "status",
2302
+ header: "Status",
2303
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { status: row.status })
2304
+ },
2305
+ {
2306
+ id: "agent",
2307
+ header: "Agent",
2308
+ className: "max-w-[160px] truncate font-mono text-xs",
2309
+ render: (row) => row.agentId ?? "-"
2310
+ }
2311
+ ]
2312
+ }
2313
+ )
2314
+ ] })
2315
+ }
2316
+ )
2317
+ ] });
2318
+ }
2319
+ function BrainMap({
2320
+ clusters,
2321
+ edges,
2322
+ loading,
2323
+ nodes,
2324
+ onSelectNode,
2325
+ selectedNodeId
2326
+ }) {
2327
+ const nodeById = import_react3.default.useMemo(
2328
+ () => new Map(nodes.map((node) => [node.id, node])),
2329
+ [nodes]
2330
+ );
2331
+ if (nodes.length === 0) {
2332
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex min-h-[360px] items-center justify-center rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2333
+ EmptyState,
2334
+ {
2335
+ icon: import_lucide_react7.Brain,
2336
+ title: loading ? "Loading map" : "No map data",
2337
+ description: loading ? "Building the namespace brain map." : "The map will appear once brain nodes exist."
2338
+ }
2339
+ ) });
2340
+ }
2341
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2342
+ "svg",
2343
+ {
2344
+ className: "block h-[420px] w-full bg-muted/20",
2345
+ role: "img",
2346
+ viewBox: "0 0 1000 600",
2347
+ children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { fill: "transparent", height: "600", width: "1000" }),
2349
+ clusters.map((cluster) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("g", { children: [
2350
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2351
+ "circle",
2352
+ {
2353
+ cx: cluster.x * 1e3,
2354
+ cy: cluster.y * 600,
2355
+ fill: cluster.layer === "working" ? "#ecfeff" : "#eef2ff",
2356
+ opacity: "0.7",
2357
+ r: Math.max(46, Math.min(96, 34 + cluster.count * 8)),
2358
+ stroke: cluster.layer === "working" ? "#0891b2" : "#4f46e5",
2359
+ strokeOpacity: "0.18"
2360
+ }
2361
+ ),
2362
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2363
+ "text",
2364
+ {
2365
+ className: "fill-muted-foreground text-[11px]",
2366
+ textAnchor: "middle",
2367
+ x: cluster.x * 1e3,
2368
+ y: cluster.y * 600 - 40,
2369
+ children: cluster.label
2370
+ }
2371
+ )
2372
+ ] }, cluster.id)),
2373
+ edges.map((edge) => {
2374
+ const source = nodeById.get(edge.sourceNodeId);
2375
+ const target = nodeById.get(edge.targetNodeId);
2376
+ if (!source || !target) return null;
2377
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2378
+ "line",
2379
+ {
2380
+ stroke: edge.type === "contradicts" ? "#dc2626" : "#64748b",
2381
+ strokeOpacity: "0.32",
2382
+ strokeWidth: edge.type === "supports" ? 2 : 1.3,
2383
+ x1: source.x * 1e3,
2384
+ x2: target.x * 1e3,
2385
+ y1: source.y * 600,
2386
+ y2: target.y * 600
2387
+ },
2388
+ edge.id
2389
+ );
2390
+ }),
2391
+ nodes.map((node) => {
2392
+ const isSelected = node.id === selectedNodeId;
2393
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2394
+ "g",
2395
+ {
2396
+ className: "cursor-pointer",
2397
+ onClick: () => onSelectNode(node),
2398
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2399
+ "circle",
2400
+ {
2401
+ cx: node.x * 1e3,
2402
+ cy: node.y * 600,
2403
+ fill: nodeColor(node),
2404
+ r: isSelected ? 9 : 6,
2405
+ stroke: isSelected ? "#0f172a" : "#ffffff",
2406
+ strokeWidth: isSelected ? 3 : 2,
2407
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("title", { children: `${node.name} \xB7 ${formatLabel(node.kind)}` })
2408
+ }
2409
+ )
2410
+ },
2411
+ node.id
2412
+ );
2413
+ })
2414
+ ]
2415
+ }
2416
+ ) });
2417
+ }
2418
+ function BrainNodeInspector({ node }) {
2419
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-3", children: [
2420
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-background p-4", children: [
2421
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
2422
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: node.layer }),
2423
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { status: node.status }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: formatLabel(node.kind) })
2425
+ ] }),
2426
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "mt-3 text-base font-semibold", children: node.name }),
2427
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-2 text-sm leading-6 text-muted-foreground", children: node.content || "-" }),
2428
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("dl", { className: "mt-4 grid gap-2 text-xs", children: [
2429
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Agent", value: node.agentId }),
2430
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Thread", value: node.threadId }),
2431
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Memory space", value: node.memorySpaceId }),
2432
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Checkpoint", value: node.checkpointId }),
2433
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Source field", value: node.sourceField }),
2434
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2435
+ InspectorRow,
2436
+ {
2437
+ label: "Updated",
2438
+ value: formatDateTime(node.updatedAt)
2439
+ }
2440
+ )
2441
+ ] })
2442
+ ] }),
2443
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(JsonPanel, { title: "Node JSON", value: node, minHeight: 300 })
2444
+ ] });
2445
+ }
2446
+ function InspectorRow({
2447
+ label,
2448
+ value
2449
+ }) {
2450
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "grid grid-cols-[110px_minmax(0,1fr)] gap-2", children: [
2451
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dt", { className: "text-muted-foreground", children: label }),
2452
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dd", { className: "truncate font-mono", children: value || "-" })
2453
+ ] });
2454
+ }
2455
+ function LayerBadge({ layer }) {
2456
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: layer === "working" ? "secondary" : "default", children: formatLabel(layer) });
2457
+ }
2458
+ function nodeColor(node) {
2459
+ if (node.layer === "working") return "#0891b2";
2460
+ if (node.kind === "decision") return "#4f46e5";
2461
+ if (node.kind === "risk") return "#dc2626";
2462
+ if (node.kind === "preference") return "#16a34a";
2463
+ return "#475569";
2464
+ }
2465
+ function formatLabel(value) {
2466
+ return value.replaceAll("_", " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
2467
+ }
2468
+ function formatDateTime(value) {
2469
+ if (!value) return "-";
2470
+ const date = new Date(value);
2471
+ if (Number.isNaN(date.getTime())) return value;
2472
+ return date.toLocaleString();
2473
+ }
2474
+ function emptyBrainResponse() {
2475
+ return {
2476
+ nodes: [],
2477
+ edges: [],
2478
+ clusters: [],
2479
+ stats: {
2480
+ total: 0,
2481
+ byLayer: {},
2482
+ byKind: {},
2483
+ byStatus: {}
2484
+ },
2485
+ pageInfo: {
2486
+ limit: 0,
2487
+ offset: 0,
2488
+ returned: 0
2489
+ }
2490
+ };
2491
+ }
2492
+
2493
+ // src/modules/collections/index.tsx
2494
+ var import_react4 = __toESM(require("react"), 1);
2495
+ var import_lucide_react8 = require("lucide-react");
2496
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2008
2497
  function collectionsModule() {
2009
2498
  return {
2010
2499
  group: "data",
2011
- icon: import_lucide_react7.Database,
2500
+ icon: import_lucide_react8.Database,
2012
2501
  id: "collections",
2013
2502
  label: "Collections",
2014
2503
  navItems: [{
2015
2504
  group: "data",
2016
- icon: import_lucide_react7.Database,
2505
+ icon: import_lucide_react8.Database,
2017
2506
  id: "collections",
2018
2507
  label: "Collections",
2019
2508
  order: 20,
@@ -2023,23 +2512,23 @@ function collectionsModule() {
2023
2512
  {
2024
2513
  id: "collections",
2025
2514
  title: "Collections",
2026
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CollectionsPage, { context })
2515
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CollectionsPage, { context })
2027
2516
  },
2028
2517
  {
2029
2518
  id: "collections.detail",
2030
2519
  title: "Collection Item",
2031
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CollectionDetailPage, { context })
2520
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CollectionDetailPage, { context })
2032
2521
  }
2033
2522
  ]
2034
2523
  };
2035
2524
  }
2036
2525
  function CollectionsPage({ context }) {
2037
- const [collections, setCollections] = import_react3.default.useState([]);
2038
- const [selected, setSelected] = import_react3.default.useState(null);
2039
- const [search, setSearch] = import_react3.default.useState("");
2040
- const [items, setItems] = import_react3.default.useState([]);
2041
- const [error, setError] = import_react3.default.useState(null);
2042
- import_react3.default.useEffect(() => {
2526
+ const [collections, setCollections] = import_react4.default.useState([]);
2527
+ const [selected, setSelected] = import_react4.default.useState(null);
2528
+ const [search, setSearch] = import_react4.default.useState("");
2529
+ const [items, setItems] = import_react4.default.useState([]);
2530
+ const [error, setError] = import_react4.default.useState(null);
2531
+ import_react4.default.useEffect(() => {
2043
2532
  let active = true;
2044
2533
  void context.client.listCollections().then((names) => {
2045
2534
  if (!active) return;
@@ -2052,7 +2541,7 @@ function CollectionsPage({ context }) {
2052
2541
  active = false;
2053
2542
  };
2054
2543
  }, [context.client, context.refreshKey]);
2055
- import_react3.default.useEffect(() => {
2544
+ import_react4.default.useEffect(() => {
2056
2545
  if (!selected) return;
2057
2546
  let active = true;
2058
2547
  setError(null);
@@ -2069,30 +2558,30 @@ function CollectionsPage({ context }) {
2069
2558
  active = false;
2070
2559
  };
2071
2560
  }, [context.client, context.refreshKey, context.scope.namespace, search, selected]);
2072
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2073
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2561
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
2562
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2074
2563
  PageHeader,
2075
2564
  {
2076
2565
  title: "Collections",
2077
2566
  description: "Schema-aware collection browsing with advanced JSON fallback for records that do not have custom editors.",
2078
- actions: selected && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2567
+ actions: selected && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2079
2568
  Button,
2080
2569
  {
2081
2570
  onClick: () => context.navigate("collections.detail", { collection: selected }),
2082
2571
  size: "sm",
2083
2572
  type: "button",
2084
2573
  children: [
2085
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Plus, { className: "size-3" }),
2574
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Plus, { className: "size-3" }),
2086
2575
  "New"
2087
2576
  ]
2088
2577
  }
2089
2578
  )
2090
2579
  }
2091
2580
  ),
2092
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "grid gap-4 lg:grid-cols-[240px_minmax(0,1fr)]", children: [
2093
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
2094
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "border-b px-3 py-2 text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Collections" }),
2095
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-h-[620px] overflow-auto p-1", children: collections.map((collection) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2581
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid gap-4 lg:grid-cols-[240px_minmax(0,1fr)]", children: [
2582
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
2583
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "border-b px-3 py-2 text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Collections" }),
2584
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-h-[620px] overflow-auto p-1", children: collections.map((collection) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2096
2585
  "button",
2097
2586
  {
2098
2587
  className: `flex w-full items-center rounded-md px-2 py-1.5 text-left text-sm ${selected === collection ? "bg-accent text-accent-foreground" : "hover:bg-muted"}`,
@@ -2103,8 +2592,8 @@ function CollectionsPage({ context }) {
2103
2592
  collection
2104
2593
  )) })
2105
2594
  ] }),
2106
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-3", children: [
2107
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2595
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-3", children: [
2596
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2108
2597
  FilterBar,
2109
2598
  {
2110
2599
  onSearchChange: setSearch,
@@ -2112,7 +2601,7 @@ function CollectionsPage({ context }) {
2112
2601
  searchValue: search
2113
2602
  }
2114
2603
  ),
2115
- error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Unable to load collection", description: error }) : selected ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2604
+ error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to load collection", description: error }) : selected ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2116
2605
  ResourceTable,
2117
2606
  {
2118
2607
  rows: items,
@@ -2121,10 +2610,10 @@ function CollectionsPage({ context }) {
2121
2610
  collection: selected,
2122
2611
  itemId: getItemId(item)
2123
2612
  }),
2124
- empty: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2613
+ empty: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2125
2614
  EmptyState,
2126
2615
  {
2127
- icon: import_lucide_react7.Database,
2616
+ icon: import_lucide_react8.Database,
2128
2617
  title: `No ${selected} records`,
2129
2618
  description: "Create a record or adjust the current filters."
2130
2619
  }
@@ -2133,16 +2622,16 @@ function CollectionsPage({ context }) {
2133
2622
  {
2134
2623
  id: "id",
2135
2624
  header: "ID",
2136
- render: (item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-sm truncate font-mono text-xs", children: getItemId(item) })
2625
+ render: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-w-sm truncate font-mono text-xs", children: getItemId(item) })
2137
2626
  },
2138
2627
  {
2139
2628
  id: "preview",
2140
2629
  header: "Preview",
2141
- render: (item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-xl truncate text-sm", children: getItemPreview(item) })
2630
+ render: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-w-xl truncate text-sm", children: getItemPreview(item) })
2142
2631
  }
2143
2632
  ]
2144
2633
  }
2145
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "No collections" })
2634
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "No collections" })
2146
2635
  ] })
2147
2636
  ] })
2148
2637
  ] });
@@ -2150,10 +2639,10 @@ function CollectionsPage({ context }) {
2150
2639
  function CollectionDetailPage({ context }) {
2151
2640
  const collection = context.route.params?.collection;
2152
2641
  const itemId = context.route.params?.itemId ?? null;
2153
- const [item, setItem] = import_react3.default.useState(null);
2154
- const [error, setError] = import_react3.default.useState(null);
2642
+ const [item, setItem] = import_react4.default.useState(null);
2643
+ const [error, setError] = import_react4.default.useState(null);
2155
2644
  const isNew = !itemId;
2156
- import_react3.default.useEffect(() => {
2645
+ import_react4.default.useEffect(() => {
2157
2646
  if (!collection || !itemId) {
2158
2647
  setItem(null);
2159
2648
  return;
@@ -2171,8 +2660,8 @@ function CollectionDetailPage({ context }) {
2171
2660
  active = false;
2172
2661
  };
2173
2662
  }, [collection, context.client, context.refreshKey, context.scope.namespace, itemId]);
2174
- if (!collection) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Collection not selected" });
2175
- if (error) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Unable to load item", description: error });
2663
+ if (!collection) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Collection not selected" });
2664
+ if (error) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to load item", description: error });
2176
2665
  const Editor = context.collectionEditors[collection];
2177
2666
  const save = async (value) => {
2178
2667
  if (isNew) {
@@ -2192,14 +2681,14 @@ function CollectionDetailPage({ context }) {
2192
2681
  });
2193
2682
  setItem(updated);
2194
2683
  };
2195
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2196
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2684
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
2685
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2197
2686
  PageHeader,
2198
2687
  {
2199
2688
  title: isNew ? `New ${collection}` : `${collection} / ${itemId}`,
2200
2689
  description: "Schema-aware editors can override this view. Advanced JSON remains available as a fallback.",
2201
- actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
2202
- !isNew && itemId && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2690
+ actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
2691
+ !isNew && itemId && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2203
2692
  Button,
2204
2693
  {
2205
2694
  onClick: () => {
@@ -2211,12 +2700,12 @@ function CollectionDetailPage({ context }) {
2211
2700
  type: "button",
2212
2701
  variant: "destructive",
2213
2702
  children: [
2214
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Trash2, { className: "size-3" }),
2703
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Trash2, { className: "size-3" }),
2215
2704
  "Delete"
2216
2705
  ]
2217
2706
  }
2218
2707
  ),
2219
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2708
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2220
2709
  Button,
2221
2710
  {
2222
2711
  onClick: () => context.navigate("collections"),
@@ -2229,7 +2718,7 @@ function CollectionDetailPage({ context }) {
2229
2718
  ] })
2230
2719
  }
2231
2720
  ),
2232
- Editor ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2721
+ Editor ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2233
2722
  Editor,
2234
2723
  {
2235
2724
  collection,
@@ -2240,7 +2729,7 @@ function CollectionDetailPage({ context }) {
2240
2729
  onSaved: setItem,
2241
2730
  onDeleted: () => context.navigate("collections")
2242
2731
  }
2243
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2732
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2244
2733
  JsonPanel,
2245
2734
  {
2246
2735
  title: "Advanced JSON",
@@ -2265,18 +2754,18 @@ function getItemPreview(item) {
2265
2754
  }
2266
2755
 
2267
2756
  // src/modules/events/index.tsx
2268
- var import_react4 = __toESM(require("react"), 1);
2269
- var import_lucide_react8 = require("lucide-react");
2270
- var import_jsx_runtime22 = require("react/jsx-runtime");
2757
+ var import_react5 = __toESM(require("react"), 1);
2758
+ var import_lucide_react9 = require("lucide-react");
2759
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2271
2760
  function eventsModule() {
2272
2761
  return {
2273
2762
  group: "operate",
2274
- icon: import_lucide_react8.Activity,
2763
+ icon: import_lucide_react9.Activity,
2275
2764
  id: "events",
2276
2765
  label: "Events",
2277
2766
  navItems: [{
2278
2767
  group: "operate",
2279
- icon: import_lucide_react8.Activity,
2768
+ icon: import_lucide_react9.Activity,
2280
2769
  id: "events",
2281
2770
  label: "Events",
2282
2771
  order: 30,
@@ -2285,7 +2774,7 @@ function eventsModule() {
2285
2774
  routes: [{
2286
2775
  id: "events",
2287
2776
  title: "Events",
2288
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EventsPage, { context })
2777
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EventsPage, { context })
2289
2778
  }]
2290
2779
  };
2291
2780
  }
@@ -2299,17 +2788,17 @@ var EVENT_STATUSES = [
2299
2788
  "overwritten"
2300
2789
  ];
2301
2790
  function EventsPage({ context }) {
2302
- const [threadId, setThreadId] = import_react4.default.useState("");
2303
- const [status, setStatus] = import_react4.default.useState(
2791
+ const [threadId, setThreadId] = import_react5.default.useState("");
2792
+ const [status, setStatus] = import_react5.default.useState(
2304
2793
  "all"
2305
2794
  );
2306
- const [eventType, setEventType] = import_react4.default.useState("");
2307
- const [traceId, setTraceId] = import_react4.default.useState("");
2308
- const [events, setEvents] = import_react4.default.useState([]);
2309
- const [selectedEvent, setSelectedEvent] = import_react4.default.useState(null);
2310
- const [error, setError] = import_react4.default.useState(null);
2311
- const [loading, setLoading] = import_react4.default.useState(false);
2312
- const [hasLoaded, setHasLoaded] = import_react4.default.useState(false);
2795
+ const [eventType, setEventType] = import_react5.default.useState("");
2796
+ const [traceId, setTraceId] = import_react5.default.useState("");
2797
+ const [events, setEvents] = import_react5.default.useState([]);
2798
+ const [selectedEvent, setSelectedEvent] = import_react5.default.useState(null);
2799
+ const [error, setError] = import_react5.default.useState(null);
2800
+ const [loading, setLoading] = import_react5.default.useState(false);
2801
+ const [hasLoaded, setHasLoaded] = import_react5.default.useState(false);
2313
2802
  const inspect = async () => {
2314
2803
  setHasLoaded(true);
2315
2804
  setLoading(true);
@@ -2335,21 +2824,21 @@ function EventsPage({ context }) {
2335
2824
  setLoading(false);
2336
2825
  }
2337
2826
  };
2338
- import_react4.default.useEffect(() => {
2827
+ import_react5.default.useEffect(() => {
2339
2828
  void inspect();
2340
2829
  }, [context.client, context.refreshKey, context.scope.namespace]);
2341
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
2342
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2830
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-4", children: [
2831
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2343
2832
  PageHeader,
2344
2833
  {
2345
2834
  title: "Events",
2346
2835
  description: "Queue and event inspection across the active namespace."
2347
2836
  }
2348
2837
  ),
2349
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2838
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2350
2839
  FilterBar,
2351
2840
  {
2352
- actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2841
+ actions: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2353
2842
  Button,
2354
2843
  {
2355
2844
  disabled: loading,
@@ -2357,13 +2846,13 @@ function EventsPage({ context }) {
2357
2846
  size: "sm",
2358
2847
  type: "button",
2359
2848
  children: [
2360
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Search, { className: "size-3" }),
2849
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react9.Search, { className: "size-3" }),
2361
2850
  loading ? "Loading" : "Inspect"
2362
2851
  ]
2363
2852
  }
2364
2853
  ),
2365
2854
  children: [
2366
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2855
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2367
2856
  Input,
2368
2857
  {
2369
2858
  className: "h-8 w-[220px]",
@@ -2375,18 +2864,18 @@ function EventsPage({ context }) {
2375
2864
  value: threadId
2376
2865
  }
2377
2866
  ),
2378
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2867
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2379
2868
  Select,
2380
2869
  {
2381
2870
  value: status,
2382
2871
  onValueChange: (value) => setStatus(value),
2383
2872
  children: [
2384
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SelectTrigger, { className: "h-8 w-[150px] text-xs", "aria-label": "Status", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SelectValue, {}) }),
2385
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SelectContent, { children: EVENT_STATUSES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SelectItem, { value: option, children: option === "all" ? "All statuses" : option }, option)) })
2873
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectTrigger, { className: "h-8 w-[150px] text-xs", "aria-label": "Status", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectValue, {}) }),
2874
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectContent, { children: EVENT_STATUSES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectItem, { value: option, children: option === "all" ? "All statuses" : option }, option)) })
2386
2875
  ]
2387
2876
  }
2388
2877
  ),
2389
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2878
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2390
2879
  Input,
2391
2880
  {
2392
2881
  className: "h-8 w-[180px]",
@@ -2398,7 +2887,7 @@ function EventsPage({ context }) {
2398
2887
  value: eventType
2399
2888
  }
2400
2889
  ),
2401
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2890
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2402
2891
  Input,
2403
2892
  {
2404
2893
  className: "h-8 w-[180px]",
@@ -2413,21 +2902,21 @@ function EventsPage({ context }) {
2413
2902
  ]
2414
2903
  }
2415
2904
  ),
2416
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to inspect event", description: error }) : !hasLoaded && loading ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2905
+ error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmptyState, { title: "Unable to inspect event", description: error }) : !hasLoaded && loading ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2417
2906
  EmptyState,
2418
2907
  {
2419
- icon: import_lucide_react8.Activity,
2908
+ icon: import_lucide_react9.Activity,
2420
2909
  title: "Loading events",
2421
2910
  description: "Fetching recent queue events for the active namespace."
2422
2911
  }
2423
- ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid gap-4 xl:grid-cols-[1fr_420px]", children: [
2424
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2912
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "grid gap-4 xl:grid-cols-[1fr_420px]", children: [
2913
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2425
2914
  ResourceTable,
2426
2915
  {
2427
2916
  rows: events,
2428
2917
  getRowKey: (row) => row.id,
2429
2918
  onRowClick: setSelectedEvent,
2430
- empty: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2919
+ empty: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2431
2920
  EmptyState,
2432
2921
  {
2433
2922
  title: "No matching events",
@@ -2449,7 +2938,7 @@ function EventsPage({ context }) {
2449
2938
  {
2450
2939
  id: "status",
2451
2940
  header: "Status",
2452
- render: (row) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StatusBadge, { status: row.status })
2941
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusBadge, { status: row.status })
2453
2942
  },
2454
2943
  {
2455
2944
  id: "trace",
@@ -2459,19 +2948,19 @@ function EventsPage({ context }) {
2459
2948
  {
2460
2949
  id: "created",
2461
2950
  header: "Created",
2462
- render: (row) => formatDateTime(row.createdAt)
2951
+ render: (row) => formatDateTime2(row.createdAt)
2463
2952
  }
2464
2953
  ]
2465
2954
  }
2466
2955
  ),
2467
- selectedEvent ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2956
+ selectedEvent ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2468
2957
  JsonPanel,
2469
2958
  {
2470
2959
  title: "Event JSON",
2471
2960
  value: selectedEvent,
2472
2961
  minHeight: 420
2473
2962
  }
2474
- ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2963
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2475
2964
  EmptyState,
2476
2965
  {
2477
2966
  title: "No event selected",
@@ -2481,7 +2970,7 @@ function EventsPage({ context }) {
2481
2970
  ] })
2482
2971
  ] });
2483
2972
  }
2484
- function formatDateTime(value) {
2973
+ function formatDateTime2(value) {
2485
2974
  if (!value) return "-";
2486
2975
  const date = new Date(value);
2487
2976
  if (Number.isNaN(date.getTime())) return value;
@@ -2494,18 +2983,18 @@ function formatDateTime(value) {
2494
2983
  }
2495
2984
 
2496
2985
  // src/modules/overview/index.tsx
2497
- var import_react5 = __toESM(require("react"), 1);
2498
- var import_lucide_react9 = require("lucide-react");
2499
- var import_jsx_runtime23 = require("react/jsx-runtime");
2986
+ var import_react6 = __toESM(require("react"), 1);
2987
+ var import_lucide_react10 = require("lucide-react");
2988
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2500
2989
  function overviewModule() {
2501
2990
  return {
2502
2991
  group: "operate",
2503
- icon: import_lucide_react9.Activity,
2992
+ icon: import_lucide_react10.Activity,
2504
2993
  id: "overview",
2505
2994
  label: "Overview",
2506
2995
  navItems: [{
2507
2996
  group: "operate",
2508
- icon: import_lucide_react9.Activity,
2997
+ icon: import_lucide_react10.Activity,
2509
2998
  id: "overview",
2510
2999
  label: "Overview",
2511
3000
  order: 10,
@@ -2514,17 +3003,17 @@ function overviewModule() {
2514
3003
  routes: [{
2515
3004
  id: "overview",
2516
3005
  title: "Overview",
2517
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(OverviewPage, { context })
3006
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(OverviewPage, { context })
2518
3007
  }]
2519
3008
  };
2520
3009
  }
2521
3010
  function OverviewPage({ context }) {
2522
- const [overview, setOverview] = import_react5.default.useState(null);
2523
- const [threads, setThreads] = import_react5.default.useState([]);
2524
- const [agents, setAgents] = import_react5.default.useState([]);
2525
- const [error, setError] = import_react5.default.useState(null);
2526
- const [isLoading, setIsLoading] = import_react5.default.useState(false);
2527
- import_react5.default.useEffect(() => {
3011
+ const [overview, setOverview] = import_react6.default.useState(null);
3012
+ const [threads, setThreads] = import_react6.default.useState([]);
3013
+ const [agents, setAgents] = import_react6.default.useState([]);
3014
+ const [error, setError] = import_react6.default.useState(null);
3015
+ const [isLoading, setIsLoading] = import_react6.default.useState(false);
3016
+ import_react6.default.useEffect(() => {
2528
3017
  let active = true;
2529
3018
  setIsLoading(true);
2530
3019
  setError(null);
@@ -2557,11 +3046,11 @@ function OverviewPage({ context }) {
2557
3046
  };
2558
3047
  }, [context.client, context.refreshKey, context.scope.namespace]);
2559
3048
  if (error) {
2560
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmptyState, { title: "Unable to load overview", description: error });
3049
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load overview", description: error });
2561
3050
  }
2562
3051
  const queueFailures = (overview?.queueTotals.failed ?? 0) + (overview?.queueTotals.expired ?? 0);
2563
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-4", children: [
2564
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3052
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
3053
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2565
3054
  PageHeader,
2566
3055
  {
2567
3056
  title: "Overview",
@@ -2572,41 +3061,41 @@ function OverviewPage({ context }) {
2572
3061
  ]
2573
3062
  }
2574
3063
  ),
2575
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3064
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2576
3065
  MetricStrip,
2577
3066
  {
2578
3067
  items: [
2579
3068
  {
2580
3069
  detail: `${formatNumber(overview?.threadTotals.active ?? 0)} active`,
2581
- icon: import_lucide_react9.MessageSquare,
3070
+ icon: import_lucide_react10.MessageSquare,
2582
3071
  label: "Threads",
2583
3072
  value: formatNumber(overview?.threadTotals.total ?? 0)
2584
3073
  },
2585
3074
  {
2586
3075
  detail: `${formatNumber(overview?.participantTotals.agents ?? 0)} agents`,
2587
- icon: import_lucide_react9.Users,
3076
+ icon: import_lucide_react10.Users,
2588
3077
  label: "Participants",
2589
3078
  value: formatNumber(overview?.participantTotals.total ?? 0)
2590
3079
  },
2591
3080
  {
2592
3081
  detail: `${formatNumber(overview?.llmTotals.totalCalls ?? 0)} LLM calls`,
2593
- icon: import_lucide_react9.Wallet,
3082
+ icon: import_lucide_react10.Wallet,
2594
3083
  label: "Cost",
2595
3084
  value: formatMetricValue(overview?.llmTotals.totalCostUsd ?? 0, "cost")
2596
3085
  },
2597
3086
  {
2598
3087
  detail: `${formatNumber(queueFailures)} failures/expired`,
2599
- icon: queueFailures > 0 ? import_lucide_react9.AlertTriangle : import_lucide_react9.Sparkles,
3088
+ icon: queueFailures > 0 ? import_lucide_react10.AlertTriangle : import_lucide_react10.Sparkles,
2600
3089
  label: "Queue",
2601
3090
  value: formatNumber(overview?.queueTotals.total ?? 0)
2602
3091
  }
2603
3092
  ]
2604
3093
  }
2605
3094
  ),
2606
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "grid gap-4 xl:grid-cols-2", children: [
2607
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("section", { className: "space-y-3", children: [
2608
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PageHeader, { title: "Recent Threads" }),
2609
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3095
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "grid gap-4 xl:grid-cols-2", children: [
3096
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("section", { className: "space-y-3", children: [
3097
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PageHeader, { title: "Recent Threads" }),
3098
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2610
3099
  ResourceTable,
2611
3100
  {
2612
3101
  rows: threads,
@@ -2616,15 +3105,15 @@ function OverviewPage({ context }) {
2616
3105
  {
2617
3106
  id: "name",
2618
3107
  header: "Thread",
2619
- render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
2620
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "max-w-md truncate font-medium", children: thread.name || thread.threadId }),
2621
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary" })
3108
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
3109
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate font-medium", children: thread.name || thread.threadId }),
3110
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary" })
2622
3111
  ] })
2623
3112
  },
2624
3113
  {
2625
3114
  id: "status",
2626
3115
  header: "Status",
2627
- render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusBadge, { status: thread.status })
3116
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusBadge, { status: thread.status })
2628
3117
  },
2629
3118
  {
2630
3119
  align: "right",
@@ -2636,9 +3125,9 @@ function OverviewPage({ context }) {
2636
3125
  }
2637
3126
  )
2638
3127
  ] }),
2639
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("section", { className: "space-y-3", children: [
2640
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PageHeader, { title: "Top Agents" }),
2641
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3128
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("section", { className: "space-y-3", children: [
3129
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PageHeader, { title: "Top Agents" }),
3130
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2642
3131
  ResourceTable,
2643
3132
  {
2644
3133
  rows: agents,
@@ -2648,11 +3137,11 @@ function OverviewPage({ context }) {
2648
3137
  {
2649
3138
  id: "agent",
2650
3139
  header: "Agent",
2651
- render: (agent) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
2652
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react9.Bot, { className: "size-4 text-muted-foreground" }),
2653
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
2654
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "font-medium", children: agent.displayName }),
2655
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-xs text-muted-foreground", children: agent.agentId })
3140
+ render: (agent) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
3141
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react10.Bot, { className: "size-4 text-muted-foreground" }),
3142
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
3143
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "font-medium", children: agent.displayName }),
3144
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-xs text-muted-foreground", children: agent.agentId })
2656
3145
  ] })
2657
3146
  ] })
2658
3147
  },
@@ -2677,18 +3166,18 @@ function OverviewPage({ context }) {
2677
3166
  }
2678
3167
 
2679
3168
  // src/modules/participants/index.tsx
2680
- var import_react6 = __toESM(require("react"), 1);
2681
- var import_lucide_react10 = require("lucide-react");
2682
- var import_jsx_runtime24 = require("react/jsx-runtime");
3169
+ var import_react7 = __toESM(require("react"), 1);
3170
+ var import_lucide_react11 = require("lucide-react");
3171
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2683
3172
  function participantsModule() {
2684
3173
  return {
2685
3174
  group: "data",
2686
- icon: import_lucide_react10.Users,
3175
+ icon: import_lucide_react11.Users,
2687
3176
  id: "participants",
2688
3177
  label: "Participants",
2689
3178
  navItems: [{
2690
3179
  group: "data",
2691
- icon: import_lucide_react10.Users,
3180
+ icon: import_lucide_react11.Users,
2692
3181
  id: "participants",
2693
3182
  label: "Participants",
2694
3183
  order: 10,
@@ -2698,21 +3187,21 @@ function participantsModule() {
2698
3187
  {
2699
3188
  id: "participants",
2700
3189
  title: "Participants",
2701
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ParticipantsPage, { context })
3190
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ParticipantsPage, { context })
2702
3191
  },
2703
3192
  {
2704
3193
  id: "participants.detail",
2705
3194
  title: "Participant Detail",
2706
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ParticipantDetailPage, { context })
3195
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ParticipantDetailPage, { context })
2707
3196
  }
2708
3197
  ]
2709
3198
  };
2710
3199
  }
2711
3200
  function ParticipantsPage({ context }) {
2712
- const [search, setSearch] = import_react6.default.useState("");
2713
- const [participants, setParticipants] = import_react6.default.useState([]);
2714
- const [error, setError] = import_react6.default.useState(null);
2715
- import_react6.default.useEffect(() => {
3201
+ const [search, setSearch] = import_react7.default.useState("");
3202
+ const [participants, setParticipants] = import_react7.default.useState([]);
3203
+ const [error, setError] = import_react7.default.useState(null);
3204
+ import_react7.default.useEffect(() => {
2716
3205
  let active = true;
2717
3206
  setError(null);
2718
3207
  void context.client.listParticipants({
@@ -2728,15 +3217,15 @@ function ParticipantsPage({ context }) {
2728
3217
  active = false;
2729
3218
  };
2730
3219
  }, [context.client, context.refreshKey, context.scope.namespace, search]);
2731
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
2732
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3220
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
3221
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2733
3222
  PageHeader,
2734
3223
  {
2735
3224
  title: "Participants",
2736
3225
  description: "Humans, agents, and jobs observed by Copilotz across conversations."
2737
3226
  }
2738
3227
  ),
2739
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3228
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2740
3229
  FilterBar,
2741
3230
  {
2742
3231
  onSearchChange: setSearch,
@@ -2744,7 +3233,7 @@ function ParticipantsPage({ context }) {
2744
3233
  searchValue: search
2745
3234
  }
2746
3235
  ),
2747
- error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load participants", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3236
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load participants", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2748
3237
  ResourceTable,
2749
3238
  {
2750
3239
  rows: participants,
@@ -2752,10 +3241,10 @@ function ParticipantsPage({ context }) {
2752
3241
  onRowClick: (participant) => context.navigate("participants.detail", {
2753
3242
  participantId: participant.externalId
2754
3243
  }),
2755
- empty: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3244
+ empty: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2756
3245
  EmptyState,
2757
3246
  {
2758
- icon: import_lucide_react10.Users,
3247
+ icon: import_lucide_react11.Users,
2759
3248
  title: "No participants",
2760
3249
  description: "Participants appear after messages or jobs are processed."
2761
3250
  }
@@ -2764,15 +3253,15 @@ function ParticipantsPage({ context }) {
2764
3253
  {
2765
3254
  id: "participant",
2766
3255
  header: "Participant",
2767
- render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
2768
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate font-medium", children: participant.displayName }),
2769
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: participant.externalId })
3256
+ render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
3257
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-md truncate font-medium", children: participant.displayName }),
3258
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: participant.externalId })
2770
3259
  ] })
2771
3260
  },
2772
3261
  {
2773
3262
  id: "type",
2774
3263
  header: "Type",
2775
- render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusBadge, { status: participant.participantType })
3264
+ render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusBadge, { status: participant.participantType })
2776
3265
  },
2777
3266
  {
2778
3267
  id: "scope",
@@ -2798,9 +3287,9 @@ function ParticipantsPage({ context }) {
2798
3287
  }
2799
3288
  function ParticipantDetailPage({ context }) {
2800
3289
  const participantId = context.route.params?.participantId;
2801
- const [participant, setParticipant] = import_react6.default.useState(null);
2802
- const [error, setError] = import_react6.default.useState(null);
2803
- import_react6.default.useEffect(() => {
3290
+ const [participant, setParticipant] = import_react7.default.useState(null);
3291
+ const [error, setError] = import_react7.default.useState(null);
3292
+ import_react7.default.useEffect(() => {
2804
3293
  if (!participantId) return;
2805
3294
  let active = true;
2806
3295
  setError(null);
@@ -2816,19 +3305,19 @@ function ParticipantDetailPage({ context }) {
2816
3305
  };
2817
3306
  }, [context.client, context.refreshKey, context.scope.namespace, participantId]);
2818
3307
  if (!participantId) {
2819
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Participant not selected" });
3308
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Participant not selected" });
2820
3309
  }
2821
3310
  if (error) {
2822
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load participant", description: error });
3311
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load participant", description: error });
2823
3312
  }
2824
3313
  const memories = Array.isArray(participant?.memories) ? participant.memories.length : 0;
2825
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
2826
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3314
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
3315
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2827
3316
  PageHeader,
2828
3317
  {
2829
3318
  title: String(participant?.displayName ?? participantId),
2830
3319
  description: "Participant profile, activity-ready metrics, and advanced record data.",
2831
- actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3320
+ actions: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2832
3321
  "button",
2833
3322
  {
2834
3323
  className: "text-sm text-muted-foreground hover:text-foreground",
@@ -2839,7 +3328,7 @@ function ParticipantDetailPage({ context }) {
2839
3328
  )
2840
3329
  }
2841
3330
  ),
2842
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3331
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2843
3332
  MetricStrip,
2844
3333
  {
2845
3334
  items: [
@@ -2849,24 +3338,24 @@ function ParticipantDetailPage({ context }) {
2849
3338
  ]
2850
3339
  }
2851
3340
  ),
2852
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(JsonPanel, { title: "Advanced JSON", value: participant, minHeight: 460 })
3341
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(JsonPanel, { title: "Advanced JSON", value: participant, minHeight: 460 })
2853
3342
  ] });
2854
3343
  }
2855
3344
 
2856
3345
  // src/modules/threads/index.tsx
2857
- var import_react7 = __toESM(require("react"), 1);
2858
- var import_lucide_react11 = require("lucide-react");
2859
- var import_jsx_runtime25 = require("react/jsx-runtime");
3346
+ var import_react8 = __toESM(require("react"), 1);
3347
+ var import_lucide_react12 = require("lucide-react");
3348
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2860
3349
  var MESSAGE_PAGE_SIZE = 50;
2861
3350
  function threadsModule() {
2862
3351
  return {
2863
3352
  group: "operate",
2864
- icon: import_lucide_react11.MessageSquare,
3353
+ icon: import_lucide_react12.MessageSquare,
2865
3354
  id: "threads",
2866
3355
  label: "Threads",
2867
3356
  navItems: [{
2868
3357
  group: "operate",
2869
- icon: import_lucide_react11.MessageSquare,
3358
+ icon: import_lucide_react12.MessageSquare,
2870
3359
  id: "threads",
2871
3360
  label: "Threads",
2872
3361
  order: 40,
@@ -2876,22 +3365,22 @@ function threadsModule() {
2876
3365
  {
2877
3366
  id: "threads",
2878
3367
  title: "Threads",
2879
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThreadsPage, { context })
3368
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadsPage, { context })
2880
3369
  },
2881
3370
  {
2882
3371
  id: "threads.detail",
2883
3372
  title: "Thread Detail",
2884
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThreadDetailPage, { context })
3373
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadDetailPage, { context })
2885
3374
  }
2886
3375
  ]
2887
3376
  };
2888
3377
  }
2889
3378
  function ThreadsPage({ context }) {
2890
- const [search, setSearch] = import_react7.default.useState("");
2891
- const [threads, setThreads] = import_react7.default.useState([]);
2892
- const [error, setError] = import_react7.default.useState(null);
2893
- const [isLoading, setIsLoading] = import_react7.default.useState(false);
2894
- import_react7.default.useEffect(() => {
3379
+ const [search, setSearch] = import_react8.default.useState("");
3380
+ const [threads, setThreads] = import_react8.default.useState([]);
3381
+ const [error, setError] = import_react8.default.useState(null);
3382
+ const [isLoading, setIsLoading] = import_react8.default.useState(false);
3383
+ import_react8.default.useEffect(() => {
2895
3384
  let active = true;
2896
3385
  setIsLoading(true);
2897
3386
  setError(null);
@@ -2910,8 +3399,8 @@ function ThreadsPage({ context }) {
2910
3399
  active = false;
2911
3400
  };
2912
3401
  }, [context.client, context.refreshKey, context.scope.namespace, search]);
2913
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
2914
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3402
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
3403
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2915
3404
  PageHeader,
2916
3405
  {
2917
3406
  title: "Threads",
@@ -2919,7 +3408,7 @@ function ThreadsPage({ context }) {
2919
3408
  badges: isLoading ? [{ label: "Loading" }] : []
2920
3409
  }
2921
3410
  ),
2922
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3411
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2923
3412
  FilterBar,
2924
3413
  {
2925
3414
  onSearchChange: setSearch,
@@ -2927,16 +3416,16 @@ function ThreadsPage({ context }) {
2927
3416
  searchValue: search
2928
3417
  }
2929
3418
  ),
2930
- error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load threads", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3419
+ error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "Unable to load threads", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2931
3420
  ResourceTable,
2932
3421
  {
2933
3422
  rows: threads,
2934
3423
  getRowKey: (thread) => thread.threadId,
2935
3424
  onRowClick: (thread) => context.navigate("threads.detail", { threadId: thread.threadId }),
2936
- empty: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3425
+ empty: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2937
3426
  EmptyState,
2938
3427
  {
2939
- icon: import_lucide_react11.MessageSquare,
3428
+ icon: import_lucide_react12.MessageSquare,
2940
3429
  title: "No threads",
2941
3430
  description: "Threads will appear after conversations start flowing."
2942
3431
  }
@@ -2945,15 +3434,15 @@ function ThreadsPage({ context }) {
2945
3434
  {
2946
3435
  id: "thread",
2947
3436
  header: "Thread",
2948
- render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "min-w-0", children: [
2949
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-xl truncate font-medium", children: thread.name || thread.threadId }),
2950
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-xl truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
3437
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0", children: [
3438
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "max-w-xl truncate font-medium", children: thread.name || thread.threadId }),
3439
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "max-w-xl truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
2951
3440
  ] })
2952
3441
  },
2953
3442
  {
2954
3443
  id: "status",
2955
3444
  header: "Status",
2956
- render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusBadge, { status: thread.status })
3445
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusBadge, { status: thread.status })
2957
3446
  },
2958
3447
  {
2959
3448
  align: "right",
@@ -2972,7 +3461,7 @@ function ThreadsPage({ context }) {
2972
3461
  {
2973
3462
  id: "activity",
2974
3463
  header: "Last activity",
2975
- render: (thread) => formatDateTime2(thread.lastActivityAt)
3464
+ render: (thread) => formatDateTime3(thread.lastActivityAt)
2976
3465
  }
2977
3466
  ]
2978
3467
  }
@@ -2982,7 +3471,7 @@ function ThreadsPage({ context }) {
2982
3471
  function ThreadDetailPage({ context }) {
2983
3472
  const threadId = context.route.params?.threadId;
2984
3473
  if (!threadId) {
2985
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3474
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2986
3475
  EmptyState,
2987
3476
  {
2988
3477
  title: "Thread not selected",
@@ -2990,19 +3479,19 @@ function ThreadDetailPage({ context }) {
2990
3479
  }
2991
3480
  );
2992
3481
  }
2993
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThreadInspector, { context, threadId });
3482
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadInspector, { context, threadId });
2994
3483
  }
2995
3484
  function ThreadInspector({
2996
3485
  context,
2997
3486
  threadId
2998
3487
  }) {
2999
- const [thread, setThread] = import_react7.default.useState(null);
3000
- const [messages, setMessages] = import_react7.default.useState([]);
3001
- const [pageInfo, setPageInfo] = import_react7.default.useState(null);
3002
- const [isLoading, setIsLoading] = import_react7.default.useState(true);
3003
- const [isLoadingMore, setIsLoadingMore] = import_react7.default.useState(false);
3004
- const [error, setError] = import_react7.default.useState(null);
3005
- import_react7.default.useEffect(() => {
3488
+ const [thread, setThread] = import_react8.default.useState(null);
3489
+ const [messages, setMessages] = import_react8.default.useState([]);
3490
+ const [pageInfo, setPageInfo] = import_react8.default.useState(null);
3491
+ const [isLoading, setIsLoading] = import_react8.default.useState(true);
3492
+ const [isLoadingMore, setIsLoadingMore] = import_react8.default.useState(false);
3493
+ const [error, setError] = import_react8.default.useState(null);
3494
+ import_react8.default.useEffect(() => {
3006
3495
  let active = true;
3007
3496
  setIsLoading(true);
3008
3497
  setError(null);
@@ -3043,13 +3532,13 @@ function ThreadInspector({
3043
3532
  }
3044
3533
  };
3045
3534
  if (isLoading) {
3046
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { icon: import_lucide_react11.Loader2, title: "Loading thread" });
3535
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { icon: import_lucide_react12.Loader2, title: "Loading thread" });
3047
3536
  }
3048
3537
  if (error) {
3049
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load thread", description: error });
3538
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "Unable to load thread", description: error });
3050
3539
  }
3051
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
3052
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3540
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
3541
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3053
3542
  PageHeader,
3054
3543
  {
3055
3544
  title: thread?.name ?? threadId,
@@ -3058,7 +3547,7 @@ function ThreadInspector({
3058
3547
  { label: thread?.status ?? "unknown" },
3059
3548
  { label: `${messages.length}${pageInfo?.hasMoreBefore ? "+" : ""} messages`, variant: "secondary" }
3060
3549
  ],
3061
- actions: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3550
+ actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3062
3551
  Button,
3063
3552
  {
3064
3553
  onClick: () => context.navigate("threads"),
@@ -3070,14 +3559,14 @@ function ThreadInspector({
3070
3559
  )
3071
3560
  }
3072
3561
  ),
3073
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3562
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3074
3563
  InspectorPanel,
3075
3564
  {
3076
- side: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(JsonPanel, { title: "Thread JSON", value: thread, minHeight: 420 }),
3077
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
3078
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between border-b px-4 py-2", children: [
3079
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-sm font-medium", children: "Timeline" }),
3080
- pageInfo?.hasMoreBefore && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3565
+ side: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(JsonPanel, { title: "Thread JSON", value: thread, minHeight: 420 }),
3566
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
3567
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between border-b px-4 py-2", children: [
3568
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "text-sm font-medium", children: "Timeline" }),
3569
+ pageInfo?.hasMoreBefore && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3081
3570
  Button,
3082
3571
  {
3083
3572
  disabled: isLoadingMore,
@@ -3086,51 +3575,51 @@ function ThreadInspector({
3086
3575
  type: "button",
3087
3576
  variant: "ghost",
3088
3577
  children: [
3089
- isLoadingMore ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.ChevronUp, { className: "size-3" }),
3578
+ isLoadingMore ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.ChevronUp, { className: "size-3" }),
3090
3579
  "Load older"
3091
3580
  ]
3092
3581
  }
3093
3582
  )
3094
3583
  ] }),
3095
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "No messages", description: "This thread has no messages yet." }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MessageRow, { message }, message.id)) })
3584
+ messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "No messages", description: "This thread has no messages yet." }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MessageRow, { message }, message.id)) })
3096
3585
  ] })
3097
3586
  }
3098
3587
  )
3099
3588
  ] });
3100
3589
  }
3101
3590
  function MessageRow({ message }) {
3102
- const [expanded, setExpanded] = import_react7.default.useState(false);
3591
+ const [expanded, setExpanded] = import_react8.default.useState(false);
3103
3592
  const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
3104
3593
  const hasReasoning = Boolean(message.reasoning);
3105
3594
  const hasMetadata = Boolean(message.metadata && Object.keys(message.metadata).length);
3106
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-start gap-3", children: [
3107
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SenderIcon, { senderType: message.senderType }),
3108
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "min-w-0 flex-1", children: [
3109
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
3110
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
3111
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "outline", className: "text-[10px]", children: message.senderType }),
3112
- message.targetId && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Badge, { variant: "secondary", className: "text-[10px]", children: [
3595
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-start gap-3", children: [
3596
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SenderIcon, { senderType: message.senderType }),
3597
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0 flex-1", children: [
3598
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
3599
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
3600
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: "outline", className: "text-[10px]", children: message.senderType }),
3601
+ message.targetId && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-[10px]", children: [
3113
3602
  "to ",
3114
3603
  message.targetId
3115
3604
  ] }),
3116
- message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-muted-foreground", children: formatDateTime2(message.createdAt) })
3605
+ message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-muted-foreground", children: formatDateTime3(message.createdAt) })
3117
3606
  ] }),
3118
- message.content && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-1 whitespace-pre-wrap break-words text-sm", children: message.content }),
3119
- (hasToolCalls || hasReasoning || hasMetadata) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "mt-2", children: [
3120
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3607
+ message.content && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "mt-1 whitespace-pre-wrap break-words text-sm", children: message.content }),
3608
+ (hasToolCalls || hasReasoning || hasMetadata) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mt-2", children: [
3609
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3121
3610
  "button",
3122
3611
  {
3123
3612
  className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground",
3124
3613
  onClick: () => setExpanded((value) => !value),
3125
3614
  type: "button",
3126
3615
  children: [
3127
- hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.Wrench, { className: "size-3" }),
3128
- hasReasoning && !hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.Cpu, { className: "size-3" }),
3616
+ hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Wrench, { className: "size-3" }),
3617
+ hasReasoning && !hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Cpu, { className: "size-3" }),
3129
3618
  "Details"
3130
3619
  ]
3131
3620
  }
3132
3621
  ),
3133
- expanded && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "mt-2 max-h-72 overflow-auto rounded-md bg-muted p-3 text-xs", children: JSON.stringify({
3622
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("pre", { className: "mt-2 max-h-72 overflow-auto rounded-md bg-muted p-3 text-xs", children: JSON.stringify({
3134
3623
  ...hasToolCalls ? { toolCalls: message.toolCalls } : {},
3135
3624
  ...hasReasoning ? { reasoning: message.reasoning } : {},
3136
3625
  ...hasMetadata ? { metadata: message.metadata } : {}
@@ -3143,16 +3632,16 @@ function SenderIcon({ senderType }) {
3143
3632
  const base = "flex size-7 shrink-0 items-center justify-center rounded-full";
3144
3633
  switch (senderType) {
3145
3634
  case "agent":
3146
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.Bot, { className: "size-3.5" }) });
3635
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Bot, { className: "size-3.5" }) });
3147
3636
  case "user":
3148
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.User, { className: "size-3.5" }) });
3637
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.User, { className: "size-3.5" }) });
3149
3638
  case "tool":
3150
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.Wrench, { className: "size-3.5" }) });
3639
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Wrench, { className: "size-3.5" }) });
3151
3640
  default:
3152
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.Cpu, { className: "size-3.5" }) });
3641
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Cpu, { className: "size-3.5" }) });
3153
3642
  }
3154
3643
  }
3155
- function formatDateTime2(value) {
3644
+ function formatDateTime3(value) {
3156
3645
  if (!value) return "No activity";
3157
3646
  const date = new Date(value);
3158
3647
  if (Number.isNaN(date.getTime())) return value;
@@ -3165,17 +3654,17 @@ function formatDateTime2(value) {
3165
3654
  }
3166
3655
 
3167
3656
  // src/modules/usage/index.tsx
3168
- var import_react8 = __toESM(require("react"), 1);
3657
+ var import_react9 = __toESM(require("react"), 1);
3169
3658
  var import_recharts = require("recharts");
3170
- var import_lucide_react12 = require("lucide-react");
3659
+ var import_lucide_react13 = require("lucide-react");
3171
3660
 
3172
3661
  // src/components/ui/chart.tsx
3173
- var React12 = __toESM(require("react"), 1);
3662
+ var React13 = __toESM(require("react"), 1);
3174
3663
  var RechartsPrimitive = __toESM(require("recharts"), 1);
3175
- var import_jsx_runtime26 = require("react/jsx-runtime");
3176
- var ChartContext = React12.createContext(null);
3664
+ var import_jsx_runtime27 = require("react/jsx-runtime");
3665
+ var ChartContext = React13.createContext(null);
3177
3666
  function useChart() {
3178
- const context = React12.useContext(ChartContext);
3667
+ const context = React13.useContext(ChartContext);
3179
3668
  if (!context) {
3180
3669
  throw new Error("useChart must be used within a ChartContainer");
3181
3670
  }
@@ -3188,9 +3677,9 @@ function ChartContainer({
3188
3677
  children,
3189
3678
  ...props
3190
3679
  }) {
3191
- const uniqueId = React12.useId();
3680
+ const uniqueId = React13.useId();
3192
3681
  const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
3193
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ChartContext.Provider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3682
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChartContext.Provider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3194
3683
  "div",
3195
3684
  {
3196
3685
  "data-chart": chartId,
@@ -3200,10 +3689,10 @@ function ChartContainer({
3200
3689
  ),
3201
3690
  ...props,
3202
3691
  children: [
3203
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("style", { children: Object.entries(config).map(([key, item]) => {
3692
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("style", { children: Object.entries(config).map(([key, item]) => {
3204
3693
  return `[data-chart=${chartId}] { --color-${key}: ${item.color}; }`;
3205
3694
  }).join("\n") }),
3206
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RechartsPrimitive.ResponsiveContainer, { children })
3695
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(RechartsPrimitive.ResponsiveContainer, { children })
3207
3696
  ]
3208
3697
  }
3209
3698
  ) });
@@ -3222,7 +3711,7 @@ function ChartTooltipContent({
3222
3711
  const value = typeof item.value === "number" ? item.value : Number(item.value ?? 0);
3223
3712
  return sum + (Number.isFinite(value) ? value : 0);
3224
3713
  }, 0);
3225
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3714
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3226
3715
  "div",
3227
3716
  {
3228
3717
  className: cn(
@@ -3230,28 +3719,28 @@ function ChartTooltipContent({
3230
3719
  className
3231
3720
  ),
3232
3721
  children: [
3233
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mb-2 flex items-center justify-between gap-4 border-b pb-2", children: [
3234
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-xs font-medium text-muted-foreground", children: labelFormatter ? labelFormatter(label) : label }),
3235
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-xs font-semibold text-foreground", children: formatter ? formatter(total) : total })
3722
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "mb-2 flex items-center justify-between gap-4 border-b pb-2", children: [
3723
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs font-medium text-muted-foreground", children: labelFormatter ? labelFormatter(label) : label }),
3724
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs font-semibold text-foreground", children: formatter ? formatter(total) : total })
3236
3725
  ] }),
3237
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
3726
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
3238
3727
  const key = String(item.dataKey ?? item.name ?? "");
3239
3728
  const itemConfig = config[key];
3240
3729
  const color = item.color ?? itemConfig?.color ?? "currentColor";
3241
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3730
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3242
3731
  "div",
3243
3732
  {
3244
3733
  className: "grid grid-cols-[0.6rem_1fr_auto] items-center gap-2",
3245
3734
  children: [
3246
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3735
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3247
3736
  "span",
3248
3737
  {
3249
3738
  className: "size-2 rounded-[2px]",
3250
3739
  style: { backgroundColor: color }
3251
3740
  }
3252
3741
  ),
3253
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "max-w-48 truncate text-muted-foreground", children: itemConfig?.label ?? item.name ?? key }),
3254
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-medium text-foreground", children: formatter ? formatter(item.value ?? 0) : item.value })
3742
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "max-w-48 truncate text-muted-foreground", children: itemConfig?.label ?? item.name ?? key }),
3743
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-medium text-foreground", children: formatter ? formatter(item.value ?? 0) : item.value })
3255
3744
  ]
3256
3745
  },
3257
3746
  key
@@ -3267,11 +3756,11 @@ function ChartLegendContent({
3267
3756
  }) {
3268
3757
  const config = useChart();
3269
3758
  if (!payload?.length) return null;
3270
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn("flex flex-wrap items-center gap-x-4 gap-y-2", className), children: payload.map((item) => {
3759
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("flex flex-wrap items-center gap-x-4 gap-y-2", className), children: payload.map((item) => {
3271
3760
  const key = String(item.dataKey ?? item.value ?? "");
3272
3761
  const itemConfig = config[key];
3273
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
3274
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3762
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2", children: [
3763
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3275
3764
  "span",
3276
3765
  {
3277
3766
  className: "size-2 rounded-[2px]",
@@ -3280,13 +3769,13 @@ function ChartLegendContent({
3280
3769
  }
3281
3770
  }
3282
3771
  ),
3283
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
3772
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
3284
3773
  ] }, key);
3285
3774
  }) });
3286
3775
  }
3287
3776
 
3288
3777
  // src/modules/usage/index.tsx
3289
- var import_jsx_runtime27 = require("react/jsx-runtime");
3778
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3290
3779
  var USAGE_DIMENSIONS = [
3291
3780
  "total",
3292
3781
  "input",
@@ -3314,12 +3803,12 @@ var STATUS_OPTIONS = [
3314
3803
  function usageModule() {
3315
3804
  return {
3316
3805
  group: "operate",
3317
- icon: import_lucide_react12.BarChart3,
3806
+ icon: import_lucide_react13.BarChart3,
3318
3807
  id: "usage",
3319
3808
  label: "Usage",
3320
3809
  navItems: [{
3321
3810
  group: "operate",
3322
- icon: import_lucide_react12.BarChart3,
3811
+ icon: import_lucide_react13.BarChart3,
3323
3812
  id: "usage",
3324
3813
  label: "Usage",
3325
3814
  order: 20,
@@ -3328,70 +3817,70 @@ function usageModule() {
3328
3817
  routes: [{
3329
3818
  id: "usage",
3330
3819
  title: "Usage",
3331
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(UsagePage, { context })
3820
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UsagePage, { context })
3332
3821
  }]
3333
3822
  };
3334
3823
  }
3335
3824
  function UsagePage({ context }) {
3336
- const [period, setPeriod] = import_react8.default.useState(
3825
+ const [period, setPeriod] = import_react9.default.useState(
3337
3826
  "7d"
3338
3827
  );
3339
- const [interval, setInterval] = import_react8.default.useState("day");
3340
- const [workload, setWorkload] = import_react8.default.useState("all");
3341
- const [metricKind, setMetricKind] = import_react8.default.useState(
3828
+ const [interval, setInterval] = import_react9.default.useState("day");
3829
+ const [workload, setWorkload] = import_react9.default.useState("all");
3830
+ const [metricKind, setMetricKind] = import_react9.default.useState(
3342
3831
  "calls"
3343
3832
  );
3344
- const [dimension, setDimension] = import_react8.default.useState("total");
3345
- const [groupBy, setGroupBy] = import_react8.default.useState("kind");
3346
- const [attribution, setAttribution] = import_react8.default.useState(
3833
+ const [dimension, setDimension] = import_react9.default.useState("total");
3834
+ const [groupBy, setGroupBy] = import_react9.default.useState("kind");
3835
+ const [attribution, setAttribution] = import_react9.default.useState(
3347
3836
  "initiatedBy"
3348
3837
  );
3349
- const [participantType, setParticipantType] = import_react8.default.useState("all");
3350
- const [threadId, setThreadId] = import_react8.default.useState("");
3351
- const [participantId, setParticipantId] = import_react8.default.useState("");
3352
- const [provider, setProvider] = import_react8.default.useState("");
3353
- const [model, setModel] = import_react8.default.useState("");
3354
- const [resource, setResource] = import_react8.default.useState("");
3355
- const [operation, setOperation] = import_react8.default.useState("");
3356
- const [status, setStatus] = import_react8.default.useState(
3838
+ const [participantType, setParticipantType] = import_react9.default.useState("all");
3839
+ const [threadId, setThreadId] = import_react9.default.useState("");
3840
+ const [participantId, setParticipantId] = import_react9.default.useState("");
3841
+ const [provider, setProvider] = import_react9.default.useState("");
3842
+ const [model, setModel] = import_react9.default.useState("");
3843
+ const [resource, setResource] = import_react9.default.useState("");
3844
+ const [operation, setOperation] = import_react9.default.useState("");
3845
+ const [status, setStatus] = import_react9.default.useState(
3357
3846
  "all"
3358
3847
  );
3359
- const [customFrom, setCustomFrom] = import_react8.default.useState("");
3360
- const [customTo, setCustomTo] = import_react8.default.useState("");
3361
- const [usage, setUsage] = import_react8.default.useState(null);
3362
- const [error, setError] = import_react8.default.useState(null);
3363
- const [isLoading, setIsLoading] = import_react8.default.useState(false);
3364
- const range = import_react8.default.useMemo(
3848
+ const [customFrom, setCustomFrom] = import_react9.default.useState("");
3849
+ const [customTo, setCustomTo] = import_react9.default.useState("");
3850
+ const [usage, setUsage] = import_react9.default.useState(null);
3851
+ const [error, setError] = import_react9.default.useState(null);
3852
+ const [isLoading, setIsLoading] = import_react9.default.useState(false);
3853
+ const range = import_react9.default.useMemo(
3365
3854
  () => getUsageRange(period, customFrom, customTo),
3366
3855
  [customFrom, customTo, period]
3367
3856
  );
3368
- const metricOptions = import_react8.default.useMemo(
3857
+ const metricOptions = import_react9.default.useMemo(
3369
3858
  () => getUsageMetricOptions(workload),
3370
3859
  [workload]
3371
3860
  );
3372
- const groupOptions = import_react8.default.useMemo(
3861
+ const groupOptions = import_react9.default.useMemo(
3373
3862
  () => getUsageGroupOptions(workload),
3374
3863
  [workload]
3375
3864
  );
3376
3865
  const showLlmFields = workload === "llm";
3377
3866
  const showResourceFields = workload !== "llm";
3378
3867
  const showDimension = metricKind === "tokens" || metricKind === "cost" && workload === "llm";
3379
- import_react8.default.useEffect(() => {
3868
+ import_react9.default.useEffect(() => {
3380
3869
  if (!metricOptions.includes(metricKind)) {
3381
3870
  setMetricKind(metricOptions[0]);
3382
3871
  }
3383
3872
  }, [metricKind, metricOptions]);
3384
- import_react8.default.useEffect(() => {
3873
+ import_react9.default.useEffect(() => {
3385
3874
  if (!groupOptions.includes(groupBy)) {
3386
3875
  setGroupBy(groupOptions[0]);
3387
3876
  }
3388
3877
  }, [groupBy, groupOptions]);
3389
- import_react8.default.useEffect(() => {
3878
+ import_react9.default.useEffect(() => {
3390
3879
  if (!showDimension && dimension !== "total") {
3391
3880
  setDimension("total");
3392
3881
  }
3393
3882
  }, [dimension, showDimension]);
3394
- import_react8.default.useEffect(() => {
3883
+ import_react9.default.useEffect(() => {
3395
3884
  let active = true;
3396
3885
  setIsLoading(true);
3397
3886
  setError(null);
@@ -3449,16 +3938,16 @@ function UsagePage({ context }) {
3449
3938
  ]);
3450
3939
  const points = usage?.points ?? [];
3451
3940
  const totals = usage?.totals ?? EMPTY_USAGE_TOTALS;
3452
- const chartState = import_react8.default.useMemo(
3941
+ const chartState = import_react9.default.useMemo(
3453
3942
  () => buildUsageChartState(points, metricKind, dimension, interval),
3454
3943
  [dimension, interval, metricKind, points]
3455
3944
  );
3456
- const rows = import_react8.default.useMemo(
3945
+ const rows = import_react9.default.useMemo(
3457
3946
  () => aggregateUsageRows(points, metricKind, dimension),
3458
3947
  [dimension, metricKind, points]
3459
3948
  );
3460
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "space-y-4", children: [
3461
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3949
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "space-y-4", children: [
3950
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3462
3951
  PageHeader,
3463
3952
  {
3464
3953
  title: "Usage",
@@ -3471,8 +3960,8 @@ function UsagePage({ context }) {
3471
3960
  ]
3472
3961
  }
3473
3962
  ),
3474
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(FilterBar, { children: [
3475
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3963
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(FilterBar, { children: [
3964
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3476
3965
  UsageSelect,
3477
3966
  {
3478
3967
  label: "Period",
@@ -3481,7 +3970,7 @@ function UsagePage({ context }) {
3481
3970
  value: period
3482
3971
  }
3483
3972
  ),
3484
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3973
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3485
3974
  UsageSelect,
3486
3975
  {
3487
3976
  label: "Bucket",
@@ -3490,7 +3979,7 @@ function UsagePage({ context }) {
3490
3979
  value: interval
3491
3980
  }
3492
3981
  ),
3493
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3982
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3494
3983
  UsageSelect,
3495
3984
  {
3496
3985
  label: "Workload",
@@ -3500,7 +3989,7 @@ function UsagePage({ context }) {
3500
3989
  formatOption: getUsageKindLabel
3501
3990
  }
3502
3991
  ),
3503
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3992
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3504
3993
  UsageSelect,
3505
3994
  {
3506
3995
  label: "Measure",
@@ -3510,7 +3999,7 @@ function UsagePage({ context }) {
3510
3999
  formatOption: getUsageMetricLabel
3511
4000
  }
3512
4001
  ),
3513
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4002
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3514
4003
  UsageSelect,
3515
4004
  {
3516
4005
  label: "Group",
@@ -3520,7 +4009,7 @@ function UsagePage({ context }) {
3520
4009
  formatOption: getUsageGroupLabel
3521
4010
  }
3522
4011
  ),
3523
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4012
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3524
4013
  UsageSelect,
3525
4014
  {
3526
4015
  label: "Actor",
@@ -3530,7 +4019,7 @@ function UsagePage({ context }) {
3530
4019
  formatOption: getUsageAttributionLabel
3531
4020
  }
3532
4021
  ),
3533
- showDimension && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4022
+ showDimension && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3534
4023
  UsageSelect,
3535
4024
  {
3536
4025
  label: "Dimension",
@@ -3541,9 +4030,9 @@ function UsagePage({ context }) {
3541
4030
  }
3542
4031
  )
3543
4032
  ] }),
3544
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(FilterBar, { children: [
3545
- period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3546
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4033
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(FilterBar, { children: [
4034
+ period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4035
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3547
4036
  Input,
3548
4037
  {
3549
4038
  className: "h-8 w-[190px]",
@@ -3552,7 +4041,7 @@ function UsagePage({ context }) {
3552
4041
  value: customFrom
3553
4042
  }
3554
4043
  ),
3555
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4044
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3556
4045
  Input,
3557
4046
  {
3558
4047
  className: "h-8 w-[190px]",
@@ -3562,7 +4051,7 @@ function UsagePage({ context }) {
3562
4051
  }
3563
4052
  )
3564
4053
  ] }),
3565
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4054
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3566
4055
  UsageSelect,
3567
4056
  {
3568
4057
  label: "Actor type",
@@ -3571,7 +4060,7 @@ function UsagePage({ context }) {
3571
4060
  value: participantType
3572
4061
  }
3573
4062
  ),
3574
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4063
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3575
4064
  UsageSelect,
3576
4065
  {
3577
4066
  label: "Status",
@@ -3580,7 +4069,7 @@ function UsagePage({ context }) {
3580
4069
  value: status
3581
4070
  }
3582
4071
  ),
3583
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4072
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3584
4073
  Input,
3585
4074
  {
3586
4075
  className: "h-8 w-[170px]",
@@ -3589,7 +4078,7 @@ function UsagePage({ context }) {
3589
4078
  value: threadId
3590
4079
  }
3591
4080
  ),
3592
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4081
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3593
4082
  Input,
3594
4083
  {
3595
4084
  className: "h-8 w-[170px]",
@@ -3598,8 +4087,8 @@ function UsagePage({ context }) {
3598
4087
  value: participantId
3599
4088
  }
3600
4089
  ),
3601
- showResourceFields && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3602
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4090
+ showResourceFields && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4091
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3603
4092
  Input,
3604
4093
  {
3605
4094
  className: "h-8 w-[170px]",
@@ -3608,7 +4097,7 @@ function UsagePage({ context }) {
3608
4097
  value: resource
3609
4098
  }
3610
4099
  ),
3611
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4100
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3612
4101
  Input,
3613
4102
  {
3614
4103
  className: "h-8 w-[150px]",
@@ -3618,8 +4107,8 @@ function UsagePage({ context }) {
3618
4107
  }
3619
4108
  )
3620
4109
  ] }),
3621
- showLlmFields && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3622
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4110
+ showLlmFields && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4111
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3623
4112
  Input,
3624
4113
  {
3625
4114
  className: "h-8 w-[140px]",
@@ -3628,7 +4117,7 @@ function UsagePage({ context }) {
3628
4117
  value: provider
3629
4118
  }
3630
4119
  ),
3631
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4120
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3632
4121
  Input,
3633
4122
  {
3634
4123
  className: "h-8 w-[140px]",
@@ -3639,58 +4128,58 @@ function UsagePage({ context }) {
3639
4128
  )
3640
4129
  ] })
3641
4130
  ] }),
3642
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4131
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3643
4132
  MetricStrip,
3644
4133
  {
3645
4134
  items: [
3646
4135
  {
3647
4136
  detail: `${formatMetricValue(totals.unpricedCalls, "unpriced")} unpriced`,
3648
- icon: import_lucide_react12.DollarSign,
4137
+ icon: import_lucide_react13.DollarSign,
3649
4138
  label: "Spend",
3650
4139
  value: formatMetricValue(totals.totalCostUsd, "cost")
3651
4140
  },
3652
4141
  {
3653
4142
  detail: `${formatMetricValue(totals.failedCalls, "failures")} failed`,
3654
- icon: import_lucide_react12.Activity,
4143
+ icon: import_lucide_react13.Activity,
3655
4144
  label: "Calls",
3656
4145
  value: formatMetricValue(totals.totalCalls, "calls")
3657
4146
  },
3658
4147
  {
3659
4148
  detail: "Tool and resource runtime",
3660
- icon: import_lucide_react12.Clock,
4149
+ icon: import_lucide_react13.Clock,
3661
4150
  label: "Duration",
3662
4151
  value: formatMetricValue(totals.totalDurationMs, "duration")
3663
4152
  },
3664
4153
  {
3665
4154
  detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
3666
- icon: import_lucide_react12.Sparkles,
4155
+ icon: import_lucide_react13.Sparkles,
3667
4156
  label: "Tokens",
3668
4157
  value: formatMetricValue(totals.totalTokens, "tokens")
3669
4158
  },
3670
4159
  {
3671
4160
  detail: "Custom metering",
3672
- icon: import_lucide_react12.Coins,
4161
+ icon: import_lucide_react13.Coins,
3673
4162
  label: "Credits",
3674
4163
  value: formatMetricValue(totals.totalCredits, "credits")
3675
4164
  },
3676
4165
  {
3677
4166
  detail: "Failed or aborted work",
3678
- icon: import_lucide_react12.AlertTriangle,
4167
+ icon: import_lucide_react13.AlertTriangle,
3679
4168
  label: "Failures",
3680
4169
  value: formatMetricValue(totals.failedCalls, "failures")
3681
4170
  }
3682
4171
  ]
3683
4172
  }
3684
4173
  ),
3685
- error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(EmptyState, { title: "Unable to load usage", description: error }) : chartState.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4174
+ error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(EmptyState, { title: "Unable to load usage", description: error }) : chartState.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3686
4175
  EmptyState,
3687
4176
  {
3688
4177
  title: "No usage",
3689
4178
  description: "Metered LLM, tool, and resource records will appear here after work is captured in the usage ledger."
3690
4179
  }
3691
- ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3692
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Card, { className: "h-[320px] py-3", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CardContent, { className: "h-full px-3", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(UsageChart, { chartState, metricKind }) }) }),
3693
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4180
+ ) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4181
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Card, { className: "h-[320px] py-3", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(CardContent, { className: "h-full px-3", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UsageChart, { chartState, metricKind }) }) }),
4182
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3694
4183
  UsageRowsTable,
3695
4184
  {
3696
4185
  dimension,
@@ -3710,19 +4199,19 @@ function UsageSelect({
3710
4199
  options,
3711
4200
  value
3712
4201
  }) {
3713
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Select, { value, onValueChange, children: [
3714
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectTrigger, { className: "h-8 w-[132px] text-xs", "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectValue, {}) }),
3715
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectItem, { value: option, children: formatOption ? formatOption(option) : option }, option)) })
4202
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Select, { value, onValueChange, children: [
4203
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectTrigger, { className: "h-8 w-[132px] text-xs", "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectValue, {}) }),
4204
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectItem, { value: option, children: formatOption ? formatOption(option) : option }, option)) })
3716
4205
  ] });
3717
4206
  }
3718
4207
  function UsageChart({
3719
4208
  chartState,
3720
4209
  metricKind
3721
4210
  }) {
3722
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChartContainer, { className: "h-full w-full", config: chartState.config, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_recharts.BarChart, { accessibilityLayer: true, data: chartState.data, margin: { left: 8, right: 8, top: 12 }, children: [
3723
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_recharts.CartesianGrid, { vertical: false }),
3724
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_recharts.XAxis, { dataKey: "label", tickLine: false, axisLine: false, tickMargin: 10 }),
3725
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4211
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChartContainer, { className: "h-full w-full", config: chartState.config, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_recharts.BarChart, { accessibilityLayer: true, data: chartState.data, margin: { left: 8, right: 8, top: 12 }, children: [
4212
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.CartesianGrid, { vertical: false }),
4213
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.XAxis, { dataKey: "label", tickLine: false, axisLine: false, tickMargin: 10 }),
4214
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3726
4215
  import_recharts.YAxis,
3727
4216
  {
3728
4217
  axisLine: false,
@@ -3731,10 +4220,10 @@ function UsageChart({
3731
4220
  width: 64
3732
4221
  }
3733
4222
  ),
3734
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4223
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3735
4224
  import_recharts.Tooltip,
3736
4225
  {
3737
- content: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4226
+ content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3738
4227
  ChartTooltipContent,
3739
4228
  {
3740
4229
  formatter: (value) => formatMetricValue(Number(value), metricKind),
@@ -3744,8 +4233,8 @@ function UsageChart({
3744
4233
  cursor: false
3745
4234
  }
3746
4235
  ),
3747
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_recharts.Legend, { content: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChartLegendContent, { className: "justify-center pt-3" }) }),
3748
- chartState.series.map((series) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4236
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.Legend, { content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChartLegendContent, { className: "justify-center pt-3" }) }),
4237
+ chartState.series.map((series) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3749
4238
  import_recharts.Bar,
3750
4239
  {
3751
4240
  dataKey: series.id,
@@ -3766,7 +4255,7 @@ function UsageRowsTable({
3766
4255
  }) {
3767
4256
  const totalValue = getUsageTotalValue(totals, metricKind, dimension);
3768
4257
  const valueHeader = (metricKind === "tokens" || metricKind === "cost") && dimension !== "total" ? `${getUsageDimensionLabel(dimension)} ${getUsageMetricLabel(metricKind)}` : getUsageMetricLabel(metricKind);
3769
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4258
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3770
4259
  ResourceTable,
3771
4260
  {
3772
4261
  rows: rows.slice(0, 80),
@@ -3775,9 +4264,9 @@ function UsageRowsTable({
3775
4264
  {
3776
4265
  id: "group",
3777
4266
  header: getUsageGroupLabel(groupBy),
3778
- render: (row) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "min-w-0", children: [
3779
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "max-w-80 truncate font-medium", children: row.groupLabel }),
3780
- row.groupKey !== row.groupLabel && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "max-w-80 truncate text-xs text-muted-foreground", children: row.groupKey })
4267
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "min-w-0", children: [
4268
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-80 truncate font-medium", children: row.groupLabel }),
4269
+ row.groupKey !== row.groupLabel && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-80 truncate text-xs text-muted-foreground", children: row.groupKey })
3781
4270
  ] })
3782
4271
  },
3783
4272
  {
@@ -3906,6 +4395,7 @@ function defaultCopilotzModules() {
3906
4395
  usageModule(),
3907
4396
  eventsModule(),
3908
4397
  threadsModule(),
4398
+ brainModule(),
3909
4399
  agentsModule(),
3910
4400
  participantsModule(),
3911
4401
  collectionsModule()
@@ -3985,17 +4475,17 @@ function firstAccessibleRoute(modules, permissions) {
3985
4475
  }
3986
4476
 
3987
4477
  // src/core/scope.tsx
3988
- var import_react9 = require("react");
3989
- var import_jsx_runtime28 = require("react/jsx-runtime");
3990
- var AdminContext = (0, import_react9.createContext)(null);
4478
+ var import_react10 = require("react");
4479
+ var import_jsx_runtime29 = require("react/jsx-runtime");
4480
+ var AdminContext = (0, import_react10.createContext)(null);
3991
4481
  function AdminProvider({
3992
4482
  children,
3993
4483
  value
3994
4484
  }) {
3995
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(AdminContext.Provider, { value, children });
4485
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AdminContext.Provider, { value, children });
3996
4486
  }
3997
4487
  function useAdmin() {
3998
- const context = (0, import_react9.useContext)(AdminContext);
4488
+ const context = (0, import_react10.useContext)(AdminContext);
3999
4489
  if (!context) {
4000
4490
  throw new Error("useAdmin must be used inside CopilotzAdmin");
4001
4491
  }
@@ -4003,7 +4493,7 @@ function useAdmin() {
4003
4493
  }
4004
4494
 
4005
4495
  // src/core/CopilotzAdmin.tsx
4006
- var import_jsx_runtime29 = require("react/jsx-runtime");
4496
+ var import_jsx_runtime30 = require("react/jsx-runtime");
4007
4497
  var DEFAULT_BRANDING = {
4008
4498
  title: "Copilotz Admin",
4009
4499
  subtitle: "Operate and configure Copilotz projects",
@@ -4039,11 +4529,11 @@ function CopilotzAdmin({
4039
4529
  permissions = {},
4040
4530
  scope: scopeProp
4041
4531
  }) {
4042
- const modules = (0, import_react10.useMemo)(
4532
+ const modules = (0, import_react11.useMemo)(
4043
4533
  () => modulesProp ?? defaultCopilotzModules(),
4044
4534
  [modulesProp]
4045
4535
  );
4046
- const adminClient = (0, import_react10.useMemo)(
4536
+ const adminClient = (0, import_react11.useMemo)(
4047
4537
  () => client ?? createAdminClient({
4048
4538
  baseUrl: clientConfig?.baseUrl ?? config?.baseUrl,
4049
4539
  paths: clientConfig?.paths,
@@ -4051,7 +4541,7 @@ function CopilotzAdmin({
4051
4541
  }),
4052
4542
  [client, clientConfig, config]
4053
4543
  );
4054
- const branding = (0, import_react10.useMemo)(
4544
+ const branding = (0, import_react11.useMemo)(
4055
4545
  () => ({
4056
4546
  ...DEFAULT_BRANDING,
4057
4547
  ...config?.branding ?? {},
@@ -4059,30 +4549,30 @@ function CopilotzAdmin({
4059
4549
  }),
4060
4550
  [brandingProp, config?.branding]
4061
4551
  );
4062
- const [namespace, setNamespaceState] = (0, import_react10.useState)(
4552
+ const [namespace, setNamespaceState] = (0, import_react11.useState)(
4063
4553
  scopeProp?.namespace ?? config?.namespace ?? ""
4064
4554
  );
4065
- const scope = (0, import_react10.useMemo)(() => ({
4555
+ const scope = (0, import_react11.useMemo)(() => ({
4066
4556
  ...scopeProp ?? {},
4067
4557
  namespace
4068
4558
  }), [namespace, scopeProp]);
4069
- const routes = (0, import_react10.useMemo)(
4559
+ const routes = (0, import_react11.useMemo)(
4070
4560
  () => collectAdminRoutes(modules, permissions),
4071
4561
  [modules, permissions]
4072
4562
  );
4073
- const navItems = (0, import_react10.useMemo)(
4563
+ const navItems = (0, import_react11.useMemo)(
4074
4564
  () => collectAdminNavItems(modules, permissions),
4075
4565
  [modules, permissions]
4076
4566
  );
4077
- const collectionEditors = (0, import_react10.useMemo)(
4567
+ const collectionEditors = (0, import_react11.useMemo)(
4078
4568
  () => collectCollectionEditors(modules),
4079
4569
  [modules]
4080
4570
  );
4081
4571
  const initialRouteId = routeFromLegacyPage(config?.defaultPage) ?? firstAccessibleRoute(modules, permissions);
4082
- const [route, setRoute] = (0, import_react10.useState)({
4572
+ const [route, setRoute] = (0, import_react11.useState)({
4083
4573
  routeId: initialRouteId
4084
4574
  });
4085
- const [refreshKey, setRefreshKey] = (0, import_react10.useState)(0);
4575
+ const [refreshKey, setRefreshKey] = (0, import_react11.useState)(0);
4086
4576
  const activeRoute = routes.get(route.routeId) ?? routes.get(firstAccessibleRoute(modules, permissions));
4087
4577
  const navigate = (routeId, params) => {
4088
4578
  const next = { routeId, params };
@@ -4103,7 +4593,7 @@ function CopilotzAdmin({
4103
4593
  scope,
4104
4594
  setNamespace: setNamespaceState
4105
4595
  };
4106
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AdminProvider, { value: runtime, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4596
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(AdminProvider, { value: runtime, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4107
4597
  "div",
4108
4598
  {
4109
4599
  className: cn(
@@ -4111,7 +4601,7 @@ function CopilotzAdmin({
4111
4601
  className
4112
4602
  ),
4113
4603
  children: [
4114
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4604
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4115
4605
  AdminShellSidebar,
4116
4606
  {
4117
4607
  branding,
@@ -4123,8 +4613,8 @@ function CopilotzAdmin({
4123
4613
  scopeOptions: scope.availableNamespaces
4124
4614
  }
4125
4615
  ),
4126
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex h-full min-h-0 flex-col", children: [
4127
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4616
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex h-full min-h-0 flex-col", children: [
4617
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4128
4618
  AdminShellHeader,
4129
4619
  {
4130
4620
  brandingActions: branding.actions,
@@ -4133,7 +4623,7 @@ function CopilotzAdmin({
4133
4623
  title: activeRoute?.title ?? "Admin"
4134
4624
  }
4135
4625
  ),
4136
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("main", { className: "min-h-0 flex-1 overflow-auto bg-muted/20", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mx-auto flex w-full max-w-[1600px] flex-col gap-4 p-4 lg:p-5", children: activeRoute ? activeRoute.render(runtime) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "rounded-lg border bg-background p-8 text-sm text-muted-foreground", children: "No accessible admin route is configured." }) }) })
4626
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("main", { className: "min-h-0 flex-1 overflow-auto bg-muted/20", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "mx-auto flex w-full max-w-[1600px] flex-col gap-4 p-4 lg:p-5", children: activeRoute ? activeRoute.render(runtime) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "rounded-lg border bg-background p-8 text-sm text-muted-foreground", children: "No accessible admin route is configured." }) }) })
4137
4627
  ] }) })
4138
4628
  ]
4139
4629
  }
@@ -4152,57 +4642,57 @@ function AdminShellSidebar({
4152
4642
  group,
4153
4643
  items: navItems.filter((item) => (item.group ?? "extensions") === group)
4154
4644
  })).filter((entry) => entry.items.length > 0);
4155
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Sidebar, { collapsible: "icon", children: [
4156
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-3 px-2 py-3", children: [
4157
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex size-8 shrink-0 items-center justify-center rounded-md bg-primary text-primary-foreground", children: branding.logo ?? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.Bot, { className: "size-4" }) }),
4158
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0 group-data-[collapsible=icon]:hidden", children: [
4159
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "truncate text-sm font-semibold", children: branding.title }),
4160
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: branding.subtitle })
4645
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Sidebar, { collapsible: "icon", children: [
4646
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-3 px-2 py-3", children: [
4647
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex size-8 shrink-0 items-center justify-center rounded-md bg-primary text-primary-foreground", children: branding.logo ?? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Bot, { className: "size-4" }) }),
4648
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "min-w-0 group-data-[collapsible=icon]:hidden", children: [
4649
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "truncate text-sm font-semibold", children: branding.title }),
4650
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: branding.subtitle })
4161
4651
  ] })
4162
4652
  ] }) }),
4163
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarContent, { children: grouped.map(({ group, items }, index) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react10.default.Fragment, { children: [
4164
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarSeparator, {}),
4165
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(SidebarGroup, { children: [
4166
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: ADMIN_GROUP_LABELS[group] }),
4167
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarMenu, { children: items.map((item) => {
4168
- const Icon2 = item.icon ?? import_lucide_react13.LayoutDashboard;
4169
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4653
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarContent, { children: grouped.map(({ group, items }, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react11.default.Fragment, { children: [
4654
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarSeparator, {}),
4655
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SidebarGroup, { children: [
4656
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: ADMIN_GROUP_LABELS[group] }),
4657
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarMenu, { children: items.map((item) => {
4658
+ const Icon2 = item.icon ?? import_lucide_react14.LayoutDashboard;
4659
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4170
4660
  SidebarMenuButton,
4171
4661
  {
4172
4662
  isActive: route.routeId === item.routeId,
4173
4663
  onClick: () => onNavigate(item.routeId),
4174
4664
  tooltip: item.label,
4175
4665
  children: [
4176
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon2, {}),
4177
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: item.label })
4666
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon2, {}),
4667
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: item.label })
4178
4668
  ]
4179
4669
  }
4180
4670
  ) }, item.id);
4181
4671
  }) }) })
4182
4672
  ] })
4183
4673
  ] }, group)) }),
4184
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(SidebarFooter, { children: [
4185
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "group-data-[collapsible=icon]:hidden", children: [
4186
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { className: "mb-1 block px-2 text-xs font-medium text-muted-foreground", children: "Namespace" }),
4187
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4674
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SidebarFooter, { children: [
4675
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "group-data-[collapsible=icon]:hidden", children: [
4676
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "mb-1 block px-2 text-xs font-medium text-muted-foreground", children: "Namespace" }),
4677
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4188
4678
  Select,
4189
4679
  {
4190
4680
  value: namespace || "__all__",
4191
4681
  onValueChange: (value) => onNamespaceChange(value === "__all__" ? "" : value),
4192
4682
  children: [
4193
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectValue, { placeholder: "All namespaces" }) }),
4194
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(SelectContent, { children: [
4195
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectItem, { value: "__all__", children: "All namespaces" }),
4196
- scopeOptions?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectItem, { value: option.id, children: option.label ?? option.id }, option.id)),
4197
- namespace && !scopeOptions?.some((option) => option.id === namespace) && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectItem, { value: namespace, children: namespace })
4683
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectValue, { placeholder: "All namespaces" }) }),
4684
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SelectContent, { children: [
4685
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: "__all__", children: "All namespaces" }),
4686
+ scopeOptions?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: option.id, children: option.label ?? option.id }, option.id)),
4687
+ namespace && !scopeOptions?.some((option) => option.id === namespace) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: namespace, children: namespace })
4198
4688
  ] })
4199
4689
  ]
4200
4690
  }
4201
4691
  )
4202
4692
  ] }),
4203
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "hidden justify-center group-data-[collapsible=icon]:flex", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.ChevronsUpDown, { className: "size-4 text-muted-foreground" }) })
4693
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "hidden justify-center group-data-[collapsible=icon]:flex", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.ChevronsUpDown, { className: "size-4 text-muted-foreground" }) })
4204
4694
  ] }),
4205
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarRail, {})
4695
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarRail, {})
4206
4696
  ] });
4207
4697
  }
4208
4698
  function AdminShellHeader({
@@ -4211,17 +4701,17 @@ function AdminShellHeader({
4211
4701
  onRefresh,
4212
4702
  title
4213
4703
  }) {
4214
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "flex min-h-12 shrink-0 items-center gap-2 border-b bg-background/95 px-3 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: [
4215
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
4216
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
4217
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { children: "Toggle sidebar" })
4704
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("header", { className: "flex min-h-12 shrink-0 items-center gap-2 border-b bg-background/95 px-3 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: [
4705
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
4706
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
4707
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { children: "Toggle sidebar" })
4218
4708
  ] }),
4219
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
4220
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.Database, { className: "size-4 text-muted-foreground" }),
4221
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h1", { className: "truncate text-sm font-medium", children: title })
4709
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
4710
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Database, { className: "size-4 text-muted-foreground" }),
4711
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", { className: "truncate text-sm font-medium", children: title })
4222
4712
  ] }),
4223
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
4224
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4713
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
4714
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4225
4715
  Button,
4226
4716
  {
4227
4717
  className: "size-8",
@@ -4230,10 +4720,10 @@ function AdminShellHeader({
4230
4720
  size: "icon",
4231
4721
  type: "button",
4232
4722
  variant: "ghost",
4233
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.RefreshCw, { className: "size-4" })
4723
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.RefreshCw, { className: "size-4" })
4234
4724
  }
4235
4725
  ) }),
4236
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { children: "Refresh" })
4726
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { children: "Refresh" })
4237
4727
  ] }),
4238
4728
  brandingActions
4239
4729
  ] });
@@ -4260,27 +4750,27 @@ function mergeAdminConfig(baseConfig = defaultAdminConfig, userConfig) {
4260
4750
  }
4261
4751
 
4262
4752
  // src/useCopilotzAdmin.ts
4263
- var import_react11 = require("react");
4753
+ var import_react12 = require("react");
4264
4754
  function useCopilotzAdmin(options = {}) {
4265
- const [range, setRange] = (0, import_react11.useState)(options.range ?? "7d");
4266
- const [interval, setInterval] = (0, import_react11.useState)(
4755
+ const [range, setRange] = (0, import_react12.useState)(options.range ?? "7d");
4756
+ const [interval, setInterval] = (0, import_react12.useState)(
4267
4757
  options.interval ?? "day"
4268
4758
  );
4269
- const [overview, setOverview] = (0, import_react11.useState)(null);
4270
- const [activity, setActivity] = (0, import_react11.useState)([]);
4271
- const [threads, setThreads] = (0, import_react11.useState)([]);
4272
- const [participants, setParticipants] = (0, import_react11.useState)([]);
4273
- const [agents, setAgents] = (0, import_react11.useState)([]);
4274
- const [isLoading, setIsLoading] = (0, import_react11.useState)(true);
4275
- const [error, setError] = (0, import_react11.useState)(null);
4276
- const client = (0, import_react11.useMemo)(
4759
+ const [overview, setOverview] = (0, import_react12.useState)(null);
4760
+ const [activity, setActivity] = (0, import_react12.useState)([]);
4761
+ const [threads, setThreads] = (0, import_react12.useState)([]);
4762
+ const [participants, setParticipants] = (0, import_react12.useState)([]);
4763
+ const [agents, setAgents] = (0, import_react12.useState)([]);
4764
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
4765
+ const [error, setError] = (0, import_react12.useState)(null);
4766
+ const client = (0, import_react12.useMemo)(
4277
4767
  () => createAdminClient({
4278
4768
  baseUrl: options.baseUrl,
4279
4769
  getRequestHeaders: options.getRequestHeaders
4280
4770
  }),
4281
4771
  [options.baseUrl, options.getRequestHeaders]
4282
4772
  );
4283
- const fetchAll = (0, import_react11.useCallback)(async () => {
4773
+ const fetchAll = (0, import_react12.useCallback)(async () => {
4284
4774
  setIsLoading(true);
4285
4775
  setError(null);
4286
4776
  try {
@@ -4326,7 +4816,7 @@ function useCopilotzAdmin(options = {}) {
4326
4816
  options.threadSearch,
4327
4817
  range
4328
4818
  ]);
4329
- (0, import_react11.useEffect)(() => {
4819
+ (0, import_react12.useEffect)(() => {
4330
4820
  void fetchAll();
4331
4821
  }, [fetchAll]);
4332
4822
  return {
@@ -4364,6 +4854,7 @@ function useCopilotzAdmin(options = {}) {
4364
4854
  addUsageTotals,
4365
4855
  agentsModule,
4366
4856
  aggregateUsageRows,
4857
+ brainModule,
4367
4858
  buildUsageChartState,
4368
4859
  canAccessAdminPermission,
4369
4860
  collectAdminNavItems,