@copilotz/admin 0.9.38 → 0.9.40

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,27 @@ 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
+ searchMode: filters.searchMode,
317
+ focusNodeId: filters.focusNodeId,
318
+ includeRelated: filters.includeRelated ? "true" : void 0,
319
+ includeSimilar: filters.includeSimilar ? "true" : void 0,
320
+ similarLimit: filters.similarLimit ? String(filters.similarLimit) : void 0,
321
+ minSimilarity: typeof filters.minSimilarity === "number" ? String(filters.minSimilarity) : void 0,
322
+ relationDepth: filters.relationDepth ? String(filters.relationDepth) : void 0,
323
+ relationTypes: filters.relationTypes?.join(","),
324
+ limit: String(filters.limit ?? 160),
325
+ offset: filters.offset ? String(filters.offset) : void 0
326
+ }),
302
327
  listCollections: async () => await requestJson(paths.collectionsBase),
303
328
  listCollectionItems: async (collection, listOptions = {}) => await requestJson(
304
329
  `${paths.collectionsBase}/${encodeURIComponent(collection)}`,
@@ -345,8 +370,8 @@ function createAdminClient(options = {}) {
345
370
  }
346
371
 
347
372
  // src/core/CopilotzAdmin.tsx
348
- var import_react10 = __toESM(require("react"), 1);
349
- var import_lucide_react13 = require("lucide-react");
373
+ var import_react11 = __toESM(require("react"), 1);
374
+ var import_lucide_react14 = require("lucide-react");
350
375
 
351
376
  // src/lib/utils.ts
352
377
  var import_clsx = require("clsx");
@@ -2001,19 +2026,686 @@ function AgentDetailPage({ context }) {
2001
2026
  ] });
2002
2027
  }
2003
2028
 
2004
- // src/modules/collections/index.tsx
2029
+ // src/modules/brain/index.tsx
2005
2030
  var import_react3 = __toESM(require("react"), 1);
2006
2031
  var import_lucide_react7 = require("lucide-react");
2007
2032
  var import_jsx_runtime21 = require("react/jsx-runtime");
2033
+ var BRAIN_LAYERS = ["all", "knowledge", "working"];
2034
+ var BRAIN_SEARCH_MODES = ["hybrid", "semantic", "keyword"];
2035
+ var BRAIN_STATUSES = ["active", "all", "superseded", "archived"];
2036
+ var BRAIN_KINDS = [
2037
+ "all",
2038
+ "decision",
2039
+ "fact",
2040
+ "preference",
2041
+ "task",
2042
+ "constraint",
2043
+ "current_state",
2044
+ "challenge",
2045
+ "risk",
2046
+ "open_question",
2047
+ "next_action"
2048
+ ];
2049
+ function brainModule() {
2050
+ return {
2051
+ group: "data",
2052
+ icon: import_lucide_react7.Brain,
2053
+ id: "brain",
2054
+ label: "Brain",
2055
+ navItems: [{
2056
+ group: "data",
2057
+ icon: import_lucide_react7.Brain,
2058
+ id: "brain",
2059
+ label: "Brain",
2060
+ order: 10,
2061
+ routeId: "brain"
2062
+ }],
2063
+ routes: [{
2064
+ id: "brain",
2065
+ title: "Brain",
2066
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BrainPage, { context })
2067
+ }]
2068
+ };
2069
+ }
2070
+ function BrainPage({ context }) {
2071
+ const [search, setSearch] = import_react3.default.useState("");
2072
+ const [searchMode, setSearchMode] = import_react3.default.useState(
2073
+ "hybrid"
2074
+ );
2075
+ const [layer, setLayer] = import_react3.default.useState("all");
2076
+ const [status, setStatus] = import_react3.default.useState(
2077
+ "active"
2078
+ );
2079
+ const [kind, setKind] = import_react3.default.useState("all");
2080
+ const [agentId, setAgentId] = import_react3.default.useState("");
2081
+ const [response, setResponse] = import_react3.default.useState(
2082
+ null
2083
+ );
2084
+ const [selectedNode, setSelectedNode] = import_react3.default.useState(
2085
+ null
2086
+ );
2087
+ const [focusNodeId, setFocusNodeId] = import_react3.default.useState(null);
2088
+ const [loading, setLoading] = import_react3.default.useState(false);
2089
+ const [error, setError] = import_react3.default.useState(null);
2090
+ const loadBrain = import_react3.default.useCallback(async (focusOverride) => {
2091
+ setLoading(true);
2092
+ setError(null);
2093
+ const effectiveFocusNodeId = focusOverride === void 0 ? focusNodeId : focusOverride;
2094
+ try {
2095
+ const next = await context.client.getBrain({
2096
+ namespace: context.scope.namespace || void 0,
2097
+ search: search.trim() || void 0,
2098
+ searchMode,
2099
+ layer,
2100
+ status,
2101
+ kind,
2102
+ agentId: agentId.trim() || void 0,
2103
+ focusNodeId: effectiveFocusNodeId || void 0,
2104
+ includeRelated: Boolean(effectiveFocusNodeId),
2105
+ includeSimilar: Boolean(effectiveFocusNodeId),
2106
+ similarLimit: 24,
2107
+ minSimilarity: 0.2,
2108
+ limit: 180
2109
+ });
2110
+ setResponse(next);
2111
+ setSelectedNode(
2112
+ (current) => effectiveFocusNodeId ? next.nodes.find((node) => node.id === effectiveFocusNodeId) ?? current : current && next.nodes.some((node) => node.id === current.id) ? next.nodes.find((node) => node.id === current.id) ?? current : next.nodes[0] ?? null
2113
+ );
2114
+ } catch (cause) {
2115
+ setError(cause instanceof Error ? cause.message : "Failed to load brain");
2116
+ setResponse(null);
2117
+ setSelectedNode(null);
2118
+ } finally {
2119
+ setLoading(false);
2120
+ }
2121
+ }, [
2122
+ agentId,
2123
+ context.client,
2124
+ context.scope.namespace,
2125
+ focusNodeId,
2126
+ kind,
2127
+ layer,
2128
+ search,
2129
+ searchMode,
2130
+ status
2131
+ ]);
2132
+ import_react3.default.useEffect(() => {
2133
+ void loadBrain();
2134
+ }, [context.refreshKey, context.scope.namespace, focusNodeId, loadBrain]);
2135
+ const data = response ?? emptyBrainResponse();
2136
+ const matches = data.matches ?? {};
2137
+ const related = data.related ?? [];
2138
+ const similar = data.similar ?? [];
2139
+ const knowledgeCount = data.stats.byLayer.knowledge ?? 0;
2140
+ const workingCount = data.stats.byLayer.working ?? 0;
2141
+ const selectNode = import_react3.default.useCallback((node) => {
2142
+ setSelectedNode(node);
2143
+ setFocusNodeId(node.id);
2144
+ }, []);
2145
+ const runSearch = import_react3.default.useCallback(() => {
2146
+ setFocusNodeId(null);
2147
+ void loadBrain(null);
2148
+ }, [loadBrain]);
2149
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2150
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2151
+ PageHeader,
2152
+ {
2153
+ title: "Brain",
2154
+ description: "Unified knowledge and working state for the active namespace.",
2155
+ badges: [
2156
+ {
2157
+ label: context.scope.namespace ?? "all namespaces",
2158
+ variant: "secondary"
2159
+ }
2160
+ ],
2161
+ actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2162
+ Button,
2163
+ {
2164
+ disabled: loading,
2165
+ onClick: () => void loadBrain(),
2166
+ size: "sm",
2167
+ type: "button",
2168
+ variant: "outline",
2169
+ children: [
2170
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.RefreshCw, { className: cn("size-3", loading && "animate-spin") }),
2171
+ "Refresh"
2172
+ ]
2173
+ }
2174
+ )
2175
+ }
2176
+ ),
2177
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2178
+ MetricStrip,
2179
+ {
2180
+ items: [
2181
+ {
2182
+ label: "Brain nodes",
2183
+ value: data.stats.total,
2184
+ detail: `${data.pageInfo.returned} shown`,
2185
+ icon: import_lucide_react7.Brain
2186
+ },
2187
+ {
2188
+ label: "Knowledge",
2189
+ value: knowledgeCount,
2190
+ detail: "Durable nodes",
2191
+ icon: import_lucide_react7.CircleDot
2192
+ },
2193
+ {
2194
+ label: "Working",
2195
+ value: workingCount,
2196
+ detail: "Current state",
2197
+ icon: import_lucide_react7.Sparkles
2198
+ },
2199
+ {
2200
+ label: "Clusters",
2201
+ value: data.clusters.length,
2202
+ detail: "Layer and kind",
2203
+ icon: import_lucide_react7.Network
2204
+ }
2205
+ ]
2206
+ }
2207
+ ),
2208
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2209
+ FilterBar,
2210
+ {
2211
+ actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2212
+ Button,
2213
+ {
2214
+ disabled: loading,
2215
+ onClick: runSearch,
2216
+ size: "sm",
2217
+ type: "button",
2218
+ children: [
2219
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Search, { className: "size-3" }),
2220
+ "Search"
2221
+ ]
2222
+ }
2223
+ ),
2224
+ onSearchChange: setSearch,
2225
+ searchPlaceholder: "Search brain",
2226
+ searchValue: search,
2227
+ children: [
2228
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "inline-flex h-8 overflow-hidden rounded-md border bg-background", children: BRAIN_SEARCH_MODES.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2229
+ "button",
2230
+ {
2231
+ className: cn(
2232
+ "px-3 text-xs transition-colors",
2233
+ searchMode === mode ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
2234
+ ),
2235
+ onClick: () => setSearchMode(mode),
2236
+ type: "button",
2237
+ children: formatLabel(mode)
2238
+ },
2239
+ mode
2240
+ )) }),
2241
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2242
+ Select,
2243
+ {
2244
+ value: layer,
2245
+ onValueChange: (value) => setLayer(value),
2246
+ children: [
2247
+ /* @__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, {}) }),
2248
+ /* @__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)) })
2249
+ ]
2250
+ }
2251
+ ),
2252
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2253
+ Select,
2254
+ {
2255
+ value: status,
2256
+ onValueChange: (value) => setStatus(value),
2257
+ children: [
2258
+ /* @__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, {}) }),
2259
+ /* @__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)) })
2260
+ ]
2261
+ }
2262
+ ),
2263
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2264
+ Select,
2265
+ {
2266
+ value: kind,
2267
+ onValueChange: (value) => setKind(value),
2268
+ children: [
2269
+ /* @__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, {}) }),
2270
+ /* @__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)) })
2271
+ ]
2272
+ }
2273
+ ),
2274
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2275
+ Input,
2276
+ {
2277
+ className: "h-8 w-[190px]",
2278
+ onChange: (event) => setAgentId(event.target.value),
2279
+ onKeyDown: (event) => {
2280
+ if (event.key === "Enter") runSearch();
2281
+ },
2282
+ placeholder: "Agent ID",
2283
+ value: agentId
2284
+ }
2285
+ )
2286
+ ]
2287
+ }
2288
+ ),
2289
+ data.semantic?.requested && data.semantic.error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: [
2290
+ "Semantic search unavailable: ",
2291
+ data.semantic.error
2292
+ ] }) : null,
2293
+ error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Unable to load brain", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2294
+ InspectorPanel,
2295
+ {
2296
+ side: selectedNode ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2297
+ BrainNodeInspector,
2298
+ {
2299
+ match: matches[selectedNode.id],
2300
+ node: selectedNode,
2301
+ onSelectNode: selectNode,
2302
+ related,
2303
+ similar
2304
+ }
2305
+ ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2306
+ EmptyState,
2307
+ {
2308
+ icon: import_lucide_react7.Brain,
2309
+ title: "No node selected",
2310
+ description: "Select a node from the map or table."
2311
+ }
2312
+ ),
2313
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2314
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2315
+ BrainMap,
2316
+ {
2317
+ clusters: data.clusters,
2318
+ edges: data.edges,
2319
+ loading,
2320
+ nodes: data.nodes,
2321
+ onSelectNode: selectNode,
2322
+ similar,
2323
+ selectedNodeId: selectedNode?.id ?? null
2324
+ }
2325
+ ),
2326
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2327
+ ResourceTable,
2328
+ {
2329
+ rows: data.nodes,
2330
+ getRowKey: (row) => row.id,
2331
+ onRowClick: selectNode,
2332
+ empty: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2333
+ EmptyState,
2334
+ {
2335
+ icon: import_lucide_react7.Brain,
2336
+ title: loading ? "Loading brain" : "No brain nodes",
2337
+ description: loading ? "Fetching brain nodes for the active namespace." : "Knowledge and working-state nodes will appear here."
2338
+ }
2339
+ ),
2340
+ columns: [
2341
+ {
2342
+ id: "node",
2343
+ header: "Node",
2344
+ className: "max-w-[360px]",
2345
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "min-w-0", children: [
2346
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "truncate font-medium", children: row.name }),
2347
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: row.content || "-" }),
2348
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MatchBadges, { match: matches[row.id] })
2349
+ ] })
2350
+ },
2351
+ {
2352
+ id: "layer",
2353
+ header: "Layer",
2354
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: row.layer })
2355
+ },
2356
+ {
2357
+ id: "kind",
2358
+ header: "Kind",
2359
+ render: (row) => formatLabel(row.kind)
2360
+ },
2361
+ {
2362
+ id: "status",
2363
+ header: "Status",
2364
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { status: row.status })
2365
+ },
2366
+ {
2367
+ id: "agent",
2368
+ header: "Agent",
2369
+ className: "max-w-[160px] truncate font-mono text-xs",
2370
+ render: (row) => row.agentId ?? "-"
2371
+ }
2372
+ ]
2373
+ }
2374
+ )
2375
+ ] })
2376
+ }
2377
+ )
2378
+ ] });
2379
+ }
2380
+ function BrainMap({
2381
+ clusters,
2382
+ edges,
2383
+ loading,
2384
+ nodes,
2385
+ onSelectNode,
2386
+ similar,
2387
+ selectedNodeId
2388
+ }) {
2389
+ const nodeById = import_react3.default.useMemo(
2390
+ () => new Map(nodes.map((node) => [node.id, node])),
2391
+ [nodes]
2392
+ );
2393
+ if (nodes.length === 0) {
2394
+ 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)(
2395
+ EmptyState,
2396
+ {
2397
+ icon: import_lucide_react7.Brain,
2398
+ title: loading ? "Loading map" : "No map data",
2399
+ description: loading ? "Building the namespace brain map." : "The map will appear once brain nodes exist."
2400
+ }
2401
+ ) });
2402
+ }
2403
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2404
+ "svg",
2405
+ {
2406
+ className: "block h-[420px] w-full bg-muted/20",
2407
+ role: "img",
2408
+ viewBox: "0 0 1000 600",
2409
+ children: [
2410
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { fill: "transparent", height: "600", width: "1000" }),
2411
+ clusters.map((cluster) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("g", { children: [
2412
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2413
+ "circle",
2414
+ {
2415
+ cx: cluster.x * 1e3,
2416
+ cy: cluster.y * 600,
2417
+ fill: cluster.layer === "working" ? "#ecfeff" : "#eef2ff",
2418
+ opacity: "0.7",
2419
+ r: Math.max(46, Math.min(96, 34 + cluster.count * 8)),
2420
+ stroke: cluster.layer === "working" ? "#0891b2" : "#4f46e5",
2421
+ strokeOpacity: "0.18"
2422
+ }
2423
+ ),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2425
+ "text",
2426
+ {
2427
+ className: "fill-muted-foreground text-[11px]",
2428
+ textAnchor: "middle",
2429
+ x: cluster.x * 1e3,
2430
+ y: cluster.y * 600 - 40,
2431
+ children: cluster.label
2432
+ }
2433
+ )
2434
+ ] }, cluster.id)),
2435
+ edges.map((edge) => {
2436
+ const source = nodeById.get(edge.sourceNodeId);
2437
+ const target = nodeById.get(edge.targetNodeId);
2438
+ if (!source || !target) return null;
2439
+ const isSelectedEdge = Boolean(
2440
+ selectedNodeId && (edge.sourceNodeId === selectedNodeId || edge.targetNodeId === selectedNodeId)
2441
+ );
2442
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2443
+ "line",
2444
+ {
2445
+ stroke: edge.type === "contradicts" ? "#dc2626" : "#64748b",
2446
+ strokeOpacity: isSelectedEdge ? "0.75" : "0.32",
2447
+ strokeWidth: isSelectedEdge ? 2.6 : edge.type === "supports" ? 2 : 1.3,
2448
+ x1: source.x * 1e3,
2449
+ x2: target.x * 1e3,
2450
+ y1: source.y * 600,
2451
+ y2: target.y * 600
2452
+ },
2453
+ edge.id
2454
+ );
2455
+ }),
2456
+ selectedNodeId ? similar.map((item) => {
2457
+ const source = nodeById.get(selectedNodeId);
2458
+ const target = nodeById.get(item.node.id);
2459
+ if (!source || !target) return null;
2460
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2461
+ "line",
2462
+ {
2463
+ stroke: "#0ea5e9",
2464
+ strokeDasharray: "5 6",
2465
+ strokeOpacity: "0.42",
2466
+ strokeWidth: "1.8",
2467
+ x1: source.x * 1e3,
2468
+ x2: target.x * 1e3,
2469
+ y1: source.y * 600,
2470
+ y2: target.y * 600
2471
+ },
2472
+ `similar-${item.node.id}`
2473
+ );
2474
+ }) : null,
2475
+ nodes.map((node) => {
2476
+ const isSelected = node.id === selectedNodeId;
2477
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2478
+ "g",
2479
+ {
2480
+ className: "cursor-pointer",
2481
+ onClick: () => onSelectNode(node),
2482
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2483
+ "circle",
2484
+ {
2485
+ cx: node.x * 1e3,
2486
+ cy: node.y * 600,
2487
+ fill: nodeColor(node),
2488
+ r: isSelected ? 9 : 6,
2489
+ stroke: isSelected ? "#0f172a" : "#ffffff",
2490
+ strokeWidth: isSelected ? 3 : 2,
2491
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("title", { children: `${node.name} \xB7 ${formatLabel(node.kind)}` })
2492
+ }
2493
+ )
2494
+ },
2495
+ node.id
2496
+ );
2497
+ })
2498
+ ]
2499
+ }
2500
+ ) });
2501
+ }
2502
+ function BrainNodeInspector({
2503
+ match,
2504
+ node,
2505
+ onSelectNode,
2506
+ related,
2507
+ similar
2508
+ }) {
2509
+ const [tab, setTab] = import_react3.default.useState("overview");
2510
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-3", children: [
2511
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-background p-4", children: [
2512
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
2513
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: node.layer }),
2514
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { status: node.status }),
2515
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: formatLabel(node.kind) })
2516
+ ] }),
2517
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "mt-3 text-base font-semibold", children: node.name }),
2518
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-2 text-sm leading-6 text-muted-foreground", children: node.content || "-" }),
2519
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MatchBadges, { match })
2520
+ ] }),
2521
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "inline-flex w-full overflow-hidden rounded-md border bg-background", children: ["overview", "related", "similar", "evidence", "json"].map((item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2522
+ "button",
2523
+ {
2524
+ className: cn(
2525
+ "min-w-0 flex-1 px-2 py-2 text-xs transition-colors",
2526
+ tab === item ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted/60"
2527
+ ),
2528
+ onClick: () => setTab(item),
2529
+ type: "button",
2530
+ children: formatLabel(item)
2531
+ },
2532
+ item
2533
+ )) }),
2534
+ tab === "overview" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BrainOverview, { node }) : null,
2535
+ tab === "related" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RelatedPanel, { onSelectNode, related }) : null,
2536
+ tab === "similar" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SimilarPanel, { onSelectNode, similar }) : null,
2537
+ tab === "evidence" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EvidencePanel, { node }) : null,
2538
+ tab === "json" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(JsonPanel, { title: "Node JSON", value: node, minHeight: 300 }) : null
2539
+ ] });
2540
+ }
2541
+ function BrainOverview({ node }) {
2542
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "rounded-lg border bg-background p-4", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("dl", { className: "grid gap-2 text-xs", children: [
2543
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Agent", value: node.agentId }),
2544
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Thread", value: node.threadId }),
2545
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Memory space", value: node.memorySpaceId }),
2546
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Checkpoint", value: node.checkpointId }),
2547
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Source field", value: node.sourceField }),
2548
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Confidence", value: formatNullableNumber(node.confidence) }),
2549
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Updated", value: formatDateTime(node.updatedAt) })
2550
+ ] }) });
2551
+ }
2552
+ function RelatedPanel({
2553
+ onSelectNode,
2554
+ related
2555
+ }) {
2556
+ if (related.length === 0) {
2557
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2558
+ EmptyState,
2559
+ {
2560
+ icon: import_lucide_react7.GitBranch,
2561
+ title: "No explicit relations",
2562
+ description: "Relation edges will appear here when this node is connected to other concepts."
2563
+ }
2564
+ );
2565
+ }
2566
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-2", children: related.map((item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2567
+ "button",
2568
+ {
2569
+ className: "w-full rounded-lg border bg-background p-3 text-left transition-colors hover:bg-muted/40",
2570
+ onClick: () => onSelectNode(item.node),
2571
+ type: "button",
2572
+ children: [
2573
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
2574
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: formatLabel(item.edge.type) }),
2575
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "secondary", children: item.direction === "out" ? "Outgoing" : "Incoming" })
2576
+ ] }),
2577
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-2 text-sm font-medium", children: item.node.name }),
2578
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-1 line-clamp-3 text-xs leading-5 text-muted-foreground", children: item.node.content || "-" })
2579
+ ]
2580
+ },
2581
+ item.edge.id
2582
+ )) });
2583
+ }
2584
+ function SimilarPanel({
2585
+ onSelectNode,
2586
+ similar
2587
+ }) {
2588
+ if (similar.length === 0) {
2589
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2590
+ EmptyState,
2591
+ {
2592
+ icon: import_lucide_react7.Sparkles,
2593
+ title: "No semantic neighbors",
2594
+ description: "Similar nodes appear here when the selected node has an embedding."
2595
+ }
2596
+ );
2597
+ }
2598
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-2", children: similar.map((item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2599
+ "button",
2600
+ {
2601
+ className: "w-full rounded-lg border bg-background p-3 text-left transition-colors hover:bg-muted/40",
2602
+ onClick: () => onSelectNode(item.node),
2603
+ type: "button",
2604
+ children: [
2605
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
2606
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "secondary", children: formatSimilarityScore(item.similarity) }),
2607
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: item.node.layer }),
2608
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: formatLabel(item.node.kind) })
2609
+ ] }),
2610
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-2 text-sm font-medium", children: item.node.name }),
2611
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-1 line-clamp-3 text-xs leading-5 text-muted-foreground", children: item.node.content || "-" })
2612
+ ]
2613
+ },
2614
+ item.node.id
2615
+ )) });
2616
+ }
2617
+ function EvidencePanel({ node }) {
2618
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-background p-4", children: [
2619
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("dl", { className: "grid gap-2 text-xs", children: [
2620
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Source", value: node.sourceType }),
2621
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Source ID", value: node.sourceId }),
2622
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Thread", value: node.threadId }),
2623
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Checkpoint", value: node.checkpointId })
2624
+ ] }),
2625
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-4", children: [
2626
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "Source messages" }),
2627
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-2 flex flex-wrap gap-1", children: node.sourceMessageIds.length ? node.sourceMessageIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { className: "max-w-full truncate", variant: "outline", children: id }, id)) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: "-" }) })
2628
+ ] })
2629
+ ] });
2630
+ }
2631
+ function MatchBadges({ match }) {
2632
+ if (!match?.reasons.length) return null;
2633
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-2 flex flex-wrap gap-1", children: match.reasons.slice(0, 4).map((reason) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { className: "text-[10px]", variant: "outline", children: reason }, reason)) });
2634
+ }
2635
+ function InspectorRow({
2636
+ label,
2637
+ value
2638
+ }) {
2639
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "grid grid-cols-[110px_minmax(0,1fr)] gap-2", children: [
2640
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dt", { className: "text-muted-foreground", children: label }),
2641
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dd", { className: "truncate font-mono", children: value || "-" })
2642
+ ] });
2643
+ }
2644
+ function LayerBadge({ layer }) {
2645
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: layer === "working" ? "secondary" : "default", children: formatLabel(layer) });
2646
+ }
2647
+ function nodeColor(node) {
2648
+ if (node.layer === "working") return "#0891b2";
2649
+ if (node.kind === "decision") return "#4f46e5";
2650
+ if (node.kind === "risk") return "#dc2626";
2651
+ if (node.kind === "preference") return "#16a34a";
2652
+ return "#475569";
2653
+ }
2654
+ function formatLabel(value) {
2655
+ return value.replaceAll("_", " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
2656
+ }
2657
+ function formatDateTime(value) {
2658
+ if (!value) return "-";
2659
+ const date = new Date(value);
2660
+ if (Number.isNaN(date.getTime())) return value;
2661
+ return date.toLocaleString();
2662
+ }
2663
+ function formatNullableNumber(value) {
2664
+ return typeof value === "number" && Number.isFinite(value) ? value.toFixed(2) : "-";
2665
+ }
2666
+ function formatSimilarityScore(value) {
2667
+ return Number.isFinite(value) ? `Similarity ${value.toFixed(2)}` : "-";
2668
+ }
2669
+ function emptyBrainResponse() {
2670
+ return {
2671
+ nodes: [],
2672
+ edges: [],
2673
+ clusters: [],
2674
+ stats: {
2675
+ total: 0,
2676
+ byLayer: {},
2677
+ byKind: {},
2678
+ byStatus: {}
2679
+ },
2680
+ matches: {},
2681
+ related: [],
2682
+ similar: [],
2683
+ semantic: {
2684
+ requested: false,
2685
+ available: false,
2686
+ error: null
2687
+ },
2688
+ pageInfo: {
2689
+ limit: 0,
2690
+ offset: 0,
2691
+ returned: 0
2692
+ }
2693
+ };
2694
+ }
2695
+
2696
+ // src/modules/collections/index.tsx
2697
+ var import_react4 = __toESM(require("react"), 1);
2698
+ var import_lucide_react8 = require("lucide-react");
2699
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2008
2700
  function collectionsModule() {
2009
2701
  return {
2010
2702
  group: "data",
2011
- icon: import_lucide_react7.Database,
2703
+ icon: import_lucide_react8.Database,
2012
2704
  id: "collections",
2013
2705
  label: "Collections",
2014
2706
  navItems: [{
2015
2707
  group: "data",
2016
- icon: import_lucide_react7.Database,
2708
+ icon: import_lucide_react8.Database,
2017
2709
  id: "collections",
2018
2710
  label: "Collections",
2019
2711
  order: 20,
@@ -2023,23 +2715,23 @@ function collectionsModule() {
2023
2715
  {
2024
2716
  id: "collections",
2025
2717
  title: "Collections",
2026
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CollectionsPage, { context })
2718
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CollectionsPage, { context })
2027
2719
  },
2028
2720
  {
2029
2721
  id: "collections.detail",
2030
2722
  title: "Collection Item",
2031
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CollectionDetailPage, { context })
2723
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CollectionDetailPage, { context })
2032
2724
  }
2033
2725
  ]
2034
2726
  };
2035
2727
  }
2036
2728
  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(() => {
2729
+ const [collections, setCollections] = import_react4.default.useState([]);
2730
+ const [selected, setSelected] = import_react4.default.useState(null);
2731
+ const [search, setSearch] = import_react4.default.useState("");
2732
+ const [items, setItems] = import_react4.default.useState([]);
2733
+ const [error, setError] = import_react4.default.useState(null);
2734
+ import_react4.default.useEffect(() => {
2043
2735
  let active = true;
2044
2736
  void context.client.listCollections().then((names) => {
2045
2737
  if (!active) return;
@@ -2052,7 +2744,7 @@ function CollectionsPage({ context }) {
2052
2744
  active = false;
2053
2745
  };
2054
2746
  }, [context.client, context.refreshKey]);
2055
- import_react3.default.useEffect(() => {
2747
+ import_react4.default.useEffect(() => {
2056
2748
  if (!selected) return;
2057
2749
  let active = true;
2058
2750
  setError(null);
@@ -2069,30 +2761,30 @@ function CollectionsPage({ context }) {
2069
2761
  active = false;
2070
2762
  };
2071
2763
  }, [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)(
2764
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
2765
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2074
2766
  PageHeader,
2075
2767
  {
2076
2768
  title: "Collections",
2077
2769
  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)(
2770
+ actions: selected && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2079
2771
  Button,
2080
2772
  {
2081
2773
  onClick: () => context.navigate("collections.detail", { collection: selected }),
2082
2774
  size: "sm",
2083
2775
  type: "button",
2084
2776
  children: [
2085
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Plus, { className: "size-3" }),
2777
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Plus, { className: "size-3" }),
2086
2778
  "New"
2087
2779
  ]
2088
2780
  }
2089
2781
  )
2090
2782
  }
2091
2783
  ),
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)(
2784
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid gap-4 lg:grid-cols-[240px_minmax(0,1fr)]", children: [
2785
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
2786
+ /* @__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" }),
2787
+ /* @__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
2788
  "button",
2097
2789
  {
2098
2790
  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 +2795,8 @@ function CollectionsPage({ context }) {
2103
2795
  collection
2104
2796
  )) })
2105
2797
  ] }),
2106
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-3", children: [
2107
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2798
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-3", children: [
2799
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2108
2800
  FilterBar,
2109
2801
  {
2110
2802
  onSearchChange: setSearch,
@@ -2112,7 +2804,7 @@ function CollectionsPage({ context }) {
2112
2804
  searchValue: search
2113
2805
  }
2114
2806
  ),
2115
- error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Unable to load collection", description: error }) : selected ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2807
+ error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to load collection", description: error }) : selected ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2116
2808
  ResourceTable,
2117
2809
  {
2118
2810
  rows: items,
@@ -2121,10 +2813,10 @@ function CollectionsPage({ context }) {
2121
2813
  collection: selected,
2122
2814
  itemId: getItemId(item)
2123
2815
  }),
2124
- empty: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2816
+ empty: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2125
2817
  EmptyState,
2126
2818
  {
2127
- icon: import_lucide_react7.Database,
2819
+ icon: import_lucide_react8.Database,
2128
2820
  title: `No ${selected} records`,
2129
2821
  description: "Create a record or adjust the current filters."
2130
2822
  }
@@ -2133,16 +2825,16 @@ function CollectionsPage({ context }) {
2133
2825
  {
2134
2826
  id: "id",
2135
2827
  header: "ID",
2136
- render: (item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-sm truncate font-mono text-xs", children: getItemId(item) })
2828
+ render: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-w-sm truncate font-mono text-xs", children: getItemId(item) })
2137
2829
  },
2138
2830
  {
2139
2831
  id: "preview",
2140
2832
  header: "Preview",
2141
- render: (item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "max-w-xl truncate text-sm", children: getItemPreview(item) })
2833
+ render: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-w-xl truncate text-sm", children: getItemPreview(item) })
2142
2834
  }
2143
2835
  ]
2144
2836
  }
2145
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "No collections" })
2837
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "No collections" })
2146
2838
  ] })
2147
2839
  ] })
2148
2840
  ] });
@@ -2150,10 +2842,10 @@ function CollectionsPage({ context }) {
2150
2842
  function CollectionDetailPage({ context }) {
2151
2843
  const collection = context.route.params?.collection;
2152
2844
  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);
2845
+ const [item, setItem] = import_react4.default.useState(null);
2846
+ const [error, setError] = import_react4.default.useState(null);
2155
2847
  const isNew = !itemId;
2156
- import_react3.default.useEffect(() => {
2848
+ import_react4.default.useEffect(() => {
2157
2849
  if (!collection || !itemId) {
2158
2850
  setItem(null);
2159
2851
  return;
@@ -2171,8 +2863,8 @@ function CollectionDetailPage({ context }) {
2171
2863
  active = false;
2172
2864
  };
2173
2865
  }, [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 });
2866
+ if (!collection) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Collection not selected" });
2867
+ if (error) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to load item", description: error });
2176
2868
  const Editor = context.collectionEditors[collection];
2177
2869
  const save = async (value) => {
2178
2870
  if (isNew) {
@@ -2192,14 +2884,14 @@ function CollectionDetailPage({ context }) {
2192
2884
  });
2193
2885
  setItem(updated);
2194
2886
  };
2195
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
2196
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2887
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
2888
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2197
2889
  PageHeader,
2198
2890
  {
2199
2891
  title: isNew ? `New ${collection}` : `${collection} / ${itemId}`,
2200
2892
  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)(
2893
+ actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
2894
+ !isNew && itemId && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2203
2895
  Button,
2204
2896
  {
2205
2897
  onClick: () => {
@@ -2211,12 +2903,12 @@ function CollectionDetailPage({ context }) {
2211
2903
  type: "button",
2212
2904
  variant: "destructive",
2213
2905
  children: [
2214
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Trash2, { className: "size-3" }),
2906
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Trash2, { className: "size-3" }),
2215
2907
  "Delete"
2216
2908
  ]
2217
2909
  }
2218
2910
  ),
2219
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2911
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2220
2912
  Button,
2221
2913
  {
2222
2914
  onClick: () => context.navigate("collections"),
@@ -2229,7 +2921,7 @@ function CollectionDetailPage({ context }) {
2229
2921
  ] })
2230
2922
  }
2231
2923
  ),
2232
- Editor ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2924
+ Editor ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2233
2925
  Editor,
2234
2926
  {
2235
2927
  collection,
@@ -2240,7 +2932,7 @@ function CollectionDetailPage({ context }) {
2240
2932
  onSaved: setItem,
2241
2933
  onDeleted: () => context.navigate("collections")
2242
2934
  }
2243
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2935
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2244
2936
  JsonPanel,
2245
2937
  {
2246
2938
  title: "Advanced JSON",
@@ -2265,18 +2957,18 @@ function getItemPreview(item) {
2265
2957
  }
2266
2958
 
2267
2959
  // 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");
2960
+ var import_react5 = __toESM(require("react"), 1);
2961
+ var import_lucide_react9 = require("lucide-react");
2962
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2271
2963
  function eventsModule() {
2272
2964
  return {
2273
2965
  group: "operate",
2274
- icon: import_lucide_react8.Activity,
2966
+ icon: import_lucide_react9.Activity,
2275
2967
  id: "events",
2276
2968
  label: "Events",
2277
2969
  navItems: [{
2278
2970
  group: "operate",
2279
- icon: import_lucide_react8.Activity,
2971
+ icon: import_lucide_react9.Activity,
2280
2972
  id: "events",
2281
2973
  label: "Events",
2282
2974
  order: 30,
@@ -2285,7 +2977,7 @@ function eventsModule() {
2285
2977
  routes: [{
2286
2978
  id: "events",
2287
2979
  title: "Events",
2288
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EventsPage, { context })
2980
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EventsPage, { context })
2289
2981
  }]
2290
2982
  };
2291
2983
  }
@@ -2299,17 +2991,17 @@ var EVENT_STATUSES = [
2299
2991
  "overwritten"
2300
2992
  ];
2301
2993
  function EventsPage({ context }) {
2302
- const [threadId, setThreadId] = import_react4.default.useState("");
2303
- const [status, setStatus] = import_react4.default.useState(
2994
+ const [threadId, setThreadId] = import_react5.default.useState("");
2995
+ const [status, setStatus] = import_react5.default.useState(
2304
2996
  "all"
2305
2997
  );
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);
2998
+ const [eventType, setEventType] = import_react5.default.useState("");
2999
+ const [traceId, setTraceId] = import_react5.default.useState("");
3000
+ const [events, setEvents] = import_react5.default.useState([]);
3001
+ const [selectedEvent, setSelectedEvent] = import_react5.default.useState(null);
3002
+ const [error, setError] = import_react5.default.useState(null);
3003
+ const [loading, setLoading] = import_react5.default.useState(false);
3004
+ const [hasLoaded, setHasLoaded] = import_react5.default.useState(false);
2313
3005
  const inspect = async () => {
2314
3006
  setHasLoaded(true);
2315
3007
  setLoading(true);
@@ -2335,21 +3027,21 @@ function EventsPage({ context }) {
2335
3027
  setLoading(false);
2336
3028
  }
2337
3029
  };
2338
- import_react4.default.useEffect(() => {
3030
+ import_react5.default.useEffect(() => {
2339
3031
  void inspect();
2340
3032
  }, [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)(
3033
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-4", children: [
3034
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2343
3035
  PageHeader,
2344
3036
  {
2345
3037
  title: "Events",
2346
3038
  description: "Queue and event inspection across the active namespace."
2347
3039
  }
2348
3040
  ),
2349
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3041
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2350
3042
  FilterBar,
2351
3043
  {
2352
- actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3044
+ actions: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2353
3045
  Button,
2354
3046
  {
2355
3047
  disabled: loading,
@@ -2357,13 +3049,13 @@ function EventsPage({ context }) {
2357
3049
  size: "sm",
2358
3050
  type: "button",
2359
3051
  children: [
2360
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Search, { className: "size-3" }),
3052
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react9.Search, { className: "size-3" }),
2361
3053
  loading ? "Loading" : "Inspect"
2362
3054
  ]
2363
3055
  }
2364
3056
  ),
2365
3057
  children: [
2366
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3058
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2367
3059
  Input,
2368
3060
  {
2369
3061
  className: "h-8 w-[220px]",
@@ -2375,18 +3067,18 @@ function EventsPage({ context }) {
2375
3067
  value: threadId
2376
3068
  }
2377
3069
  ),
2378
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3070
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2379
3071
  Select,
2380
3072
  {
2381
3073
  value: status,
2382
3074
  onValueChange: (value) => setStatus(value),
2383
3075
  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)) })
3076
+ /* @__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, {}) }),
3077
+ /* @__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
3078
  ]
2387
3079
  }
2388
3080
  ),
2389
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3081
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2390
3082
  Input,
2391
3083
  {
2392
3084
  className: "h-8 w-[180px]",
@@ -2398,7 +3090,7 @@ function EventsPage({ context }) {
2398
3090
  value: eventType
2399
3091
  }
2400
3092
  ),
2401
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3093
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2402
3094
  Input,
2403
3095
  {
2404
3096
  className: "h-8 w-[180px]",
@@ -2413,21 +3105,21 @@ function EventsPage({ context }) {
2413
3105
  ]
2414
3106
  }
2415
3107
  ),
2416
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to inspect event", description: error }) : !hasLoaded && loading ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3108
+ error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmptyState, { title: "Unable to inspect event", description: error }) : !hasLoaded && loading ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2417
3109
  EmptyState,
2418
3110
  {
2419
- icon: import_lucide_react8.Activity,
3111
+ icon: import_lucide_react9.Activity,
2420
3112
  title: "Loading events",
2421
3113
  description: "Fetching recent queue events for the active namespace."
2422
3114
  }
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)(
3115
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "grid gap-4 xl:grid-cols-[1fr_420px]", children: [
3116
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2425
3117
  ResourceTable,
2426
3118
  {
2427
3119
  rows: events,
2428
3120
  getRowKey: (row) => row.id,
2429
3121
  onRowClick: setSelectedEvent,
2430
- empty: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3122
+ empty: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2431
3123
  EmptyState,
2432
3124
  {
2433
3125
  title: "No matching events",
@@ -2449,7 +3141,7 @@ function EventsPage({ context }) {
2449
3141
  {
2450
3142
  id: "status",
2451
3143
  header: "Status",
2452
- render: (row) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StatusBadge, { status: row.status })
3144
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusBadge, { status: row.status })
2453
3145
  },
2454
3146
  {
2455
3147
  id: "trace",
@@ -2459,19 +3151,19 @@ function EventsPage({ context }) {
2459
3151
  {
2460
3152
  id: "created",
2461
3153
  header: "Created",
2462
- render: (row) => formatDateTime(row.createdAt)
3154
+ render: (row) => formatDateTime2(row.createdAt)
2463
3155
  }
2464
3156
  ]
2465
3157
  }
2466
3158
  ),
2467
- selectedEvent ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3159
+ selectedEvent ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2468
3160
  JsonPanel,
2469
3161
  {
2470
3162
  title: "Event JSON",
2471
3163
  value: selectedEvent,
2472
3164
  minHeight: 420
2473
3165
  }
2474
- ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3166
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2475
3167
  EmptyState,
2476
3168
  {
2477
3169
  title: "No event selected",
@@ -2481,7 +3173,7 @@ function EventsPage({ context }) {
2481
3173
  ] })
2482
3174
  ] });
2483
3175
  }
2484
- function formatDateTime(value) {
3176
+ function formatDateTime2(value) {
2485
3177
  if (!value) return "-";
2486
3178
  const date = new Date(value);
2487
3179
  if (Number.isNaN(date.getTime())) return value;
@@ -2494,18 +3186,18 @@ function formatDateTime(value) {
2494
3186
  }
2495
3187
 
2496
3188
  // 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");
3189
+ var import_react6 = __toESM(require("react"), 1);
3190
+ var import_lucide_react10 = require("lucide-react");
3191
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2500
3192
  function overviewModule() {
2501
3193
  return {
2502
3194
  group: "operate",
2503
- icon: import_lucide_react9.Activity,
3195
+ icon: import_lucide_react10.Activity,
2504
3196
  id: "overview",
2505
3197
  label: "Overview",
2506
3198
  navItems: [{
2507
3199
  group: "operate",
2508
- icon: import_lucide_react9.Activity,
3200
+ icon: import_lucide_react10.Activity,
2509
3201
  id: "overview",
2510
3202
  label: "Overview",
2511
3203
  order: 10,
@@ -2514,17 +3206,17 @@ function overviewModule() {
2514
3206
  routes: [{
2515
3207
  id: "overview",
2516
3208
  title: "Overview",
2517
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(OverviewPage, { context })
3209
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(OverviewPage, { context })
2518
3210
  }]
2519
3211
  };
2520
3212
  }
2521
3213
  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(() => {
3214
+ const [overview, setOverview] = import_react6.default.useState(null);
3215
+ const [threads, setThreads] = import_react6.default.useState([]);
3216
+ const [agents, setAgents] = import_react6.default.useState([]);
3217
+ const [error, setError] = import_react6.default.useState(null);
3218
+ const [isLoading, setIsLoading] = import_react6.default.useState(false);
3219
+ import_react6.default.useEffect(() => {
2528
3220
  let active = true;
2529
3221
  setIsLoading(true);
2530
3222
  setError(null);
@@ -2557,11 +3249,11 @@ function OverviewPage({ context }) {
2557
3249
  };
2558
3250
  }, [context.client, context.refreshKey, context.scope.namespace]);
2559
3251
  if (error) {
2560
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmptyState, { title: "Unable to load overview", description: error });
3252
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load overview", description: error });
2561
3253
  }
2562
3254
  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)(
3255
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
3256
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2565
3257
  PageHeader,
2566
3258
  {
2567
3259
  title: "Overview",
@@ -2572,41 +3264,41 @@ function OverviewPage({ context }) {
2572
3264
  ]
2573
3265
  }
2574
3266
  ),
2575
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3267
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2576
3268
  MetricStrip,
2577
3269
  {
2578
3270
  items: [
2579
3271
  {
2580
3272
  detail: `${formatNumber(overview?.threadTotals.active ?? 0)} active`,
2581
- icon: import_lucide_react9.MessageSquare,
3273
+ icon: import_lucide_react10.MessageSquare,
2582
3274
  label: "Threads",
2583
3275
  value: formatNumber(overview?.threadTotals.total ?? 0)
2584
3276
  },
2585
3277
  {
2586
3278
  detail: `${formatNumber(overview?.participantTotals.agents ?? 0)} agents`,
2587
- icon: import_lucide_react9.Users,
3279
+ icon: import_lucide_react10.Users,
2588
3280
  label: "Participants",
2589
3281
  value: formatNumber(overview?.participantTotals.total ?? 0)
2590
3282
  },
2591
3283
  {
2592
3284
  detail: `${formatNumber(overview?.llmTotals.totalCalls ?? 0)} LLM calls`,
2593
- icon: import_lucide_react9.Wallet,
3285
+ icon: import_lucide_react10.Wallet,
2594
3286
  label: "Cost",
2595
3287
  value: formatMetricValue(overview?.llmTotals.totalCostUsd ?? 0, "cost")
2596
3288
  },
2597
3289
  {
2598
3290
  detail: `${formatNumber(queueFailures)} failures/expired`,
2599
- icon: queueFailures > 0 ? import_lucide_react9.AlertTriangle : import_lucide_react9.Sparkles,
3291
+ icon: queueFailures > 0 ? import_lucide_react10.AlertTriangle : import_lucide_react10.Sparkles,
2600
3292
  label: "Queue",
2601
3293
  value: formatNumber(overview?.queueTotals.total ?? 0)
2602
3294
  }
2603
3295
  ]
2604
3296
  }
2605
3297
  ),
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)(
3298
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "grid gap-4 xl:grid-cols-2", children: [
3299
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("section", { className: "space-y-3", children: [
3300
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PageHeader, { title: "Recent Threads" }),
3301
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2610
3302
  ResourceTable,
2611
3303
  {
2612
3304
  rows: threads,
@@ -2616,15 +3308,15 @@ function OverviewPage({ context }) {
2616
3308
  {
2617
3309
  id: "name",
2618
3310
  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" })
3311
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
3312
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate font-medium", children: thread.name || thread.threadId }),
3313
+ /* @__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
3314
  ] })
2623
3315
  },
2624
3316
  {
2625
3317
  id: "status",
2626
3318
  header: "Status",
2627
- render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusBadge, { status: thread.status })
3319
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusBadge, { status: thread.status })
2628
3320
  },
2629
3321
  {
2630
3322
  align: "right",
@@ -2636,9 +3328,9 @@ function OverviewPage({ context }) {
2636
3328
  }
2637
3329
  )
2638
3330
  ] }),
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)(
3331
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("section", { className: "space-y-3", children: [
3332
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PageHeader, { title: "Top Agents" }),
3333
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2642
3334
  ResourceTable,
2643
3335
  {
2644
3336
  rows: agents,
@@ -2648,11 +3340,11 @@ function OverviewPage({ context }) {
2648
3340
  {
2649
3341
  id: "agent",
2650
3342
  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 })
3343
+ render: (agent) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
3344
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react10.Bot, { className: "size-4 text-muted-foreground" }),
3345
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
3346
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "font-medium", children: agent.displayName }),
3347
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-xs text-muted-foreground", children: agent.agentId })
2656
3348
  ] })
2657
3349
  ] })
2658
3350
  },
@@ -2677,18 +3369,18 @@ function OverviewPage({ context }) {
2677
3369
  }
2678
3370
 
2679
3371
  // 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");
3372
+ var import_react7 = __toESM(require("react"), 1);
3373
+ var import_lucide_react11 = require("lucide-react");
3374
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2683
3375
  function participantsModule() {
2684
3376
  return {
2685
3377
  group: "data",
2686
- icon: import_lucide_react10.Users,
3378
+ icon: import_lucide_react11.Users,
2687
3379
  id: "participants",
2688
3380
  label: "Participants",
2689
3381
  navItems: [{
2690
3382
  group: "data",
2691
- icon: import_lucide_react10.Users,
3383
+ icon: import_lucide_react11.Users,
2692
3384
  id: "participants",
2693
3385
  label: "Participants",
2694
3386
  order: 10,
@@ -2698,21 +3390,21 @@ function participantsModule() {
2698
3390
  {
2699
3391
  id: "participants",
2700
3392
  title: "Participants",
2701
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ParticipantsPage, { context })
3393
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ParticipantsPage, { context })
2702
3394
  },
2703
3395
  {
2704
3396
  id: "participants.detail",
2705
3397
  title: "Participant Detail",
2706
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ParticipantDetailPage, { context })
3398
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ParticipantDetailPage, { context })
2707
3399
  }
2708
3400
  ]
2709
3401
  };
2710
3402
  }
2711
3403
  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(() => {
3404
+ const [search, setSearch] = import_react7.default.useState("");
3405
+ const [participants, setParticipants] = import_react7.default.useState([]);
3406
+ const [error, setError] = import_react7.default.useState(null);
3407
+ import_react7.default.useEffect(() => {
2716
3408
  let active = true;
2717
3409
  setError(null);
2718
3410
  void context.client.listParticipants({
@@ -2728,15 +3420,15 @@ function ParticipantsPage({ context }) {
2728
3420
  active = false;
2729
3421
  };
2730
3422
  }, [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)(
3423
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
3424
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2733
3425
  PageHeader,
2734
3426
  {
2735
3427
  title: "Participants",
2736
3428
  description: "Humans, agents, and jobs observed by Copilotz across conversations."
2737
3429
  }
2738
3430
  ),
2739
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3431
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2740
3432
  FilterBar,
2741
3433
  {
2742
3434
  onSearchChange: setSearch,
@@ -2744,7 +3436,7 @@ function ParticipantsPage({ context }) {
2744
3436
  searchValue: search
2745
3437
  }
2746
3438
  ),
2747
- error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load participants", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3439
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load participants", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2748
3440
  ResourceTable,
2749
3441
  {
2750
3442
  rows: participants,
@@ -2752,10 +3444,10 @@ function ParticipantsPage({ context }) {
2752
3444
  onRowClick: (participant) => context.navigate("participants.detail", {
2753
3445
  participantId: participant.externalId
2754
3446
  }),
2755
- empty: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3447
+ empty: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2756
3448
  EmptyState,
2757
3449
  {
2758
- icon: import_lucide_react10.Users,
3450
+ icon: import_lucide_react11.Users,
2759
3451
  title: "No participants",
2760
3452
  description: "Participants appear after messages or jobs are processed."
2761
3453
  }
@@ -2764,15 +3456,15 @@ function ParticipantsPage({ context }) {
2764
3456
  {
2765
3457
  id: "participant",
2766
3458
  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 })
3459
+ render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
3460
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-md truncate font-medium", children: participant.displayName }),
3461
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: participant.externalId })
2770
3462
  ] })
2771
3463
  },
2772
3464
  {
2773
3465
  id: "type",
2774
3466
  header: "Type",
2775
- render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusBadge, { status: participant.participantType })
3467
+ render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusBadge, { status: participant.participantType })
2776
3468
  },
2777
3469
  {
2778
3470
  id: "scope",
@@ -2798,9 +3490,9 @@ function ParticipantsPage({ context }) {
2798
3490
  }
2799
3491
  function ParticipantDetailPage({ context }) {
2800
3492
  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(() => {
3493
+ const [participant, setParticipant] = import_react7.default.useState(null);
3494
+ const [error, setError] = import_react7.default.useState(null);
3495
+ import_react7.default.useEffect(() => {
2804
3496
  if (!participantId) return;
2805
3497
  let active = true;
2806
3498
  setError(null);
@@ -2816,19 +3508,19 @@ function ParticipantDetailPage({ context }) {
2816
3508
  };
2817
3509
  }, [context.client, context.refreshKey, context.scope.namespace, participantId]);
2818
3510
  if (!participantId) {
2819
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Participant not selected" });
3511
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Participant not selected" });
2820
3512
  }
2821
3513
  if (error) {
2822
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load participant", description: error });
3514
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load participant", description: error });
2823
3515
  }
2824
3516
  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)(
3517
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
3518
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2827
3519
  PageHeader,
2828
3520
  {
2829
3521
  title: String(participant?.displayName ?? participantId),
2830
3522
  description: "Participant profile, activity-ready metrics, and advanced record data.",
2831
- actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3523
+ actions: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2832
3524
  "button",
2833
3525
  {
2834
3526
  className: "text-sm text-muted-foreground hover:text-foreground",
@@ -2839,7 +3531,7 @@ function ParticipantDetailPage({ context }) {
2839
3531
  )
2840
3532
  }
2841
3533
  ),
2842
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3534
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2843
3535
  MetricStrip,
2844
3536
  {
2845
3537
  items: [
@@ -2849,24 +3541,24 @@ function ParticipantDetailPage({ context }) {
2849
3541
  ]
2850
3542
  }
2851
3543
  ),
2852
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(JsonPanel, { title: "Advanced JSON", value: participant, minHeight: 460 })
3544
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(JsonPanel, { title: "Advanced JSON", value: participant, minHeight: 460 })
2853
3545
  ] });
2854
3546
  }
2855
3547
 
2856
3548
  // 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");
3549
+ var import_react8 = __toESM(require("react"), 1);
3550
+ var import_lucide_react12 = require("lucide-react");
3551
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2860
3552
  var MESSAGE_PAGE_SIZE = 50;
2861
3553
  function threadsModule() {
2862
3554
  return {
2863
3555
  group: "operate",
2864
- icon: import_lucide_react11.MessageSquare,
3556
+ icon: import_lucide_react12.MessageSquare,
2865
3557
  id: "threads",
2866
3558
  label: "Threads",
2867
3559
  navItems: [{
2868
3560
  group: "operate",
2869
- icon: import_lucide_react11.MessageSquare,
3561
+ icon: import_lucide_react12.MessageSquare,
2870
3562
  id: "threads",
2871
3563
  label: "Threads",
2872
3564
  order: 40,
@@ -2876,22 +3568,22 @@ function threadsModule() {
2876
3568
  {
2877
3569
  id: "threads",
2878
3570
  title: "Threads",
2879
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThreadsPage, { context })
3571
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadsPage, { context })
2880
3572
  },
2881
3573
  {
2882
3574
  id: "threads.detail",
2883
3575
  title: "Thread Detail",
2884
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThreadDetailPage, { context })
3576
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadDetailPage, { context })
2885
3577
  }
2886
3578
  ]
2887
3579
  };
2888
3580
  }
2889
3581
  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(() => {
3582
+ const [search, setSearch] = import_react8.default.useState("");
3583
+ const [threads, setThreads] = import_react8.default.useState([]);
3584
+ const [error, setError] = import_react8.default.useState(null);
3585
+ const [isLoading, setIsLoading] = import_react8.default.useState(false);
3586
+ import_react8.default.useEffect(() => {
2895
3587
  let active = true;
2896
3588
  setIsLoading(true);
2897
3589
  setError(null);
@@ -2910,8 +3602,8 @@ function ThreadsPage({ context }) {
2910
3602
  active = false;
2911
3603
  };
2912
3604
  }, [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)(
3605
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
3606
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2915
3607
  PageHeader,
2916
3608
  {
2917
3609
  title: "Threads",
@@ -2919,7 +3611,7 @@ function ThreadsPage({ context }) {
2919
3611
  badges: isLoading ? [{ label: "Loading" }] : []
2920
3612
  }
2921
3613
  ),
2922
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3614
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2923
3615
  FilterBar,
2924
3616
  {
2925
3617
  onSearchChange: setSearch,
@@ -2927,16 +3619,16 @@ function ThreadsPage({ context }) {
2927
3619
  searchValue: search
2928
3620
  }
2929
3621
  ),
2930
- error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load threads", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3622
+ error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "Unable to load threads", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2931
3623
  ResourceTable,
2932
3624
  {
2933
3625
  rows: threads,
2934
3626
  getRowKey: (thread) => thread.threadId,
2935
3627
  onRowClick: (thread) => context.navigate("threads.detail", { threadId: thread.threadId }),
2936
- empty: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3628
+ empty: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2937
3629
  EmptyState,
2938
3630
  {
2939
- icon: import_lucide_react11.MessageSquare,
3631
+ icon: import_lucide_react12.MessageSquare,
2940
3632
  title: "No threads",
2941
3633
  description: "Threads will appear after conversations start flowing."
2942
3634
  }
@@ -2945,15 +3637,15 @@ function ThreadsPage({ context }) {
2945
3637
  {
2946
3638
  id: "thread",
2947
3639
  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" })
3640
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0", children: [
3641
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "max-w-xl truncate font-medium", children: thread.name || thread.threadId }),
3642
+ /* @__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
3643
  ] })
2952
3644
  },
2953
3645
  {
2954
3646
  id: "status",
2955
3647
  header: "Status",
2956
- render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusBadge, { status: thread.status })
3648
+ render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusBadge, { status: thread.status })
2957
3649
  },
2958
3650
  {
2959
3651
  align: "right",
@@ -2972,7 +3664,7 @@ function ThreadsPage({ context }) {
2972
3664
  {
2973
3665
  id: "activity",
2974
3666
  header: "Last activity",
2975
- render: (thread) => formatDateTime2(thread.lastActivityAt)
3667
+ render: (thread) => formatDateTime3(thread.lastActivityAt)
2976
3668
  }
2977
3669
  ]
2978
3670
  }
@@ -2982,7 +3674,7 @@ function ThreadsPage({ context }) {
2982
3674
  function ThreadDetailPage({ context }) {
2983
3675
  const threadId = context.route.params?.threadId;
2984
3676
  if (!threadId) {
2985
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3677
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2986
3678
  EmptyState,
2987
3679
  {
2988
3680
  title: "Thread not selected",
@@ -2990,19 +3682,19 @@ function ThreadDetailPage({ context }) {
2990
3682
  }
2991
3683
  );
2992
3684
  }
2993
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThreadInspector, { context, threadId });
3685
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadInspector, { context, threadId });
2994
3686
  }
2995
3687
  function ThreadInspector({
2996
3688
  context,
2997
3689
  threadId
2998
3690
  }) {
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(() => {
3691
+ const [thread, setThread] = import_react8.default.useState(null);
3692
+ const [messages, setMessages] = import_react8.default.useState([]);
3693
+ const [pageInfo, setPageInfo] = import_react8.default.useState(null);
3694
+ const [isLoading, setIsLoading] = import_react8.default.useState(true);
3695
+ const [isLoadingMore, setIsLoadingMore] = import_react8.default.useState(false);
3696
+ const [error, setError] = import_react8.default.useState(null);
3697
+ import_react8.default.useEffect(() => {
3006
3698
  let active = true;
3007
3699
  setIsLoading(true);
3008
3700
  setError(null);
@@ -3043,13 +3735,13 @@ function ThreadInspector({
3043
3735
  }
3044
3736
  };
3045
3737
  if (isLoading) {
3046
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { icon: import_lucide_react11.Loader2, title: "Loading thread" });
3738
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { icon: import_lucide_react12.Loader2, title: "Loading thread" });
3047
3739
  }
3048
3740
  if (error) {
3049
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load thread", description: error });
3741
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "Unable to load thread", description: error });
3050
3742
  }
3051
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
3052
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3743
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
3744
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3053
3745
  PageHeader,
3054
3746
  {
3055
3747
  title: thread?.name ?? threadId,
@@ -3058,7 +3750,7 @@ function ThreadInspector({
3058
3750
  { label: thread?.status ?? "unknown" },
3059
3751
  { label: `${messages.length}${pageInfo?.hasMoreBefore ? "+" : ""} messages`, variant: "secondary" }
3060
3752
  ],
3061
- actions: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3753
+ actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3062
3754
  Button,
3063
3755
  {
3064
3756
  onClick: () => context.navigate("threads"),
@@ -3070,14 +3762,14 @@ function ThreadInspector({
3070
3762
  )
3071
3763
  }
3072
3764
  ),
3073
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3765
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3074
3766
  InspectorPanel,
3075
3767
  {
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)(
3768
+ side: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(JsonPanel, { title: "Thread JSON", value: thread, minHeight: 420 }),
3769
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
3770
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between border-b px-4 py-2", children: [
3771
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "text-sm font-medium", children: "Timeline" }),
3772
+ pageInfo?.hasMoreBefore && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3081
3773
  Button,
3082
3774
  {
3083
3775
  disabled: isLoadingMore,
@@ -3086,51 +3778,51 @@ function ThreadInspector({
3086
3778
  type: "button",
3087
3779
  variant: "ghost",
3088
3780
  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" }),
3781
+ 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
3782
  "Load older"
3091
3783
  ]
3092
3784
  }
3093
3785
  )
3094
3786
  ] }),
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)) })
3787
+ 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
3788
  ] })
3097
3789
  }
3098
3790
  )
3099
3791
  ] });
3100
3792
  }
3101
3793
  function MessageRow({ message }) {
3102
- const [expanded, setExpanded] = import_react7.default.useState(false);
3794
+ const [expanded, setExpanded] = import_react8.default.useState(false);
3103
3795
  const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
3104
3796
  const hasReasoning = Boolean(message.reasoning);
3105
3797
  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: [
3798
+ 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: [
3799
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SenderIcon, { senderType: message.senderType }),
3800
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0 flex-1", children: [
3801
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
3802
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
3803
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: "outline", className: "text-[10px]", children: message.senderType }),
3804
+ message.targetId && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-[10px]", children: [
3113
3805
  "to ",
3114
3806
  message.targetId
3115
3807
  ] }),
3116
- message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-muted-foreground", children: formatDateTime2(message.createdAt) })
3808
+ message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-muted-foreground", children: formatDateTime3(message.createdAt) })
3117
3809
  ] }),
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)(
3810
+ message.content && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "mt-1 whitespace-pre-wrap break-words text-sm", children: message.content }),
3811
+ (hasToolCalls || hasReasoning || hasMetadata) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mt-2", children: [
3812
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3121
3813
  "button",
3122
3814
  {
3123
3815
  className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground",
3124
3816
  onClick: () => setExpanded((value) => !value),
3125
3817
  type: "button",
3126
3818
  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" }),
3819
+ hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Wrench, { className: "size-3" }),
3820
+ hasReasoning && !hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Cpu, { className: "size-3" }),
3129
3821
  "Details"
3130
3822
  ]
3131
3823
  }
3132
3824
  ),
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({
3825
+ 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
3826
  ...hasToolCalls ? { toolCalls: message.toolCalls } : {},
3135
3827
  ...hasReasoning ? { reasoning: message.reasoning } : {},
3136
3828
  ...hasMetadata ? { metadata: message.metadata } : {}
@@ -3143,16 +3835,16 @@ function SenderIcon({ senderType }) {
3143
3835
  const base = "flex size-7 shrink-0 items-center justify-center rounded-full";
3144
3836
  switch (senderType) {
3145
3837
  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" }) });
3838
+ 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
3839
  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" }) });
3840
+ 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
3841
  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" }) });
3842
+ 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
3843
  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" }) });
3844
+ 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
3845
  }
3154
3846
  }
3155
- function formatDateTime2(value) {
3847
+ function formatDateTime3(value) {
3156
3848
  if (!value) return "No activity";
3157
3849
  const date = new Date(value);
3158
3850
  if (Number.isNaN(date.getTime())) return value;
@@ -3165,17 +3857,17 @@ function formatDateTime2(value) {
3165
3857
  }
3166
3858
 
3167
3859
  // src/modules/usage/index.tsx
3168
- var import_react8 = __toESM(require("react"), 1);
3860
+ var import_react9 = __toESM(require("react"), 1);
3169
3861
  var import_recharts = require("recharts");
3170
- var import_lucide_react12 = require("lucide-react");
3862
+ var import_lucide_react13 = require("lucide-react");
3171
3863
 
3172
3864
  // src/components/ui/chart.tsx
3173
- var React12 = __toESM(require("react"), 1);
3865
+ var React13 = __toESM(require("react"), 1);
3174
3866
  var RechartsPrimitive = __toESM(require("recharts"), 1);
3175
- var import_jsx_runtime26 = require("react/jsx-runtime");
3176
- var ChartContext = React12.createContext(null);
3867
+ var import_jsx_runtime27 = require("react/jsx-runtime");
3868
+ var ChartContext = React13.createContext(null);
3177
3869
  function useChart() {
3178
- const context = React12.useContext(ChartContext);
3870
+ const context = React13.useContext(ChartContext);
3179
3871
  if (!context) {
3180
3872
  throw new Error("useChart must be used within a ChartContainer");
3181
3873
  }
@@ -3188,9 +3880,9 @@ function ChartContainer({
3188
3880
  children,
3189
3881
  ...props
3190
3882
  }) {
3191
- const uniqueId = React12.useId();
3883
+ const uniqueId = React13.useId();
3192
3884
  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)(
3885
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChartContext.Provider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3194
3886
  "div",
3195
3887
  {
3196
3888
  "data-chart": chartId,
@@ -3200,10 +3892,10 @@ function ChartContainer({
3200
3892
  ),
3201
3893
  ...props,
3202
3894
  children: [
3203
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("style", { children: Object.entries(config).map(([key, item]) => {
3895
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("style", { children: Object.entries(config).map(([key, item]) => {
3204
3896
  return `[data-chart=${chartId}] { --color-${key}: ${item.color}; }`;
3205
3897
  }).join("\n") }),
3206
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RechartsPrimitive.ResponsiveContainer, { children })
3898
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(RechartsPrimitive.ResponsiveContainer, { children })
3207
3899
  ]
3208
3900
  }
3209
3901
  ) });
@@ -3222,7 +3914,7 @@ function ChartTooltipContent({
3222
3914
  const value = typeof item.value === "number" ? item.value : Number(item.value ?? 0);
3223
3915
  return sum + (Number.isFinite(value) ? value : 0);
3224
3916
  }, 0);
3225
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3917
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3226
3918
  "div",
3227
3919
  {
3228
3920
  className: cn(
@@ -3230,28 +3922,28 @@ function ChartTooltipContent({
3230
3922
  className
3231
3923
  ),
3232
3924
  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 })
3925
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "mb-2 flex items-center justify-between gap-4 border-b pb-2", children: [
3926
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs font-medium text-muted-foreground", children: labelFormatter ? labelFormatter(label) : label }),
3927
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs font-semibold text-foreground", children: formatter ? formatter(total) : total })
3236
3928
  ] }),
3237
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
3929
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
3238
3930
  const key = String(item.dataKey ?? item.name ?? "");
3239
3931
  const itemConfig = config[key];
3240
3932
  const color = item.color ?? itemConfig?.color ?? "currentColor";
3241
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3933
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3242
3934
  "div",
3243
3935
  {
3244
3936
  className: "grid grid-cols-[0.6rem_1fr_auto] items-center gap-2",
3245
3937
  children: [
3246
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3938
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3247
3939
  "span",
3248
3940
  {
3249
3941
  className: "size-2 rounded-[2px]",
3250
3942
  style: { backgroundColor: color }
3251
3943
  }
3252
3944
  ),
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 })
3945
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "max-w-48 truncate text-muted-foreground", children: itemConfig?.label ?? item.name ?? key }),
3946
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-medium text-foreground", children: formatter ? formatter(item.value ?? 0) : item.value })
3255
3947
  ]
3256
3948
  },
3257
3949
  key
@@ -3267,11 +3959,11 @@ function ChartLegendContent({
3267
3959
  }) {
3268
3960
  const config = useChart();
3269
3961
  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) => {
3962
+ 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
3963
  const key = String(item.dataKey ?? item.value ?? "");
3272
3964
  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)(
3965
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2", children: [
3966
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3275
3967
  "span",
3276
3968
  {
3277
3969
  className: "size-2 rounded-[2px]",
@@ -3280,13 +3972,13 @@ function ChartLegendContent({
3280
3972
  }
3281
3973
  }
3282
3974
  ),
3283
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
3975
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
3284
3976
  ] }, key);
3285
3977
  }) });
3286
3978
  }
3287
3979
 
3288
3980
  // src/modules/usage/index.tsx
3289
- var import_jsx_runtime27 = require("react/jsx-runtime");
3981
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3290
3982
  var USAGE_DIMENSIONS = [
3291
3983
  "total",
3292
3984
  "input",
@@ -3314,12 +4006,12 @@ var STATUS_OPTIONS = [
3314
4006
  function usageModule() {
3315
4007
  return {
3316
4008
  group: "operate",
3317
- icon: import_lucide_react12.BarChart3,
4009
+ icon: import_lucide_react13.BarChart3,
3318
4010
  id: "usage",
3319
4011
  label: "Usage",
3320
4012
  navItems: [{
3321
4013
  group: "operate",
3322
- icon: import_lucide_react12.BarChart3,
4014
+ icon: import_lucide_react13.BarChart3,
3323
4015
  id: "usage",
3324
4016
  label: "Usage",
3325
4017
  order: 20,
@@ -3328,70 +4020,70 @@ function usageModule() {
3328
4020
  routes: [{
3329
4021
  id: "usage",
3330
4022
  title: "Usage",
3331
- render: (context) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(UsagePage, { context })
4023
+ render: (context) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UsagePage, { context })
3332
4024
  }]
3333
4025
  };
3334
4026
  }
3335
4027
  function UsagePage({ context }) {
3336
- const [period, setPeriod] = import_react8.default.useState(
4028
+ const [period, setPeriod] = import_react9.default.useState(
3337
4029
  "7d"
3338
4030
  );
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(
4031
+ const [interval, setInterval] = import_react9.default.useState("day");
4032
+ const [workload, setWorkload] = import_react9.default.useState("all");
4033
+ const [metricKind, setMetricKind] = import_react9.default.useState(
3342
4034
  "calls"
3343
4035
  );
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(
4036
+ const [dimension, setDimension] = import_react9.default.useState("total");
4037
+ const [groupBy, setGroupBy] = import_react9.default.useState("kind");
4038
+ const [attribution, setAttribution] = import_react9.default.useState(
3347
4039
  "initiatedBy"
3348
4040
  );
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(
4041
+ const [participantType, setParticipantType] = import_react9.default.useState("all");
4042
+ const [threadId, setThreadId] = import_react9.default.useState("");
4043
+ const [participantId, setParticipantId] = import_react9.default.useState("");
4044
+ const [provider, setProvider] = import_react9.default.useState("");
4045
+ const [model, setModel] = import_react9.default.useState("");
4046
+ const [resource, setResource] = import_react9.default.useState("");
4047
+ const [operation, setOperation] = import_react9.default.useState("");
4048
+ const [status, setStatus] = import_react9.default.useState(
3357
4049
  "all"
3358
4050
  );
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(
4051
+ const [customFrom, setCustomFrom] = import_react9.default.useState("");
4052
+ const [customTo, setCustomTo] = import_react9.default.useState("");
4053
+ const [usage, setUsage] = import_react9.default.useState(null);
4054
+ const [error, setError] = import_react9.default.useState(null);
4055
+ const [isLoading, setIsLoading] = import_react9.default.useState(false);
4056
+ const range = import_react9.default.useMemo(
3365
4057
  () => getUsageRange(period, customFrom, customTo),
3366
4058
  [customFrom, customTo, period]
3367
4059
  );
3368
- const metricOptions = import_react8.default.useMemo(
4060
+ const metricOptions = import_react9.default.useMemo(
3369
4061
  () => getUsageMetricOptions(workload),
3370
4062
  [workload]
3371
4063
  );
3372
- const groupOptions = import_react8.default.useMemo(
4064
+ const groupOptions = import_react9.default.useMemo(
3373
4065
  () => getUsageGroupOptions(workload),
3374
4066
  [workload]
3375
4067
  );
3376
4068
  const showLlmFields = workload === "llm";
3377
4069
  const showResourceFields = workload !== "llm";
3378
4070
  const showDimension = metricKind === "tokens" || metricKind === "cost" && workload === "llm";
3379
- import_react8.default.useEffect(() => {
4071
+ import_react9.default.useEffect(() => {
3380
4072
  if (!metricOptions.includes(metricKind)) {
3381
4073
  setMetricKind(metricOptions[0]);
3382
4074
  }
3383
4075
  }, [metricKind, metricOptions]);
3384
- import_react8.default.useEffect(() => {
4076
+ import_react9.default.useEffect(() => {
3385
4077
  if (!groupOptions.includes(groupBy)) {
3386
4078
  setGroupBy(groupOptions[0]);
3387
4079
  }
3388
4080
  }, [groupBy, groupOptions]);
3389
- import_react8.default.useEffect(() => {
4081
+ import_react9.default.useEffect(() => {
3390
4082
  if (!showDimension && dimension !== "total") {
3391
4083
  setDimension("total");
3392
4084
  }
3393
4085
  }, [dimension, showDimension]);
3394
- import_react8.default.useEffect(() => {
4086
+ import_react9.default.useEffect(() => {
3395
4087
  let active = true;
3396
4088
  setIsLoading(true);
3397
4089
  setError(null);
@@ -3449,16 +4141,16 @@ function UsagePage({ context }) {
3449
4141
  ]);
3450
4142
  const points = usage?.points ?? [];
3451
4143
  const totals = usage?.totals ?? EMPTY_USAGE_TOTALS;
3452
- const chartState = import_react8.default.useMemo(
4144
+ const chartState = import_react9.default.useMemo(
3453
4145
  () => buildUsageChartState(points, metricKind, dimension, interval),
3454
4146
  [dimension, interval, metricKind, points]
3455
4147
  );
3456
- const rows = import_react8.default.useMemo(
4148
+ const rows = import_react9.default.useMemo(
3457
4149
  () => aggregateUsageRows(points, metricKind, dimension),
3458
4150
  [dimension, metricKind, points]
3459
4151
  );
3460
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "space-y-4", children: [
3461
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4152
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "space-y-4", children: [
4153
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3462
4154
  PageHeader,
3463
4155
  {
3464
4156
  title: "Usage",
@@ -3471,8 +4163,8 @@ function UsagePage({ context }) {
3471
4163
  ]
3472
4164
  }
3473
4165
  ),
3474
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(FilterBar, { children: [
3475
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4166
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(FilterBar, { children: [
4167
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3476
4168
  UsageSelect,
3477
4169
  {
3478
4170
  label: "Period",
@@ -3481,7 +4173,7 @@ function UsagePage({ context }) {
3481
4173
  value: period
3482
4174
  }
3483
4175
  ),
3484
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4176
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3485
4177
  UsageSelect,
3486
4178
  {
3487
4179
  label: "Bucket",
@@ -3490,7 +4182,7 @@ function UsagePage({ context }) {
3490
4182
  value: interval
3491
4183
  }
3492
4184
  ),
3493
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4185
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3494
4186
  UsageSelect,
3495
4187
  {
3496
4188
  label: "Workload",
@@ -3500,7 +4192,7 @@ function UsagePage({ context }) {
3500
4192
  formatOption: getUsageKindLabel
3501
4193
  }
3502
4194
  ),
3503
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4195
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3504
4196
  UsageSelect,
3505
4197
  {
3506
4198
  label: "Measure",
@@ -3510,7 +4202,7 @@ function UsagePage({ context }) {
3510
4202
  formatOption: getUsageMetricLabel
3511
4203
  }
3512
4204
  ),
3513
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4205
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3514
4206
  UsageSelect,
3515
4207
  {
3516
4208
  label: "Group",
@@ -3520,7 +4212,7 @@ function UsagePage({ context }) {
3520
4212
  formatOption: getUsageGroupLabel
3521
4213
  }
3522
4214
  ),
3523
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4215
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3524
4216
  UsageSelect,
3525
4217
  {
3526
4218
  label: "Actor",
@@ -3530,7 +4222,7 @@ function UsagePage({ context }) {
3530
4222
  formatOption: getUsageAttributionLabel
3531
4223
  }
3532
4224
  ),
3533
- showDimension && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4225
+ showDimension && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3534
4226
  UsageSelect,
3535
4227
  {
3536
4228
  label: "Dimension",
@@ -3541,9 +4233,9 @@ function UsagePage({ context }) {
3541
4233
  }
3542
4234
  )
3543
4235
  ] }),
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)(
4236
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(FilterBar, { children: [
4237
+ period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4238
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3547
4239
  Input,
3548
4240
  {
3549
4241
  className: "h-8 w-[190px]",
@@ -3552,7 +4244,7 @@ function UsagePage({ context }) {
3552
4244
  value: customFrom
3553
4245
  }
3554
4246
  ),
3555
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4247
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3556
4248
  Input,
3557
4249
  {
3558
4250
  className: "h-8 w-[190px]",
@@ -3562,7 +4254,7 @@ function UsagePage({ context }) {
3562
4254
  }
3563
4255
  )
3564
4256
  ] }),
3565
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4257
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3566
4258
  UsageSelect,
3567
4259
  {
3568
4260
  label: "Actor type",
@@ -3571,7 +4263,7 @@ function UsagePage({ context }) {
3571
4263
  value: participantType
3572
4264
  }
3573
4265
  ),
3574
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4266
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3575
4267
  UsageSelect,
3576
4268
  {
3577
4269
  label: "Status",
@@ -3580,7 +4272,7 @@ function UsagePage({ context }) {
3580
4272
  value: status
3581
4273
  }
3582
4274
  ),
3583
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4275
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3584
4276
  Input,
3585
4277
  {
3586
4278
  className: "h-8 w-[170px]",
@@ -3589,7 +4281,7 @@ function UsagePage({ context }) {
3589
4281
  value: threadId
3590
4282
  }
3591
4283
  ),
3592
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4284
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3593
4285
  Input,
3594
4286
  {
3595
4287
  className: "h-8 w-[170px]",
@@ -3598,8 +4290,8 @@ function UsagePage({ context }) {
3598
4290
  value: participantId
3599
4291
  }
3600
4292
  ),
3601
- showResourceFields && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3602
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4293
+ showResourceFields && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4294
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3603
4295
  Input,
3604
4296
  {
3605
4297
  className: "h-8 w-[170px]",
@@ -3608,7 +4300,7 @@ function UsagePage({ context }) {
3608
4300
  value: resource
3609
4301
  }
3610
4302
  ),
3611
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4303
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3612
4304
  Input,
3613
4305
  {
3614
4306
  className: "h-8 w-[150px]",
@@ -3618,8 +4310,8 @@ function UsagePage({ context }) {
3618
4310
  }
3619
4311
  )
3620
4312
  ] }),
3621
- showLlmFields && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3622
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4313
+ showLlmFields && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4314
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3623
4315
  Input,
3624
4316
  {
3625
4317
  className: "h-8 w-[140px]",
@@ -3628,7 +4320,7 @@ function UsagePage({ context }) {
3628
4320
  value: provider
3629
4321
  }
3630
4322
  ),
3631
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4323
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3632
4324
  Input,
3633
4325
  {
3634
4326
  className: "h-8 w-[140px]",
@@ -3639,58 +4331,58 @@ function UsagePage({ context }) {
3639
4331
  )
3640
4332
  ] })
3641
4333
  ] }),
3642
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4334
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3643
4335
  MetricStrip,
3644
4336
  {
3645
4337
  items: [
3646
4338
  {
3647
4339
  detail: `${formatMetricValue(totals.unpricedCalls, "unpriced")} unpriced`,
3648
- icon: import_lucide_react12.DollarSign,
4340
+ icon: import_lucide_react13.DollarSign,
3649
4341
  label: "Spend",
3650
4342
  value: formatMetricValue(totals.totalCostUsd, "cost")
3651
4343
  },
3652
4344
  {
3653
4345
  detail: `${formatMetricValue(totals.failedCalls, "failures")} failed`,
3654
- icon: import_lucide_react12.Activity,
4346
+ icon: import_lucide_react13.Activity,
3655
4347
  label: "Calls",
3656
4348
  value: formatMetricValue(totals.totalCalls, "calls")
3657
4349
  },
3658
4350
  {
3659
4351
  detail: "Tool and resource runtime",
3660
- icon: import_lucide_react12.Clock,
4352
+ icon: import_lucide_react13.Clock,
3661
4353
  label: "Duration",
3662
4354
  value: formatMetricValue(totals.totalDurationMs, "duration")
3663
4355
  },
3664
4356
  {
3665
4357
  detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
3666
- icon: import_lucide_react12.Sparkles,
4358
+ icon: import_lucide_react13.Sparkles,
3667
4359
  label: "Tokens",
3668
4360
  value: formatMetricValue(totals.totalTokens, "tokens")
3669
4361
  },
3670
4362
  {
3671
4363
  detail: "Custom metering",
3672
- icon: import_lucide_react12.Coins,
4364
+ icon: import_lucide_react13.Coins,
3673
4365
  label: "Credits",
3674
4366
  value: formatMetricValue(totals.totalCredits, "credits")
3675
4367
  },
3676
4368
  {
3677
4369
  detail: "Failed or aborted work",
3678
- icon: import_lucide_react12.AlertTriangle,
4370
+ icon: import_lucide_react13.AlertTriangle,
3679
4371
  label: "Failures",
3680
4372
  value: formatMetricValue(totals.failedCalls, "failures")
3681
4373
  }
3682
4374
  ]
3683
4375
  }
3684
4376
  ),
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)(
4377
+ 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
4378
  EmptyState,
3687
4379
  {
3688
4380
  title: "No usage",
3689
4381
  description: "Metered LLM, tool, and resource records will appear here after work is captured in the usage ledger."
3690
4382
  }
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)(
4383
+ ) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4384
+ /* @__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 }) }) }),
4385
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3694
4386
  UsageRowsTable,
3695
4387
  {
3696
4388
  dimension,
@@ -3710,19 +4402,19 @@ function UsageSelect({
3710
4402
  options,
3711
4403
  value
3712
4404
  }) {
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)) })
4405
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Select, { value, onValueChange, children: [
4406
+ /* @__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, {}) }),
4407
+ /* @__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
4408
  ] });
3717
4409
  }
3718
4410
  function UsageChart({
3719
4411
  chartState,
3720
4412
  metricKind
3721
4413
  }) {
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)(
4414
+ 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: [
4415
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.CartesianGrid, { vertical: false }),
4416
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.XAxis, { dataKey: "label", tickLine: false, axisLine: false, tickMargin: 10 }),
4417
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3726
4418
  import_recharts.YAxis,
3727
4419
  {
3728
4420
  axisLine: false,
@@ -3731,10 +4423,10 @@ function UsageChart({
3731
4423
  width: 64
3732
4424
  }
3733
4425
  ),
3734
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4426
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3735
4427
  import_recharts.Tooltip,
3736
4428
  {
3737
- content: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4429
+ content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3738
4430
  ChartTooltipContent,
3739
4431
  {
3740
4432
  formatter: (value) => formatMetricValue(Number(value), metricKind),
@@ -3744,8 +4436,8 @@ function UsageChart({
3744
4436
  cursor: false
3745
4437
  }
3746
4438
  ),
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)(
4439
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.Legend, { content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChartLegendContent, { className: "justify-center pt-3" }) }),
4440
+ chartState.series.map((series) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3749
4441
  import_recharts.Bar,
3750
4442
  {
3751
4443
  dataKey: series.id,
@@ -3766,7 +4458,7 @@ function UsageRowsTable({
3766
4458
  }) {
3767
4459
  const totalValue = getUsageTotalValue(totals, metricKind, dimension);
3768
4460
  const valueHeader = (metricKind === "tokens" || metricKind === "cost") && dimension !== "total" ? `${getUsageDimensionLabel(dimension)} ${getUsageMetricLabel(metricKind)}` : getUsageMetricLabel(metricKind);
3769
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4461
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3770
4462
  ResourceTable,
3771
4463
  {
3772
4464
  rows: rows.slice(0, 80),
@@ -3775,9 +4467,9 @@ function UsageRowsTable({
3775
4467
  {
3776
4468
  id: "group",
3777
4469
  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 })
4470
+ render: (row) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "min-w-0", children: [
4471
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-80 truncate font-medium", children: row.groupLabel }),
4472
+ 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
4473
  ] })
3782
4474
  },
3783
4475
  {
@@ -3906,6 +4598,7 @@ function defaultCopilotzModules() {
3906
4598
  usageModule(),
3907
4599
  eventsModule(),
3908
4600
  threadsModule(),
4601
+ brainModule(),
3909
4602
  agentsModule(),
3910
4603
  participantsModule(),
3911
4604
  collectionsModule()
@@ -3985,17 +4678,17 @@ function firstAccessibleRoute(modules, permissions) {
3985
4678
  }
3986
4679
 
3987
4680
  // 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);
4681
+ var import_react10 = require("react");
4682
+ var import_jsx_runtime29 = require("react/jsx-runtime");
4683
+ var AdminContext = (0, import_react10.createContext)(null);
3991
4684
  function AdminProvider({
3992
4685
  children,
3993
4686
  value
3994
4687
  }) {
3995
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(AdminContext.Provider, { value, children });
4688
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AdminContext.Provider, { value, children });
3996
4689
  }
3997
4690
  function useAdmin() {
3998
- const context = (0, import_react9.useContext)(AdminContext);
4691
+ const context = (0, import_react10.useContext)(AdminContext);
3999
4692
  if (!context) {
4000
4693
  throw new Error("useAdmin must be used inside CopilotzAdmin");
4001
4694
  }
@@ -4003,7 +4696,7 @@ function useAdmin() {
4003
4696
  }
4004
4697
 
4005
4698
  // src/core/CopilotzAdmin.tsx
4006
- var import_jsx_runtime29 = require("react/jsx-runtime");
4699
+ var import_jsx_runtime30 = require("react/jsx-runtime");
4007
4700
  var DEFAULT_BRANDING = {
4008
4701
  title: "Copilotz Admin",
4009
4702
  subtitle: "Operate and configure Copilotz projects",
@@ -4039,11 +4732,11 @@ function CopilotzAdmin({
4039
4732
  permissions = {},
4040
4733
  scope: scopeProp
4041
4734
  }) {
4042
- const modules = (0, import_react10.useMemo)(
4735
+ const modules = (0, import_react11.useMemo)(
4043
4736
  () => modulesProp ?? defaultCopilotzModules(),
4044
4737
  [modulesProp]
4045
4738
  );
4046
- const adminClient = (0, import_react10.useMemo)(
4739
+ const adminClient = (0, import_react11.useMemo)(
4047
4740
  () => client ?? createAdminClient({
4048
4741
  baseUrl: clientConfig?.baseUrl ?? config?.baseUrl,
4049
4742
  paths: clientConfig?.paths,
@@ -4051,7 +4744,7 @@ function CopilotzAdmin({
4051
4744
  }),
4052
4745
  [client, clientConfig, config]
4053
4746
  );
4054
- const branding = (0, import_react10.useMemo)(
4747
+ const branding = (0, import_react11.useMemo)(
4055
4748
  () => ({
4056
4749
  ...DEFAULT_BRANDING,
4057
4750
  ...config?.branding ?? {},
@@ -4059,30 +4752,30 @@ function CopilotzAdmin({
4059
4752
  }),
4060
4753
  [brandingProp, config?.branding]
4061
4754
  );
4062
- const [namespace, setNamespaceState] = (0, import_react10.useState)(
4755
+ const [namespace, setNamespaceState] = (0, import_react11.useState)(
4063
4756
  scopeProp?.namespace ?? config?.namespace ?? ""
4064
4757
  );
4065
- const scope = (0, import_react10.useMemo)(() => ({
4758
+ const scope = (0, import_react11.useMemo)(() => ({
4066
4759
  ...scopeProp ?? {},
4067
4760
  namespace
4068
4761
  }), [namespace, scopeProp]);
4069
- const routes = (0, import_react10.useMemo)(
4762
+ const routes = (0, import_react11.useMemo)(
4070
4763
  () => collectAdminRoutes(modules, permissions),
4071
4764
  [modules, permissions]
4072
4765
  );
4073
- const navItems = (0, import_react10.useMemo)(
4766
+ const navItems = (0, import_react11.useMemo)(
4074
4767
  () => collectAdminNavItems(modules, permissions),
4075
4768
  [modules, permissions]
4076
4769
  );
4077
- const collectionEditors = (0, import_react10.useMemo)(
4770
+ const collectionEditors = (0, import_react11.useMemo)(
4078
4771
  () => collectCollectionEditors(modules),
4079
4772
  [modules]
4080
4773
  );
4081
4774
  const initialRouteId = routeFromLegacyPage(config?.defaultPage) ?? firstAccessibleRoute(modules, permissions);
4082
- const [route, setRoute] = (0, import_react10.useState)({
4775
+ const [route, setRoute] = (0, import_react11.useState)({
4083
4776
  routeId: initialRouteId
4084
4777
  });
4085
- const [refreshKey, setRefreshKey] = (0, import_react10.useState)(0);
4778
+ const [refreshKey, setRefreshKey] = (0, import_react11.useState)(0);
4086
4779
  const activeRoute = routes.get(route.routeId) ?? routes.get(firstAccessibleRoute(modules, permissions));
4087
4780
  const navigate = (routeId, params) => {
4088
4781
  const next = { routeId, params };
@@ -4103,7 +4796,7 @@ function CopilotzAdmin({
4103
4796
  scope,
4104
4797
  setNamespace: setNamespaceState
4105
4798
  };
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)(
4799
+ 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
4800
  "div",
4108
4801
  {
4109
4802
  className: cn(
@@ -4111,7 +4804,7 @@ function CopilotzAdmin({
4111
4804
  className
4112
4805
  ),
4113
4806
  children: [
4114
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4807
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4115
4808
  AdminShellSidebar,
4116
4809
  {
4117
4810
  branding,
@@ -4123,8 +4816,8 @@ function CopilotzAdmin({
4123
4816
  scopeOptions: scope.availableNamespaces
4124
4817
  }
4125
4818
  ),
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)(
4819
+ /* @__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: [
4820
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4128
4821
  AdminShellHeader,
4129
4822
  {
4130
4823
  brandingActions: branding.actions,
@@ -4133,7 +4826,7 @@ function CopilotzAdmin({
4133
4826
  title: activeRoute?.title ?? "Admin"
4134
4827
  }
4135
4828
  ),
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." }) }) })
4829
+ /* @__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
4830
  ] }) })
4138
4831
  ]
4139
4832
  }
@@ -4152,57 +4845,57 @@ function AdminShellSidebar({
4152
4845
  group,
4153
4846
  items: navItems.filter((item) => (item.group ?? "extensions") === group)
4154
4847
  })).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 })
4848
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Sidebar, { collapsible: "icon", children: [
4849
+ /* @__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: [
4850
+ /* @__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" }) }),
4851
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "min-w-0 group-data-[collapsible=icon]:hidden", children: [
4852
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "truncate text-sm font-semibold", children: branding.title }),
4853
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: branding.subtitle })
4161
4854
  ] })
4162
4855
  ] }) }),
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)(
4856
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarContent, { children: grouped.map(({ group, items }, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react11.default.Fragment, { children: [
4857
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarSeparator, {}),
4858
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SidebarGroup, { children: [
4859
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: ADMIN_GROUP_LABELS[group] }),
4860
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarMenu, { children: items.map((item) => {
4861
+ const Icon2 = item.icon ?? import_lucide_react14.LayoutDashboard;
4862
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4170
4863
  SidebarMenuButton,
4171
4864
  {
4172
4865
  isActive: route.routeId === item.routeId,
4173
4866
  onClick: () => onNavigate(item.routeId),
4174
4867
  tooltip: item.label,
4175
4868
  children: [
4176
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon2, {}),
4177
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: item.label })
4869
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon2, {}),
4870
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: item.label })
4178
4871
  ]
4179
4872
  }
4180
4873
  ) }, item.id);
4181
4874
  }) }) })
4182
4875
  ] })
4183
4876
  ] }, 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)(
4877
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SidebarFooter, { children: [
4878
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "group-data-[collapsible=icon]:hidden", children: [
4879
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "mb-1 block px-2 text-xs font-medium text-muted-foreground", children: "Namespace" }),
4880
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4188
4881
  Select,
4189
4882
  {
4190
4883
  value: namespace || "__all__",
4191
4884
  onValueChange: (value) => onNamespaceChange(value === "__all__" ? "" : value),
4192
4885
  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 })
4886
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectValue, { placeholder: "All namespaces" }) }),
4887
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SelectContent, { children: [
4888
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: "__all__", children: "All namespaces" }),
4889
+ scopeOptions?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: option.id, children: option.label ?? option.id }, option.id)),
4890
+ namespace && !scopeOptions?.some((option) => option.id === namespace) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: namespace, children: namespace })
4198
4891
  ] })
4199
4892
  ]
4200
4893
  }
4201
4894
  )
4202
4895
  ] }),
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" }) })
4896
+ /* @__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
4897
  ] }),
4205
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SidebarRail, {})
4898
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarRail, {})
4206
4899
  ] });
4207
4900
  }
4208
4901
  function AdminShellHeader({
@@ -4211,17 +4904,17 @@ function AdminShellHeader({
4211
4904
  onRefresh,
4212
4905
  title
4213
4906
  }) {
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" })
4907
+ 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: [
4908
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
4909
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
4910
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { children: "Toggle sidebar" })
4218
4911
  ] }),
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 })
4912
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
4913
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Database, { className: "size-4 text-muted-foreground" }),
4914
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", { className: "truncate text-sm font-medium", children: title })
4222
4915
  ] }),
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)(
4916
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
4917
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4225
4918
  Button,
4226
4919
  {
4227
4920
  className: "size-8",
@@ -4230,10 +4923,10 @@ function AdminShellHeader({
4230
4923
  size: "icon",
4231
4924
  type: "button",
4232
4925
  variant: "ghost",
4233
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.RefreshCw, { className: "size-4" })
4926
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.RefreshCw, { className: "size-4" })
4234
4927
  }
4235
4928
  ) }),
4236
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { children: "Refresh" })
4929
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { children: "Refresh" })
4237
4930
  ] }),
4238
4931
  brandingActions
4239
4932
  ] });
@@ -4260,27 +4953,27 @@ function mergeAdminConfig(baseConfig = defaultAdminConfig, userConfig) {
4260
4953
  }
4261
4954
 
4262
4955
  // src/useCopilotzAdmin.ts
4263
- var import_react11 = require("react");
4956
+ var import_react12 = require("react");
4264
4957
  function useCopilotzAdmin(options = {}) {
4265
- const [range, setRange] = (0, import_react11.useState)(options.range ?? "7d");
4266
- const [interval, setInterval] = (0, import_react11.useState)(
4958
+ const [range, setRange] = (0, import_react12.useState)(options.range ?? "7d");
4959
+ const [interval, setInterval] = (0, import_react12.useState)(
4267
4960
  options.interval ?? "day"
4268
4961
  );
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)(
4962
+ const [overview, setOverview] = (0, import_react12.useState)(null);
4963
+ const [activity, setActivity] = (0, import_react12.useState)([]);
4964
+ const [threads, setThreads] = (0, import_react12.useState)([]);
4965
+ const [participants, setParticipants] = (0, import_react12.useState)([]);
4966
+ const [agents, setAgents] = (0, import_react12.useState)([]);
4967
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
4968
+ const [error, setError] = (0, import_react12.useState)(null);
4969
+ const client = (0, import_react12.useMemo)(
4277
4970
  () => createAdminClient({
4278
4971
  baseUrl: options.baseUrl,
4279
4972
  getRequestHeaders: options.getRequestHeaders
4280
4973
  }),
4281
4974
  [options.baseUrl, options.getRequestHeaders]
4282
4975
  );
4283
- const fetchAll = (0, import_react11.useCallback)(async () => {
4976
+ const fetchAll = (0, import_react12.useCallback)(async () => {
4284
4977
  setIsLoading(true);
4285
4978
  setError(null);
4286
4979
  try {
@@ -4326,7 +5019,7 @@ function useCopilotzAdmin(options = {}) {
4326
5019
  options.threadSearch,
4327
5020
  range
4328
5021
  ]);
4329
- (0, import_react11.useEffect)(() => {
5022
+ (0, import_react12.useEffect)(() => {
4330
5023
  void fetchAll();
4331
5024
  }, [fetchAll]);
4332
5025
  return {
@@ -4364,6 +5057,7 @@ function useCopilotzAdmin(options = {}) {
4364
5057
  addUsageTotals,
4365
5058
  agentsModule,
4366
5059
  aggregateUsageRows,
5060
+ brainModule,
4367
5061
  buildUsageChartState,
4368
5062
  canAccessAdminPermission,
4369
5063
  collectAdminNavItems,