@agentprojectcontext/apx 1.72.0 → 1.73.0

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.
@@ -18,8 +18,8 @@
18
18
  <link rel="apple-touch-icon" href="/favicon/dark/apple-touch-icon.png" media="(prefers-color-scheme: dark)" />
19
19
  <link rel="manifest" href="/favicon/white/site.webmanifest" media="(prefers-color-scheme: light)" />
20
20
  <link rel="manifest" href="/favicon/dark/site.webmanifest" media="(prefers-color-scheme: dark)" />
21
- <script type="module" crossorigin src="/assets/index-DVxJfrii.js"></script>
22
- <link rel="stylesheet" crossorigin href="/assets/index-vSNUqL56.css">
21
+ <script type="module" crossorigin src="/assets/index-D2b7Sqvg.js"></script>
22
+ <link rel="stylesheet" crossorigin href="/assets/index-CUeIhw7z.css">
23
23
  </head>
24
24
  <body class="bg-background text-foreground antialiased">
25
25
  <div id="root"></div>
@@ -1495,6 +1495,9 @@ export const en = {
1495
1495
  brain_pan_hint: "scroll to zoom · drag background to pan",
1496
1496
  brain_expand: "Expand brains",
1497
1497
  brain_collapse: "Collapse",
1498
+ brain_open: "Open",
1499
+ brain_part_of: "Part of",
1500
+ brain_branches: "Branches",
1498
1501
  config_def_desc: "definition (frontmatter + system prompt).",
1499
1502
  memory_durable_desc: "durable facts the agent remembers.",
1500
1503
  running: "running",
@@ -1493,6 +1493,9 @@ export const es = {
1493
1493
  brain_pan_hint: "scroll para zoom · arrastrá el fondo para mover",
1494
1494
  brain_expand: "Expandir cerebros",
1495
1495
  brain_collapse: "Colapsar",
1496
+ brain_open: "Abrir",
1497
+ brain_part_of: "Parte de",
1498
+ brain_branches: "Ramas",
1496
1499
  config_def_desc: "definición (frontmatter + system prompt).",
1497
1500
  memory_durable_desc: "hechos durables que el agente recuerda.",
1498
1501
  running: "running",
@@ -53,6 +53,12 @@ function kindLabel(k: BrainKind): string {
53
53
  const RADIUS: Record<BrainRole, number> = { core: 24, hub: 12, leaf: 6 };
54
54
  const roleOf = (n: BrainNode): BrainRole => n.role ?? "leaf";
55
55
  const clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));
56
+ const uniqById = <T extends { id: string }>(arr: T[]): T[] => {
57
+ const m = new Map<string, T>();
58
+ for (const n of arr) m.set(n.id, n);
59
+ return [...m.values()];
60
+ };
61
+ const clip = (s: string, n = 26) => (s.length > n ? `${s.slice(0, n)}…` : s);
56
62
 
57
63
  export function BrainGraph({
58
64
  nodes, edges, height = 520, onNodeClick, toolbar,
@@ -223,6 +229,13 @@ export function BrainGraph({
223
229
  const legendKinds = [...new Set(nodes.map((n) => n.kind))].filter((k) => k !== "agent" && k !== "hub");
224
230
  const pick = (n: SimNode) => { setSelected(n); onNodeClick?.(n); };
225
231
 
232
+ // For the detail panel: what the selected node hangs off (parents) and the
233
+ // branches that hang off it (children), derived from the live edges.
234
+ const selParents = selected ? uniqById(links.filter((l) => l.target.id === selected.id).map((l) => l.source)) : [];
235
+ const selChildren = selected ? uniqById(links.filter((l) => l.source.id === selected.id).map((l) => l.target)) : [];
236
+ // The detail line is only meaningful when it adds something beyond the title.
237
+ const selDetail = selected?.detail && selected.detail.trim() !== selected.label.trim() ? selected.detail : null;
238
+
226
239
  const CtrlBtn = ({ onClick, title, children }: { onClick: () => void; title: string; children: React.ReactNode }) => (
227
240
  <button type="button" title={title} onClick={onClick}
228
241
  className="grid size-7 place-items-center rounded-md border border-border bg-card/80 text-muted-fg backdrop-blur hover:text-foreground">
@@ -364,16 +377,63 @@ export function BrainGraph({
364
377
  </div>
365
378
 
366
379
  {selected && (
367
- <div className="rounded-lg border border-border bg-card p-3 text-xs">
368
- <div className="flex items-center gap-2">
369
- <span className="size-2 rounded-full" style={{ background: KIND_COLOR[selected.kind] }} />
370
- {selected.emoji && <span>{selected.emoji}</span>}
371
- <span className="font-medium">{selected.label}</span>
380
+ <div className="space-y-2.5 rounded-lg border border-border bg-card p-3 text-xs">
381
+ {/* The clicked node: title, type, relation */}
382
+ <div className="flex flex-wrap items-center gap-2">
383
+ <span className="size-2.5 rounded-full" style={{ background: KIND_COLOR[selected.kind] }} />
384
+ {selected.emoji && <span className="text-sm leading-none">{selected.emoji}</span>}
385
+ <span className="text-[13px] font-semibold">{selected.label}</span>
386
+ <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-muted-fg">
387
+ {kindLabel(selected.kind)}
388
+ </span>
372
389
  {selected.relation && <span className="text-muted-fg">· {selected.relation}</span>}
390
+ <div className="ml-auto flex items-center gap-2">
391
+ {selected.slug && onNodeClick && (
392
+ <button type="button" onClick={() => onNodeClick(selected)} className="text-primary hover:underline">
393
+ {t("agents_ui.brain_open")}
394
+ </button>
395
+ )}
396
+ <button type="button" onClick={() => setSelected(null)} className="text-muted-fg hover:text-foreground">✕</button>
397
+ </div>
373
398
  </div>
374
- {selected.detail && <p className="mt-1 whitespace-pre-wrap text-muted-fg">{selected.detail}</p>}
399
+
400
+ {/* Internal info — only when it adds something beyond the title */}
401
+ {selDetail && <p className="whitespace-pre-wrap text-muted-fg">{selDetail}</p>}
402
+
403
+ {/* Where it hangs from */}
404
+ {selParents.length > 0 && (
405
+ <div className="flex flex-wrap items-center gap-1.5">
406
+ <span className="text-[10px] uppercase tracking-wide text-muted-fg/70">{t("agents_ui.brain_part_of")}</span>
407
+ {selParents.map((p) => <NeighborChip key={p.id} node={p} onClick={() => setSelected(p)} />)}
408
+ </div>
409
+ )}
410
+
411
+ {/* Branches that follow it */}
412
+ {selChildren.length > 0 && (
413
+ <div className="flex flex-wrap items-center gap-1.5">
414
+ <span className="text-[10px] uppercase tracking-wide text-muted-fg/70">
415
+ {t("agents_ui.brain_branches")} · {selChildren.length}
416
+ </span>
417
+ {selChildren.map((c) => <NeighborChip key={c.id} node={c} onClick={() => setSelected(c)} />)}
418
+ </div>
419
+ )}
375
420
  </div>
376
421
  )}
377
422
  </div>
378
423
  );
379
424
  }
425
+
426
+ // A clickable chip for a connected node in the detail panel.
427
+ function NeighborChip({ node, onClick }: { node: BrainNode; onClick: () => void }) {
428
+ return (
429
+ <button
430
+ type="button"
431
+ onClick={onClick}
432
+ className="inline-flex max-w-[220px] items-center gap-1 rounded-md border border-border bg-muted/40 px-1.5 py-0.5 text-[11px] hover:border-muted-fg/50 hover:bg-muted"
433
+ >
434
+ <span className="size-1.5 shrink-0 rounded-full" style={{ background: KIND_COLOR[node.kind] }} />
435
+ {node.emoji && <span className="leading-none">{node.emoji}</span>}
436
+ <span className="truncate">{clip(node.label, 28)}</span>
437
+ </button>
438
+ );
439
+ }