@copilotz/admin 0.9.39 → 0.9.41

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.js CHANGED
@@ -234,6 +234,14 @@ function createAdminClient(options = {}) {
234
234
  kind: filters.kind === "all" ? void 0 : filters.kind,
235
235
  status: filters.status === "all" ? void 0 : filters.status,
236
236
  search: filters.search,
237
+ searchMode: filters.searchMode,
238
+ focusNodeId: filters.focusNodeId,
239
+ includeRelated: filters.includeRelated ? "true" : void 0,
240
+ includeSimilar: filters.includeSimilar ? "true" : void 0,
241
+ similarLimit: filters.similarLimit ? String(filters.similarLimit) : void 0,
242
+ minSimilarity: typeof filters.minSimilarity === "number" ? String(filters.minSimilarity) : void 0,
243
+ relationDepth: filters.relationDepth ? String(filters.relationDepth) : void 0,
244
+ relationTypes: filters.relationTypes?.join(","),
237
245
  limit: String(filters.limit ?? 160),
238
246
  offset: filters.offset ? String(filters.offset) : void 0
239
247
  }),
@@ -1948,18 +1956,165 @@ function AgentDetailPage({ context }) {
1948
1956
  // src/modules/brain/index.tsx
1949
1957
  import React7 from "react";
1950
1958
  import {
1959
+ BookOpen,
1951
1960
  Brain as Brain2,
1952
- CircleDot,
1953
- Network,
1961
+ GitBranch,
1954
1962
  RefreshCw,
1955
1963
  Search as Search2,
1956
- Sparkles
1964
+ Sparkles,
1965
+ UsersRound
1957
1966
  } from "lucide-react";
1967
+
1968
+ // src/modules/brain/view-model.ts
1969
+ var ENTITY_FOCUS_RELATION_TYPES = [
1970
+ "mentions",
1971
+ "related_to",
1972
+ "supports",
1973
+ "depends_on",
1974
+ "contradicts",
1975
+ "supersedes"
1976
+ ];
1977
+ var BRAIN_VIEW_LABELS = {
1978
+ entities: "Entities",
1979
+ knowledge: "Knowledge",
1980
+ work: "Work",
1981
+ map: "Map",
1982
+ all: "All nodes"
1983
+ };
1984
+ var BRAIN_RELATION_GROUP_DEFINITIONS = [
1985
+ {
1986
+ id: "decisions",
1987
+ label: "Decisions",
1988
+ description: "Durable choices connected to this entity.",
1989
+ kinds: ["decision"]
1990
+ },
1991
+ {
1992
+ id: "facts",
1993
+ label: "Facts",
1994
+ description: "Known statements and observations.",
1995
+ kinds: ["fact"]
1996
+ },
1997
+ {
1998
+ id: "tasks",
1999
+ label: "Tasks",
2000
+ description: "Actions, next steps, and execution work.",
2001
+ kinds: ["task", "next_action"]
2002
+ },
2003
+ {
2004
+ id: "preferences",
2005
+ label: "Preferences",
2006
+ description: "Remembered user, org, or agent preferences.",
2007
+ kinds: ["preference"]
2008
+ },
2009
+ {
2010
+ id: "constraints",
2011
+ label: "Constraints",
2012
+ description: "Limits, rules, and requirements.",
2013
+ kinds: ["constraint"]
2014
+ },
2015
+ {
2016
+ id: "risks",
2017
+ label: "Risks",
2018
+ description: "Known risks or possible failures.",
2019
+ kinds: ["risk"]
2020
+ },
2021
+ {
2022
+ id: "openQuestions",
2023
+ label: "Open questions",
2024
+ description: "Questions that still need resolution.",
2025
+ kinds: ["open_question"]
2026
+ },
2027
+ {
2028
+ id: "currentState",
2029
+ label: "Current state",
2030
+ description: "Shorter-term context, challenges, and active state.",
2031
+ kinds: ["current_state", "challenge"]
2032
+ },
2033
+ {
2034
+ id: "entities",
2035
+ label: "Other entities",
2036
+ description: "Neighboring people, systems, projects, or concepts.",
2037
+ kinds: ["entity"]
2038
+ },
2039
+ {
2040
+ id: "other",
2041
+ label: "Other",
2042
+ description: "Related nodes that do not fit a standard Brain kind yet.",
2043
+ kinds: []
2044
+ }
2045
+ ];
2046
+ var GROUP_BY_KIND = new Map(
2047
+ BRAIN_RELATION_GROUP_DEFINITIONS.flatMap(
2048
+ (group) => group.kinds.map((kind) => [kind, group.id])
2049
+ )
2050
+ );
2051
+ function getBrainViewBaseFilters(view) {
2052
+ if (view === "entities") {
2053
+ return { kind: "entity", layer: "knowledge" };
2054
+ }
2055
+ if (view === "knowledge") {
2056
+ return { kind: "all", layer: "knowledge" };
2057
+ }
2058
+ if (view === "work") {
2059
+ return { kind: "all", layer: "working" };
2060
+ }
2061
+ return { kind: "all", layer: "all" };
2062
+ }
2063
+ function isEntityBrainView(view) {
2064
+ return view === "entities";
2065
+ }
2066
+ function groupBrainRelationsByKind(related) {
2067
+ const groups = BRAIN_RELATION_GROUP_DEFINITIONS.map((definition) => ({
2068
+ id: definition.id,
2069
+ label: definition.label,
2070
+ description: definition.description,
2071
+ items: []
2072
+ }));
2073
+ const byId = new Map(groups.map((group) => [group.id, group]));
2074
+ for (const item of related) {
2075
+ const groupId = GROUP_BY_KIND.get(item.node.kind) ?? "other";
2076
+ byId.get(groupId)?.items.push(item);
2077
+ }
2078
+ return groups.filter((group) => group.items.length > 0);
2079
+ }
2080
+ function getKnowledgeRelationGroups(related) {
2081
+ const knowledgeGroupIds = [
2082
+ "decisions",
2083
+ "facts",
2084
+ "preferences",
2085
+ "constraints"
2086
+ ];
2087
+ return groupBrainRelationsByKind(related).filter(
2088
+ (group) => knowledgeGroupIds.includes(group.id)
2089
+ );
2090
+ }
2091
+ function getWorkRelationGroups(related) {
2092
+ const workGroupIds = [
2093
+ "tasks",
2094
+ "risks",
2095
+ "openQuestions",
2096
+ "currentState"
2097
+ ];
2098
+ return groupBrainRelationsByKind(related).filter(
2099
+ (group) => workGroupIds.includes(group.id)
2100
+ );
2101
+ }
2102
+
2103
+ // src/modules/brain/index.tsx
1958
2104
  import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
1959
2105
  var BRAIN_LAYERS = ["all", "knowledge", "working"];
2106
+ var BRAIN_SEARCH_MODES = ["hybrid", "semantic", "keyword"];
1960
2107
  var BRAIN_STATUSES = ["active", "all", "superseded", "archived"];
2108
+ var BRAIN_VIEWS = [
2109
+ "entities",
2110
+ "knowledge",
2111
+ "work",
2112
+ "map",
2113
+ "all"
2114
+ ];
1961
2115
  var BRAIN_KINDS = [
1962
2116
  "all",
2117
+ "entity",
1963
2118
  "decision",
1964
2119
  "fact",
1965
2120
  "preference",
@@ -1993,7 +2148,11 @@ function brainModule() {
1993
2148
  };
1994
2149
  }
1995
2150
  function BrainPage({ context }) {
2151
+ const [view, setView] = React7.useState("entities");
1996
2152
  const [search, setSearch] = React7.useState("");
2153
+ const [searchMode, setSearchMode] = React7.useState(
2154
+ "hybrid"
2155
+ );
1997
2156
  const [layer, setLayer] = React7.useState("all");
1998
2157
  const [status, setStatus] = React7.useState(
1999
2158
  "active"
@@ -2006,25 +2165,44 @@ function BrainPage({ context }) {
2006
2165
  const [selectedNode, setSelectedNode] = React7.useState(
2007
2166
  null
2008
2167
  );
2168
+ const [focusNodeId, setFocusNodeId] = React7.useState(null);
2009
2169
  const [loading, setLoading] = React7.useState(false);
2010
2170
  const [error, setError] = React7.useState(null);
2011
- const loadBrain = React7.useCallback(async () => {
2171
+ const loadBrain = React7.useCallback(async (focusOverride) => {
2012
2172
  setLoading(true);
2013
2173
  setError(null);
2174
+ const effectiveFocusNodeId = focusOverride === void 0 ? focusNodeId : focusOverride;
2175
+ const viewFilters = getBrainViewBaseFilters(view);
2176
+ const effectiveLayer = view === "map" || view === "all" ? layer : viewFilters.layer;
2177
+ const effectiveKind = view === "entities" ? "entity" : kind;
2014
2178
  try {
2015
2179
  const next = await context.client.getBrain({
2016
2180
  namespace: context.scope.namespace || void 0,
2017
2181
  search: search.trim() || void 0,
2018
- layer,
2182
+ searchMode,
2183
+ layer: effectiveLayer,
2019
2184
  status,
2020
- kind,
2185
+ kind: effectiveKind,
2021
2186
  agentId: agentId.trim() || void 0,
2187
+ focusNodeId: effectiveFocusNodeId || void 0,
2188
+ includeRelated: Boolean(effectiveFocusNodeId),
2189
+ includeSimilar: Boolean(effectiveFocusNodeId),
2190
+ similarLimit: 24,
2191
+ minSimilarity: 0.2,
2192
+ relationTypes: effectiveFocusNodeId ? [...ENTITY_FOCUS_RELATION_TYPES] : void 0,
2022
2193
  limit: 180
2023
2194
  });
2024
2195
  setResponse(next);
2025
- setSelectedNode(
2026
- (current) => current && next.nodes.some((node) => node.id === current.id) ? current : next.nodes[0] ?? null
2027
- );
2196
+ setSelectedNode((current) => {
2197
+ const currentInResults = current ? next.nodes.find((node) => node.id === current.id) ?? current : null;
2198
+ if (effectiveFocusNodeId) {
2199
+ return next.nodes.find((node) => node.id === effectiveFocusNodeId) ?? currentInResults;
2200
+ }
2201
+ if (view === "entities") {
2202
+ return current && next.nodes.some((node) => node.id === current.id) ? currentInResults : null;
2203
+ }
2204
+ return current && next.nodes.some((node) => node.id === current.id) ? currentInResults : next.nodes[0] ?? null;
2205
+ });
2028
2206
  } catch (cause) {
2029
2207
  setError(cause instanceof Error ? cause.message : "Failed to load brain");
2030
2208
  setResponse(null);
@@ -2036,17 +2214,38 @@ function BrainPage({ context }) {
2036
2214
  agentId,
2037
2215
  context.client,
2038
2216
  context.scope.namespace,
2217
+ focusNodeId,
2039
2218
  kind,
2040
2219
  layer,
2041
2220
  search,
2042
- status
2221
+ searchMode,
2222
+ status,
2223
+ view
2043
2224
  ]);
2044
2225
  React7.useEffect(() => {
2045
2226
  void loadBrain();
2046
- }, [context.refreshKey, context.scope.namespace, loadBrain]);
2227
+ }, [context.refreshKey, context.scope.namespace, focusNodeId, loadBrain]);
2047
2228
  const data = response ?? emptyBrainResponse();
2229
+ const matches = data.matches ?? {};
2230
+ const related = data.related ?? [];
2231
+ const similar = data.similar ?? [];
2232
+ const entityCount = data.stats.byKind.entity ?? data.nodes.filter((node) => node.kind === "entity").length;
2048
2233
  const knowledgeCount = data.stats.byLayer.knowledge ?? 0;
2049
2234
  const workingCount = data.stats.byLayer.working ?? 0;
2235
+ const selectNode = React7.useCallback((node) => {
2236
+ setSelectedNode(node);
2237
+ setFocusNodeId(node.id);
2238
+ }, []);
2239
+ const selectView = React7.useCallback((nextView) => {
2240
+ setView(nextView);
2241
+ setFocusNodeId(null);
2242
+ setSelectedNode(null);
2243
+ }, []);
2244
+ const runSearch = React7.useCallback(() => {
2245
+ setFocusNodeId(null);
2246
+ setSelectedNode(null);
2247
+ void loadBrain(null);
2248
+ }, [loadBrain]);
2050
2249
  return /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
2051
2250
  /* @__PURE__ */ jsx21(
2052
2251
  PageHeader,
@@ -2080,16 +2279,16 @@ function BrainPage({ context }) {
2080
2279
  {
2081
2280
  items: [
2082
2281
  {
2083
- label: "Brain nodes",
2084
- value: data.stats.total,
2085
- detail: `${data.pageInfo.returned} shown`,
2086
- icon: Brain2
2282
+ label: "Entities",
2283
+ value: entityCount,
2284
+ detail: view === "entities" ? `${data.pageInfo.returned} shown` : "Stable anchors",
2285
+ icon: UsersRound
2087
2286
  },
2088
2287
  {
2089
2288
  label: "Knowledge",
2090
2289
  value: knowledgeCount,
2091
2290
  detail: "Durable nodes",
2092
- icon: CircleDot
2291
+ icon: BookOpen
2093
2292
  },
2094
2293
  {
2095
2294
  label: "Working",
@@ -2098,14 +2297,27 @@ function BrainPage({ context }) {
2098
2297
  icon: Sparkles
2099
2298
  },
2100
2299
  {
2101
- label: "Clusters",
2102
- value: data.clusters.length,
2103
- detail: "Layer and kind",
2104
- icon: Network
2300
+ label: selectedNode ? "Focus links" : "Brain nodes",
2301
+ value: selectedNode ? related.length + similar.length : data.stats.total,
2302
+ detail: selectedNode ? "Related and similar" : `${data.pageInfo.returned} shown`,
2303
+ icon: selectedNode ? GitBranch : Brain2
2105
2304
  }
2106
2305
  ]
2107
2306
  }
2108
2307
  ),
2308
+ /* @__PURE__ */ jsx21("div", { className: "inline-flex max-w-full overflow-hidden rounded-md border bg-background", children: BRAIN_VIEWS.map((item) => /* @__PURE__ */ jsx21(
2309
+ "button",
2310
+ {
2311
+ className: cn(
2312
+ "min-w-0 px-3 py-2 text-xs transition-colors sm:px-4",
2313
+ view === item ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
2314
+ ),
2315
+ onClick: () => selectView(item),
2316
+ type: "button",
2317
+ children: BRAIN_VIEW_LABELS[item]
2318
+ },
2319
+ item
2320
+ )) }),
2109
2321
  /* @__PURE__ */ jsxs13(
2110
2322
  FilterBar,
2111
2323
  {
@@ -2113,7 +2325,7 @@ function BrainPage({ context }) {
2113
2325
  Button,
2114
2326
  {
2115
2327
  disabled: loading,
2116
- onClick: () => void loadBrain(),
2328
+ onClick: runSearch,
2117
2329
  size: "sm",
2118
2330
  type: "button",
2119
2331
  children: [
@@ -2123,20 +2335,40 @@ function BrainPage({ context }) {
2123
2335
  }
2124
2336
  ),
2125
2337
  onSearchChange: setSearch,
2126
- searchPlaceholder: "Search brain",
2338
+ searchPlaceholder: view === "entities" ? "Search entities" : "Search brain",
2127
2339
  searchValue: search,
2128
2340
  children: [
2129
- /* @__PURE__ */ jsxs13(
2341
+ /* @__PURE__ */ jsx21("div", { className: "inline-flex h-8 overflow-hidden rounded-md border bg-background", children: BRAIN_SEARCH_MODES.map((mode) => /* @__PURE__ */ jsx21(
2342
+ "button",
2343
+ {
2344
+ className: cn(
2345
+ "px-3 text-xs transition-colors",
2346
+ searchMode === mode ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
2347
+ ),
2348
+ onClick: () => setSearchMode(mode),
2349
+ type: "button",
2350
+ children: formatLabel(mode)
2351
+ },
2352
+ mode
2353
+ )) }),
2354
+ view === "map" || view === "all" ? /* @__PURE__ */ jsxs13(
2130
2355
  Select,
2131
2356
  {
2132
2357
  value: layer,
2133
2358
  onValueChange: (value) => setLayer(value),
2134
2359
  children: [
2135
- /* @__PURE__ */ jsx21(SelectTrigger, { className: "h-8 w-[140px] text-xs", "aria-label": "Layer", children: /* @__PURE__ */ jsx21(SelectValue, {}) }),
2360
+ /* @__PURE__ */ jsx21(
2361
+ SelectTrigger,
2362
+ {
2363
+ className: "h-8 w-[140px] text-xs",
2364
+ "aria-label": "Layer",
2365
+ children: /* @__PURE__ */ jsx21(SelectValue, {})
2366
+ }
2367
+ ),
2136
2368
  /* @__PURE__ */ jsx21(SelectContent, { children: BRAIN_LAYERS.map((option) => /* @__PURE__ */ jsx21(SelectItem, { value: option, children: option === "all" ? "All layers" : formatLabel(option) }, option)) })
2137
2369
  ]
2138
2370
  }
2139
- ),
2371
+ ) : null,
2140
2372
  /* @__PURE__ */ jsxs13(
2141
2373
  Select,
2142
2374
  {
@@ -2148,24 +2380,31 @@ function BrainPage({ context }) {
2148
2380
  ]
2149
2381
  }
2150
2382
  ),
2151
- /* @__PURE__ */ jsxs13(
2383
+ view !== "entities" ? /* @__PURE__ */ jsxs13(
2152
2384
  Select,
2153
2385
  {
2154
2386
  value: kind,
2155
2387
  onValueChange: (value) => setKind(value),
2156
2388
  children: [
2157
- /* @__PURE__ */ jsx21(SelectTrigger, { className: "h-8 w-[170px] text-xs", "aria-label": "Kind", children: /* @__PURE__ */ jsx21(SelectValue, {}) }),
2389
+ /* @__PURE__ */ jsx21(
2390
+ SelectTrigger,
2391
+ {
2392
+ className: "h-8 w-[170px] text-xs",
2393
+ "aria-label": "Kind",
2394
+ children: /* @__PURE__ */ jsx21(SelectValue, {})
2395
+ }
2396
+ ),
2158
2397
  /* @__PURE__ */ jsx21(SelectContent, { children: BRAIN_KINDS.map((option) => /* @__PURE__ */ jsx21(SelectItem, { value: option, children: option === "all" ? "All kinds" : formatLabel(option) }, option)) })
2159
2398
  ]
2160
2399
  }
2161
- ),
2400
+ ) : /* @__PURE__ */ jsx21(Badge, { className: "h-8 px-3", variant: "secondary", children: "Entity index" }),
2162
2401
  /* @__PURE__ */ jsx21(
2163
2402
  Input,
2164
2403
  {
2165
2404
  className: "h-8 w-[190px]",
2166
2405
  onChange: (event) => setAgentId(event.target.value),
2167
2406
  onKeyDown: (event) => {
2168
- if (event.key === "Enter") void loadBrain();
2407
+ if (event.key === "Enter") runSearch();
2169
2408
  },
2170
2409
  placeholder: "Agent ID",
2171
2410
  value: agentId
@@ -2174,10 +2413,23 @@ function BrainPage({ context }) {
2174
2413
  ]
2175
2414
  }
2176
2415
  ),
2416
+ data.semantic?.requested && data.semantic.error ? /* @__PURE__ */ jsxs13("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: [
2417
+ "Semantic search unavailable: ",
2418
+ data.semantic.error
2419
+ ] }) : null,
2177
2420
  error ? /* @__PURE__ */ jsx21(EmptyState, { title: "Unable to load brain", description: error }) : /* @__PURE__ */ jsx21(
2178
2421
  InspectorPanel,
2179
2422
  {
2180
- side: selectedNode ? /* @__PURE__ */ jsx21(BrainNodeInspector, { node: selectedNode }) : /* @__PURE__ */ jsx21(
2423
+ side: selectedNode ? /* @__PURE__ */ jsx21(
2424
+ BrainNodeInspector,
2425
+ {
2426
+ match: matches[selectedNode.id],
2427
+ node: selectedNode,
2428
+ onSelectNode: selectNode,
2429
+ related,
2430
+ similar
2431
+ }
2432
+ ) : /* @__PURE__ */ jsx21(
2181
2433
  EmptyState,
2182
2434
  {
2183
2435
  icon: Brain2,
@@ -2185,70 +2437,299 @@ function BrainPage({ context }) {
2185
2437
  description: "Select a node from the map or table."
2186
2438
  }
2187
2439
  ),
2188
- children: /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
2440
+ children: /* @__PURE__ */ jsx21("div", { className: "space-y-4", children: /* @__PURE__ */ jsx21(
2441
+ BrainPrimaryContent,
2442
+ {
2443
+ data,
2444
+ loading,
2445
+ matches,
2446
+ onSelectNode: selectNode,
2447
+ related,
2448
+ selectedNode,
2449
+ similar,
2450
+ view
2451
+ }
2452
+ ) })
2453
+ }
2454
+ )
2455
+ ] });
2456
+ }
2457
+ function BrainPrimaryContent({
2458
+ data,
2459
+ loading,
2460
+ matches,
2461
+ onSelectNode,
2462
+ related,
2463
+ selectedNode,
2464
+ similar,
2465
+ view
2466
+ }) {
2467
+ if (view === "entities") {
2468
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
2469
+ /* @__PURE__ */ jsx21(
2470
+ EntityEgoGraph,
2471
+ {
2472
+ entity: selectedNode?.kind === "entity" ? selectedNode : null,
2473
+ loading,
2474
+ onSelectNode,
2475
+ related,
2476
+ similar
2477
+ }
2478
+ ),
2479
+ /* @__PURE__ */ jsx21(
2480
+ BrainNodeTable,
2481
+ {
2482
+ emptyDescription: "Entity nodes will appear here once the Brain has named people, tenants, projects, products, tools, policies, or concepts.",
2483
+ emptyTitle: loading ? "Loading entities" : "No entities yet",
2484
+ loading,
2485
+ matches,
2486
+ nodes: data.nodes,
2487
+ onSelectNode,
2488
+ variant: "entities"
2489
+ }
2490
+ )
2491
+ ] });
2492
+ }
2493
+ if (view === "map") {
2494
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
2495
+ /* @__PURE__ */ jsx21(
2496
+ BrainMap,
2497
+ {
2498
+ clusters: data.clusters,
2499
+ edges: data.edges,
2500
+ loading,
2501
+ nodes: data.nodes,
2502
+ onSelectNode,
2503
+ similar,
2504
+ selectedNodeId: selectedNode?.id ?? null
2505
+ }
2506
+ ),
2507
+ /* @__PURE__ */ jsx21(
2508
+ BrainNodeTable,
2509
+ {
2510
+ emptyDescription: "Knowledge and working-state nodes will appear here.",
2511
+ emptyTitle: loading ? "Loading brain" : "No brain nodes",
2512
+ loading,
2513
+ matches,
2514
+ nodes: data.nodes,
2515
+ onSelectNode
2516
+ }
2517
+ )
2518
+ ] });
2519
+ }
2520
+ return /* @__PURE__ */ jsx21(
2521
+ BrainNodeTable,
2522
+ {
2523
+ emptyDescription: view === "work" ? "Working-state nodes will appear here when the Brain captures current challenges, tasks, risks, and open questions." : view === "knowledge" ? "Durable facts, decisions, preferences, constraints, and entities will appear here." : "Knowledge and working-state nodes will appear here.",
2524
+ emptyTitle: loading ? `Loading ${BRAIN_VIEW_LABELS[view].toLowerCase()}` : `No ${BRAIN_VIEW_LABELS[view].toLowerCase()}`,
2525
+ loading,
2526
+ matches,
2527
+ nodes: data.nodes,
2528
+ onSelectNode
2529
+ }
2530
+ );
2531
+ }
2532
+ function BrainNodeTable({
2533
+ emptyDescription,
2534
+ emptyTitle,
2535
+ loading,
2536
+ matches,
2537
+ nodes,
2538
+ onSelectNode,
2539
+ variant = "default"
2540
+ }) {
2541
+ return /* @__PURE__ */ jsx21(
2542
+ ResourceTable,
2543
+ {
2544
+ rows: nodes,
2545
+ getRowKey: (row) => row.id,
2546
+ onRowClick: onSelectNode,
2547
+ empty: /* @__PURE__ */ jsx21(
2548
+ EmptyState,
2549
+ {
2550
+ icon: variant === "entities" ? UsersRound : Brain2,
2551
+ title: emptyTitle,
2552
+ description: loading ? "Fetching Brain nodes for the active namespace." : emptyDescription
2553
+ }
2554
+ ),
2555
+ columns: [
2556
+ {
2557
+ id: "node",
2558
+ header: variant === "entities" ? "Entity" : "Node",
2559
+ className: "max-w-[420px]",
2560
+ render: (row) => /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
2561
+ /* @__PURE__ */ jsx21("div", { className: "truncate font-medium", children: row.name }),
2562
+ /* @__PURE__ */ jsx21("div", { className: "truncate text-xs text-muted-foreground", children: row.content || "-" }),
2563
+ /* @__PURE__ */ jsx21(MatchBadges, { match: matches[row.id] })
2564
+ ] })
2565
+ },
2566
+ ...variant === "entities" ? [{
2567
+ id: "updated",
2568
+ header: "Updated",
2569
+ className: "whitespace-nowrap text-xs",
2570
+ render: (row) => formatDateTime(row.updatedAt)
2571
+ }] : [{
2572
+ id: "layer",
2573
+ header: "Layer",
2574
+ render: (row) => /* @__PURE__ */ jsx21(LayerBadge, { layer: row.layer })
2575
+ }, {
2576
+ id: "kind",
2577
+ header: "Kind",
2578
+ render: (row) => formatLabel(row.kind)
2579
+ }],
2580
+ {
2581
+ id: "status",
2582
+ header: "Status",
2583
+ render: (row) => /* @__PURE__ */ jsx21(StatusBadge, { status: row.status })
2584
+ },
2585
+ {
2586
+ id: "agent",
2587
+ header: "Agent",
2588
+ className: "max-w-[160px] truncate font-mono text-xs",
2589
+ render: (row) => row.agentId ?? "-"
2590
+ }
2591
+ ]
2592
+ }
2593
+ );
2594
+ }
2595
+ function EntityEgoGraph({
2596
+ entity,
2597
+ loading,
2598
+ onSelectNode,
2599
+ related,
2600
+ similar
2601
+ }) {
2602
+ if (!entity) {
2603
+ return /* @__PURE__ */ jsx21("div", { className: "flex min-h-[300px] items-center justify-center rounded-lg border bg-background", children: /* @__PURE__ */ jsx21(
2604
+ EmptyState,
2605
+ {
2606
+ icon: UsersRound,
2607
+ title: loading ? "Loading entity workspace" : "Select an entity",
2608
+ description: loading ? "Fetching entity nodes for the active namespace." : "Choose an entity to see its explicit relations and semantic neighbors."
2609
+ }
2610
+ ) });
2611
+ }
2612
+ const relatedItems = related.slice(0, 18);
2613
+ const similarItems = similar.slice(0, 10);
2614
+ const orbitCount = relatedItems.length + similarItems.length;
2615
+ const center = { x: 500, y: 260 };
2616
+ const radius = orbitCount > 12 ? 190 : 165;
2617
+ const orbitNodes = [
2618
+ ...relatedItems.map((item, index) => ({
2619
+ id: item.edge.id,
2620
+ index,
2621
+ node: item.node,
2622
+ tone: "relation",
2623
+ label: formatLabel(item.edge.type)
2624
+ })),
2625
+ ...similarItems.map((item, index) => ({
2626
+ id: `similar-${item.node.id}`,
2627
+ index: index + relatedItems.length,
2628
+ node: item.node,
2629
+ tone: "similar",
2630
+ label: formatSimilarityScore(item.similarity)
2631
+ }))
2632
+ ].map((item) => {
2633
+ const angle = orbitCount > 0 ? Math.PI * 2 * item.index / orbitCount - Math.PI / 2 : 0;
2634
+ return {
2635
+ ...item,
2636
+ x: center.x + Math.cos(angle) * radius,
2637
+ y: center.y + Math.sin(angle) * radius
2638
+ };
2639
+ });
2640
+ return /* @__PURE__ */ jsx21("div", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsxs13("div", { className: "grid gap-0 lg:grid-cols-[minmax(0,1.5fr)_320px]", children: [
2641
+ /* @__PURE__ */ jsxs13(
2642
+ "svg",
2643
+ {
2644
+ className: "block h-[380px] w-full bg-muted/20",
2645
+ role: "img",
2646
+ viewBox: "0 0 1000 520",
2647
+ children: [
2648
+ /* @__PURE__ */ jsx21("rect", { fill: "transparent", height: "520", width: "1000" }),
2649
+ orbitNodes.map((item) => /* @__PURE__ */ jsx21(
2650
+ "line",
2651
+ {
2652
+ stroke: item.tone === "similar" ? "#0ea5e9" : "#64748b",
2653
+ strokeDasharray: item.tone === "similar" ? "6 7" : void 0,
2654
+ strokeOpacity: item.tone === "similar" ? "0.48" : "0.38",
2655
+ strokeWidth: item.tone === "similar" ? "1.8" : "2.2",
2656
+ x1: center.x,
2657
+ x2: item.x,
2658
+ y1: center.y,
2659
+ y2: item.y
2660
+ },
2661
+ `line-${item.id}`
2662
+ )),
2189
2663
  /* @__PURE__ */ jsx21(
2190
- BrainMap,
2664
+ "circle",
2191
2665
  {
2192
- clusters: data.clusters,
2193
- edges: data.edges,
2194
- loading,
2195
- nodes: data.nodes,
2196
- onSelectNode: setSelectedNode,
2197
- selectedNodeId: selectedNode?.id ?? null
2666
+ cx: center.x,
2667
+ cy: center.y,
2668
+ fill: nodeColor(entity),
2669
+ r: "22",
2670
+ stroke: "#0f172a",
2671
+ strokeWidth: "3",
2672
+ children: /* @__PURE__ */ jsx21("title", { children: entity.name })
2198
2673
  }
2199
2674
  ),
2200
- /* @__PURE__ */ jsx21(
2201
- ResourceTable,
2675
+ orbitNodes.map((item) => /* @__PURE__ */ jsx21(
2676
+ "g",
2202
2677
  {
2203
- rows: data.nodes,
2204
- getRowKey: (row) => row.id,
2205
- onRowClick: setSelectedNode,
2206
- empty: /* @__PURE__ */ jsx21(
2207
- EmptyState,
2208
- {
2209
- icon: Brain2,
2210
- title: loading ? "Loading brain" : "No brain nodes",
2211
- description: loading ? "Fetching brain nodes for the active namespace." : "Knowledge and working-state nodes will appear here."
2212
- }
2213
- ),
2214
- columns: [
2215
- {
2216
- id: "node",
2217
- header: "Node",
2218
- className: "max-w-[360px]",
2219
- render: (row) => /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
2220
- /* @__PURE__ */ jsx21("div", { className: "truncate font-medium", children: row.name }),
2221
- /* @__PURE__ */ jsx21("div", { className: "truncate text-xs text-muted-foreground", children: row.content || "-" })
2222
- ] })
2223
- },
2224
- {
2225
- id: "layer",
2226
- header: "Layer",
2227
- render: (row) => /* @__PURE__ */ jsx21(LayerBadge, { layer: row.layer })
2228
- },
2229
- {
2230
- id: "kind",
2231
- header: "Kind",
2232
- render: (row) => formatLabel(row.kind)
2233
- },
2234
- {
2235
- id: "status",
2236
- header: "Status",
2237
- render: (row) => /* @__PURE__ */ jsx21(StatusBadge, { status: row.status })
2238
- },
2678
+ className: "cursor-pointer",
2679
+ onClick: () => onSelectNode(item.node),
2680
+ children: /* @__PURE__ */ jsx21(
2681
+ "circle",
2239
2682
  {
2240
- id: "agent",
2241
- header: "Agent",
2242
- className: "max-w-[160px] truncate font-mono text-xs",
2243
- render: (row) => row.agentId ?? "-"
2683
+ cx: item.x,
2684
+ cy: item.y,
2685
+ fill: nodeColor(item.node),
2686
+ r: item.tone === "similar" ? 9 : 11,
2687
+ stroke: item.tone === "similar" ? "#0ea5e9" : "#ffffff",
2688
+ strokeWidth: "2",
2689
+ children: /* @__PURE__ */ jsx21("title", { children: `${item.node.name} \xB7 ${formatLabel(item.node.kind)} \xB7 ${item.label}` })
2244
2690
  }
2245
- ]
2246
- }
2247
- )
2248
- ] })
2691
+ )
2692
+ },
2693
+ item.id
2694
+ ))
2695
+ ]
2249
2696
  }
2250
- )
2251
- ] });
2697
+ ),
2698
+ /* @__PURE__ */ jsxs13("div", { className: "border-t p-4 lg:border-l lg:border-t-0", children: [
2699
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2", children: [
2700
+ /* @__PURE__ */ jsx21(LayerBadge, { layer: entity.layer }),
2701
+ /* @__PURE__ */ jsx21(StatusBadge, { status: entity.status }),
2702
+ /* @__PURE__ */ jsx21(Badge, { variant: "outline", children: "Entity" })
2703
+ ] }),
2704
+ /* @__PURE__ */ jsx21("h3", { className: "mt-3 truncate text-base font-semibold", children: entity.name }),
2705
+ /* @__PURE__ */ jsx21("p", { className: "mt-2 line-clamp-4 text-sm leading-6 text-muted-foreground", children: entity.content || "-" }),
2706
+ /* @__PURE__ */ jsxs13("div", { className: "mt-4 grid grid-cols-2 gap-2 text-xs", children: [
2707
+ /* @__PURE__ */ jsxs13("div", { className: "rounded-md border bg-muted/20 p-3", children: [
2708
+ /* @__PURE__ */ jsx21("div", { className: "text-muted-foreground", children: "Explicit" }),
2709
+ /* @__PURE__ */ jsx21("div", { className: "mt-1 text-lg font-semibold", children: related.length })
2710
+ ] }),
2711
+ /* @__PURE__ */ jsxs13("div", { className: "rounded-md border bg-muted/20 p-3", children: [
2712
+ /* @__PURE__ */ jsx21("div", { className: "text-muted-foreground", children: "Semantic" }),
2713
+ /* @__PURE__ */ jsx21("div", { className: "mt-1 text-lg font-semibold", children: similar.length })
2714
+ ] })
2715
+ ] }),
2716
+ /* @__PURE__ */ jsxs13("div", { className: "mt-4 space-y-2", children: [
2717
+ /* @__PURE__ */ jsx21("div", { className: "text-xs font-medium text-muted-foreground", children: "Knowledge orbit" }),
2718
+ groupBrainRelationsByKind(related).slice(0, 5).map((group) => /* @__PURE__ */ jsxs13(
2719
+ "div",
2720
+ {
2721
+ className: "flex items-center justify-between gap-3 text-xs",
2722
+ children: [
2723
+ /* @__PURE__ */ jsx21("span", { className: "truncate", children: group.label }),
2724
+ /* @__PURE__ */ jsx21(Badge, { variant: "secondary", children: group.items.length })
2725
+ ]
2726
+ },
2727
+ group.id
2728
+ )),
2729
+ related.length === 0 && similar.length === 0 ? /* @__PURE__ */ jsx21("p", { className: "text-xs leading-5 text-muted-foreground", children: "Select an entity with relations or embeddings to see its neighborhood." }) : null
2730
+ ] })
2731
+ ] })
2732
+ ] }) });
2252
2733
  }
2253
2734
  function BrainMap({
2254
2735
  clusters,
@@ -2256,6 +2737,7 @@ function BrainMap({
2256
2737
  loading,
2257
2738
  nodes,
2258
2739
  onSelectNode,
2740
+ similar,
2259
2741
  selectedNodeId
2260
2742
  }) {
2261
2743
  const nodeById = React7.useMemo(
@@ -2308,12 +2790,15 @@ function BrainMap({
2308
2790
  const source = nodeById.get(edge.sourceNodeId);
2309
2791
  const target = nodeById.get(edge.targetNodeId);
2310
2792
  if (!source || !target) return null;
2793
+ const isSelectedEdge = Boolean(
2794
+ selectedNodeId && (edge.sourceNodeId === selectedNodeId || edge.targetNodeId === selectedNodeId)
2795
+ );
2311
2796
  return /* @__PURE__ */ jsx21(
2312
2797
  "line",
2313
2798
  {
2314
2799
  stroke: edge.type === "contradicts" ? "#dc2626" : "#64748b",
2315
- strokeOpacity: "0.32",
2316
- strokeWidth: edge.type === "supports" ? 2 : 1.3,
2800
+ strokeOpacity: isSelectedEdge ? "0.75" : "0.32",
2801
+ strokeWidth: isSelectedEdge ? 2.6 : edge.type === "supports" ? 2 : 1.3,
2317
2802
  x1: source.x * 1e3,
2318
2803
  x2: target.x * 1e3,
2319
2804
  y1: source.y * 600,
@@ -2322,6 +2807,25 @@ function BrainMap({
2322
2807
  edge.id
2323
2808
  );
2324
2809
  }),
2810
+ selectedNodeId ? similar.map((item) => {
2811
+ const source = nodeById.get(selectedNodeId);
2812
+ const target = nodeById.get(item.node.id);
2813
+ if (!source || !target) return null;
2814
+ return /* @__PURE__ */ jsx21(
2815
+ "line",
2816
+ {
2817
+ stroke: "#0ea5e9",
2818
+ strokeDasharray: "5 6",
2819
+ strokeOpacity: "0.42",
2820
+ strokeWidth: "1.8",
2821
+ x1: source.x * 1e3,
2822
+ x2: target.x * 1e3,
2823
+ y1: source.y * 600,
2824
+ y2: target.y * 600
2825
+ },
2826
+ `similar-${item.node.id}`
2827
+ );
2828
+ }) : null,
2325
2829
  nodes.map((node) => {
2326
2830
  const isSelected = node.id === selectedNodeId;
2327
2831
  return /* @__PURE__ */ jsx21(
@@ -2349,7 +2853,19 @@ function BrainMap({
2349
2853
  }
2350
2854
  ) });
2351
2855
  }
2352
- function BrainNodeInspector({ node }) {
2856
+ function BrainNodeInspector({
2857
+ match,
2858
+ node,
2859
+ onSelectNode,
2860
+ related,
2861
+ similar
2862
+ }) {
2863
+ const [tab, setTab] = React7.useState("overview");
2864
+ const isEntity = node.kind === "entity";
2865
+ const tabs = isEntity ? ["overview", "knowledge", "work", "relations", "similar", "evidence", "json"] : ["overview", "relations", "similar", "evidence", "json"];
2866
+ React7.useEffect(() => {
2867
+ setTab("overview");
2868
+ }, [node.id]);
2353
2869
  return /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
2354
2870
  /* @__PURE__ */ jsxs13("div", { className: "rounded-lg border bg-background p-4", children: [
2355
2871
  /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2", children: [
@@ -2359,24 +2875,161 @@ function BrainNodeInspector({ node }) {
2359
2875
  ] }),
2360
2876
  /* @__PURE__ */ jsx21("h3", { className: "mt-3 text-base font-semibold", children: node.name }),
2361
2877
  /* @__PURE__ */ jsx21("p", { className: "mt-2 text-sm leading-6 text-muted-foreground", children: node.content || "-" }),
2362
- /* @__PURE__ */ jsxs13("dl", { className: "mt-4 grid gap-2 text-xs", children: [
2363
- /* @__PURE__ */ jsx21(InspectorRow, { label: "Agent", value: node.agentId }),
2364
- /* @__PURE__ */ jsx21(InspectorRow, { label: "Thread", value: node.threadId }),
2365
- /* @__PURE__ */ jsx21(InspectorRow, { label: "Memory space", value: node.memorySpaceId }),
2366
- /* @__PURE__ */ jsx21(InspectorRow, { label: "Checkpoint", value: node.checkpointId }),
2367
- /* @__PURE__ */ jsx21(InspectorRow, { label: "Source field", value: node.sourceField }),
2368
- /* @__PURE__ */ jsx21(
2369
- InspectorRow,
2370
- {
2371
- label: "Updated",
2372
- value: formatDateTime(node.updatedAt)
2373
- }
2374
- )
2375
- ] })
2878
+ /* @__PURE__ */ jsx21(MatchBadges, { match })
2376
2879
  ] }),
2377
- /* @__PURE__ */ jsx21(JsonPanel, { title: "Node JSON", value: node, minHeight: 300 })
2880
+ /* @__PURE__ */ jsx21("div", { className: "inline-flex w-full overflow-hidden rounded-md border bg-background", children: tabs.map((item) => /* @__PURE__ */ jsx21(
2881
+ "button",
2882
+ {
2883
+ className: cn(
2884
+ "min-w-0 flex-1 px-2 py-2 text-xs transition-colors",
2885
+ tab === item ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted/60"
2886
+ ),
2887
+ onClick: () => setTab(item),
2888
+ type: "button",
2889
+ children: formatLabel(item)
2890
+ },
2891
+ item
2892
+ )) }),
2893
+ tab === "overview" ? /* @__PURE__ */ jsx21(BrainOverview, { node }) : null,
2894
+ tab === "knowledge" ? /* @__PURE__ */ jsx21(
2895
+ RelationGroupsPanel,
2896
+ {
2897
+ emptyDescription: "Durable decisions, facts, preferences, and constraints related to this entity will appear here.",
2898
+ emptyTitle: "No durable knowledge",
2899
+ groups: getKnowledgeRelationGroups(related),
2900
+ onSelectNode
2901
+ }
2902
+ ) : null,
2903
+ tab === "work" ? /* @__PURE__ */ jsx21(
2904
+ RelationGroupsPanel,
2905
+ {
2906
+ emptyDescription: "Tasks, risks, open questions, and current-state nodes related to this entity will appear here.",
2907
+ emptyTitle: "No current work",
2908
+ groups: getWorkRelationGroups(related),
2909
+ onSelectNode
2910
+ }
2911
+ ) : null,
2912
+ tab === "relations" ? /* @__PURE__ */ jsx21(
2913
+ RelationGroupsPanel,
2914
+ {
2915
+ emptyDescription: "Explicit relation edges will appear here when this node is connected to other concepts.",
2916
+ emptyTitle: "No explicit relations",
2917
+ groups: groupBrainRelationsByKind(related),
2918
+ onSelectNode
2919
+ }
2920
+ ) : null,
2921
+ tab === "similar" ? /* @__PURE__ */ jsx21(SimilarPanel, { onSelectNode, similar }) : null,
2922
+ tab === "evidence" ? /* @__PURE__ */ jsx21(EvidencePanel, { node }) : null,
2923
+ tab === "json" ? /* @__PURE__ */ jsx21(JsonPanel, { title: "Node JSON", value: node, minHeight: 300 }) : null
2378
2924
  ] });
2379
2925
  }
2926
+ function BrainOverview({ node }) {
2927
+ return /* @__PURE__ */ jsx21("div", { className: "rounded-lg border bg-background p-4", children: /* @__PURE__ */ jsxs13("dl", { className: "grid gap-2 text-xs", children: [
2928
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Agent", value: node.agentId }),
2929
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Thread", value: node.threadId }),
2930
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Memory space", value: node.memorySpaceId }),
2931
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Checkpoint", value: node.checkpointId }),
2932
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Source field", value: node.sourceField }),
2933
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Confidence", value: formatNullableNumber(node.confidence) }),
2934
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Updated", value: formatDateTime(node.updatedAt) })
2935
+ ] }) });
2936
+ }
2937
+ function RelationGroupsPanel({
2938
+ emptyDescription,
2939
+ emptyTitle,
2940
+ groups,
2941
+ onSelectNode
2942
+ }) {
2943
+ if (groups.length === 0) {
2944
+ return /* @__PURE__ */ jsx21(
2945
+ EmptyState,
2946
+ {
2947
+ icon: GitBranch,
2948
+ title: emptyTitle,
2949
+ description: emptyDescription
2950
+ }
2951
+ );
2952
+ }
2953
+ return /* @__PURE__ */ jsx21("div", { className: "space-y-3", children: groups.map((group) => /* @__PURE__ */ jsxs13("section", { className: "rounded-lg border bg-background", children: [
2954
+ /* @__PURE__ */ jsx21("div", { className: "border-b px-3 py-2", children: /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between gap-3", children: [
2955
+ /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
2956
+ /* @__PURE__ */ jsx21("h4", { className: "truncate text-sm font-medium", children: group.label }),
2957
+ /* @__PURE__ */ jsx21("p", { className: "mt-0.5 line-clamp-2 text-xs text-muted-foreground", children: group.description })
2958
+ ] }),
2959
+ /* @__PURE__ */ jsx21(Badge, { variant: "secondary", children: group.items.length })
2960
+ ] }) }),
2961
+ /* @__PURE__ */ jsx21("div", { className: "divide-y", children: group.items.map((item) => /* @__PURE__ */ jsxs13(
2962
+ "button",
2963
+ {
2964
+ className: "w-full p-3 text-left transition-colors hover:bg-muted/40",
2965
+ onClick: () => onSelectNode(item.node),
2966
+ type: "button",
2967
+ children: [
2968
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2", children: [
2969
+ /* @__PURE__ */ jsx21(Badge, { variant: "outline", children: formatLabel(item.edge.type) }),
2970
+ /* @__PURE__ */ jsx21(Badge, { variant: "secondary", children: item.direction === "out" ? "Outgoing" : "Incoming" }),
2971
+ /* @__PURE__ */ jsx21(LayerBadge, { layer: item.node.layer })
2972
+ ] }),
2973
+ /* @__PURE__ */ jsx21("div", { className: "mt-2 text-sm font-medium", children: item.node.name }),
2974
+ /* @__PURE__ */ jsx21("p", { className: "mt-1 line-clamp-3 text-xs leading-5 text-muted-foreground", children: item.node.content || "-" })
2975
+ ]
2976
+ },
2977
+ item.edge.id
2978
+ )) })
2979
+ ] }, group.id)) });
2980
+ }
2981
+ function SimilarPanel({
2982
+ onSelectNode,
2983
+ similar
2984
+ }) {
2985
+ if (similar.length === 0) {
2986
+ return /* @__PURE__ */ jsx21(
2987
+ EmptyState,
2988
+ {
2989
+ icon: Sparkles,
2990
+ title: "No semantic neighbors",
2991
+ description: "Similar nodes appear here when the selected node has an embedding."
2992
+ }
2993
+ );
2994
+ }
2995
+ return /* @__PURE__ */ jsx21("div", { className: "space-y-2", children: similar.map((item) => /* @__PURE__ */ jsxs13(
2996
+ "button",
2997
+ {
2998
+ className: "w-full rounded-lg border bg-background p-3 text-left transition-colors hover:bg-muted/40",
2999
+ onClick: () => onSelectNode(item.node),
3000
+ type: "button",
3001
+ children: [
3002
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2", children: [
3003
+ /* @__PURE__ */ jsx21(Badge, { variant: "secondary", children: formatSimilarityScore(item.similarity) }),
3004
+ /* @__PURE__ */ jsx21(LayerBadge, { layer: item.node.layer }),
3005
+ /* @__PURE__ */ jsx21(Badge, { variant: "outline", children: formatLabel(item.node.kind) })
3006
+ ] }),
3007
+ /* @__PURE__ */ jsx21("div", { className: "mt-2 text-sm font-medium", children: item.node.name }),
3008
+ /* @__PURE__ */ jsx21("p", { className: "mt-1 line-clamp-3 text-xs leading-5 text-muted-foreground", children: item.node.content || "-" })
3009
+ ]
3010
+ },
3011
+ item.node.id
3012
+ )) });
3013
+ }
3014
+ function EvidencePanel({ node }) {
3015
+ const sourceMessageIds = Array.isArray(node.sourceMessageIds) ? node.sourceMessageIds : [];
3016
+ return /* @__PURE__ */ jsxs13("div", { className: "rounded-lg border bg-background p-4", children: [
3017
+ /* @__PURE__ */ jsxs13("dl", { className: "grid gap-2 text-xs", children: [
3018
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Source", value: node.sourceType }),
3019
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Source ID", value: node.sourceId }),
3020
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Thread", value: node.threadId }),
3021
+ /* @__PURE__ */ jsx21(InspectorRow, { label: "Checkpoint", value: node.checkpointId })
3022
+ ] }),
3023
+ /* @__PURE__ */ jsxs13("div", { className: "mt-4", children: [
3024
+ /* @__PURE__ */ jsx21("div", { className: "text-xs font-medium text-muted-foreground", children: "Source messages" }),
3025
+ /* @__PURE__ */ jsx21("div", { className: "mt-2 flex flex-wrap gap-1", children: sourceMessageIds.length ? sourceMessageIds.map((id) => /* @__PURE__ */ jsx21(Badge, { className: "max-w-full truncate", variant: "outline", children: id }, id)) : /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: "-" }) })
3026
+ ] })
3027
+ ] });
3028
+ }
3029
+ function MatchBadges({ match }) {
3030
+ if (!match?.reasons.length) return null;
3031
+ return /* @__PURE__ */ jsx21("div", { className: "mt-2 flex flex-wrap gap-1", children: match.reasons.slice(0, 4).map((reason) => /* @__PURE__ */ jsx21(Badge, { className: "text-[10px]", variant: "outline", children: reason }, reason)) });
3032
+ }
2380
3033
  function InspectorRow({
2381
3034
  label,
2382
3035
  value
@@ -2405,6 +3058,12 @@ function formatDateTime(value) {
2405
3058
  if (Number.isNaN(date.getTime())) return value;
2406
3059
  return date.toLocaleString();
2407
3060
  }
3061
+ function formatNullableNumber(value) {
3062
+ return typeof value === "number" && Number.isFinite(value) ? value.toFixed(2) : "-";
3063
+ }
3064
+ function formatSimilarityScore(value) {
3065
+ return Number.isFinite(value) ? `Similarity ${value.toFixed(2)}` : "-";
3066
+ }
2408
3067
  function emptyBrainResponse() {
2409
3068
  return {
2410
3069
  nodes: [],
@@ -2416,6 +3075,14 @@ function emptyBrainResponse() {
2416
3075
  byKind: {},
2417
3076
  byStatus: {}
2418
3077
  },
3078
+ matches: {},
3079
+ related: [],
3080
+ similar: [],
3081
+ semantic: {
3082
+ requested: false,
3083
+ available: false,
3084
+ error: null
3085
+ },
2419
3086
  pageInfo: {
2420
3087
  limit: 0,
2421
3088
  offset: 0,
@@ -4806,8 +5473,11 @@ function useCopilotzAdmin(options = {}) {
4806
5473
  export {
4807
5474
  ADMIN_GROUP_LABELS,
4808
5475
  ADMIN_GROUP_ORDER,
5476
+ BRAIN_RELATION_GROUP_DEFINITIONS,
5477
+ BRAIN_VIEW_LABELS,
4809
5478
  CopilotzAdmin,
4810
5479
  EMPTY_USAGE_TOTALS,
5480
+ ENTITY_FOCUS_RELATION_TYPES,
4811
5481
  EmptyState,
4812
5482
  FilterBar,
4813
5483
  InspectorPanel,
@@ -4836,11 +5506,16 @@ export {
4836
5506
  formatNumber,
4837
5507
  formatPercent,
4838
5508
  formatUsageBucket,
5509
+ getBrainViewBaseFilters,
5510
+ getKnowledgeRelationGroups,
4839
5511
  getUsageDimensionLabel,
4840
5512
  getUsageGroupLabel,
4841
5513
  getUsageMetricLabel,
4842
5514
  getUsageRange,
4843
5515
  getUsageTotalValue,
5516
+ getWorkRelationGroups,
5517
+ groupBrainRelationsByKind,
5518
+ isEntityBrainView,
4844
5519
  mergeAdminConfig,
4845
5520
  overviewModule,
4846
5521
  participantsModule,