@copilotz/admin 0.9.37 → 0.9.39

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