@ai-matrx/agents 0.41.1 → 0.42.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.
@@ -494,10 +494,43 @@ function summarizeContextRows(rows) {
494
494
  var import_jsx_runtime3 = require("react/jsx-runtime");
495
495
  var CONTEXT_RULES_GRID = {
496
496
  compact: "grid grid-cols-[minmax(0,1fr)_2.75rem_4rem_6.5rem] items-center gap-x-2 px-2",
497
- // Phone widths (375px): the fixed columns stay compact so Item always keeps
498
- // the remaining width — ~125px at 375 — and truncates with an ellipsis.
499
497
  comfortable: "grid grid-cols-[minmax(0,1fr)_2.75rem_3.5rem_6.75rem] items-center gap-x-1.5 px-3"
500
498
  };
499
+ var NARROW_GRID = {
500
+ compact: "grid grid-cols-[minmax(0,1fr)_auto_auto_auto] items-center gap-x-1.5 px-2",
501
+ comfortable: "grid grid-cols-[minmax(0,1fr)_auto_auto_auto] items-center gap-x-1.5 px-3"
502
+ };
503
+ var CONTEXT_RULES_NARROW_BELOW = 400;
504
+ var useIsoLayoutEffect = typeof window === "undefined" ? React2.useEffect : React2.useLayoutEffect;
505
+ function useNarrow(ref) {
506
+ const [narrow, setNarrow] = React2.useState(false);
507
+ useIsoLayoutEffect(() => {
508
+ const el = ref.current;
509
+ if (!el) return void 0;
510
+ const fit = () => {
511
+ const width = el.clientWidth;
512
+ if (width > 0) setNarrow(width < CONTEXT_RULES_NARROW_BELOW);
513
+ };
514
+ fit();
515
+ if (typeof ResizeObserver === "undefined") return void 0;
516
+ const observer = new ResizeObserver(fit);
517
+ observer.observe(el);
518
+ return () => observer.disconnect();
519
+ }, [ref]);
520
+ return narrow;
521
+ }
522
+ var INDENT = ["", "pl-2", "pl-4", "pl-6"];
523
+ var indent = (depth) => INDENT[Math.min(depth, INDENT.length - 1)];
524
+ function sectionsOf(levels) {
525
+ const out = [];
526
+ for (const level of levels) {
527
+ const label = level.ref.path.length > 1 ? level.ref.path[0] : null;
528
+ const last = out[out.length - 1];
529
+ if (label !== null && last && last.label === label) last.levels.push(level);
530
+ else out.push({ id: label === null ? `level:${level.ref.id}` : `section:${label}`, label, levels: [level] });
531
+ }
532
+ return out;
533
+ }
501
534
  function ContextRulesTable({
502
535
  rows,
503
536
  cap,
@@ -514,14 +547,23 @@ function ContextRulesTable({
514
547
  className
515
548
  }) {
516
549
  const comfortable = density === "comfortable";
550
+ const rootRef = React2.useRef(null);
551
+ const narrow = useNarrow(rootRef);
552
+ const grid = narrow ? NARROW_GRID[density] : CONTEXT_RULES_GRID[density];
517
553
  const levels = buildContextLevels(rows, hierarchy);
518
554
  const headed = Boolean(hierarchy) || levels.length > 1;
555
+ const bulkChanges = (list, next) => includeChanges(list, next, cap);
556
+ const bulk = (list) => onSetInclude && !readOnly ? (next) => {
557
+ const changes = bulkChanges(list, next);
558
+ if (changes.length > 0) onSetInclude(changes);
559
+ } : void 0;
519
560
  const renderRow = (row, depth) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
520
561
  ContextRuleRow,
521
562
  {
522
563
  row,
523
564
  cap,
524
- density,
565
+ grid,
566
+ narrow,
525
567
  depth: headed ? depth : 0,
526
568
  readOnly,
527
569
  selected: selectedKey === row.key,
@@ -534,154 +576,131 @@ function ContextRulesTable({
534
576
  },
535
577
  rowId(row)
536
578
  );
537
- const bulk = (list) => onSetInclude && !readOnly ? (next) => {
538
- const changes = includeChanges(list, next, cap);
539
- if (changes.length > 0) onSetInclude(changes);
540
- } : void 0;
541
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system2.TooltipProvider, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "table", "aria-label": "Values", "data-density": density, className: (0, import_design_system2.cn)("text-xs", className), children: [
542
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
543
- "div",
544
- {
545
- role: "row",
546
- className: (0, import_design_system2.cn)(
547
- CONTEXT_RULES_GRID[density],
548
- "sticky top-0 z-10 h-7 border-b border-border bg-card font-medium text-muted-foreground"
549
- ),
550
- children: [
551
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", children: "Item" }),
552
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", className: "text-center", children: "Include" }),
553
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", className: "text-right", children: "Chars" }),
554
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", className: "pr-6 text-right", children: "Inline max" })
555
- ]
556
- }
557
- ),
558
- levels.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-2 py-3 text-center text-muted-foreground", children: "None" }) : levels.map((level) => {
559
- const all = levelRows(level);
560
- const name = level.ref.path.join(" \u203A ");
561
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "rowgroup", "aria-label": headed ? name : void 0, "data-level": level.ref.id, children: [
562
- headed ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
563
- LevelHeading,
564
- {
565
- kind: "level",
566
- path: level.ref.path,
567
- rows: all,
568
- density,
569
- readOnly,
570
- ...levelSwitch(level, bulk(all))
571
- }
572
- ) : null,
573
- level.rows.map((row) => renderRow(row, 1)),
574
- level.groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "rowgroup", "aria-label": group.ref.label, "data-group": group.ref.id, children: [
575
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
576
- LevelHeading,
577
- {
578
- kind: "group",
579
- path: [group.ref.label],
580
- rows: group.rows,
581
- density,
582
- readOnly,
583
- onToggle: bulk(group.rows),
584
- checked: group.rows.some((r) => r.include)
585
- }
586
- ),
587
- group.rows.map((row) => renderRow(row, 2))
588
- ] }, group.ref.id))
589
- ] }, level.ref.id);
590
- })
591
- ] }) });
592
- }
593
- function levelSwitch(level, bulk) {
594
- if (level.master) return { checked: level.master.on, onToggle: level.master.onToggle };
595
- return { checked: levelRows(level).some((r) => r.include), onToggle: bulk };
596
- }
597
- var useIsoLayoutEffect = typeof window === "undefined" ? React2.useEffect : React2.useLayoutEffect;
598
- function HeadingPath({ path, name }) {
599
- const boxRef = React2.useRef(null);
600
- const fullRef = React2.useRef(null);
601
- const [compact, setCompact] = React2.useState(false);
602
- const multi = path.length > 1;
603
- useIsoLayoutEffect(() => {
604
- const box = boxRef.current;
605
- const full = fullRef.current;
606
- if (!multi || !box || !full) return void 0;
607
- const fit = () => setCompact(full.scrollWidth > box.clientWidth);
608
- fit();
609
- if (typeof ResizeObserver === "undefined") return void 0;
610
- const observer = new ResizeObserver(fit);
611
- observer.observe(box);
612
- return () => observer.disconnect();
613
- }, [multi, name]);
614
- const shown = multi && compact ? path.slice(-1) : path;
615
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
616
- "span",
579
+ const heading = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Heading, { ...props, grid, comfortable, readOnly }, props.id);
580
+ const renderLevel = (level, depth) => {
581
+ const all = levelRows(level);
582
+ const name = level.ref.path[level.ref.path.length - 1] ?? "";
583
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "rowgroup", "aria-label": headed ? level.ref.path.join(" \u203A ") : void 0, "data-level": level.ref.id, children: [
584
+ headed ? heading({
585
+ id: `h:${level.ref.id}`,
586
+ kind: "level",
587
+ label: name,
588
+ switchName: level.ref.path.join(" \u203A "),
589
+ depth,
590
+ rows: all,
591
+ ...levelSwitch(level, bulk(all))
592
+ }) : null,
593
+ level.rows.map((row) => renderRow(row, depth + 1)),
594
+ level.groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "rowgroup", "aria-label": group.ref.label, "data-group": group.ref.id, children: [
595
+ heading({
596
+ id: `h:${group.ref.id}`,
597
+ kind: "group",
598
+ label: group.ref.label,
599
+ switchName: group.ref.label,
600
+ depth: depth + 1,
601
+ rows: group.rows,
602
+ checked: group.rows.some((r) => r.include),
603
+ onToggle: bulk(group.rows)
604
+ }),
605
+ group.rows.map((row) => renderRow(row, depth + 2))
606
+ ] }, group.ref.id))
607
+ ] }, level.ref.id);
608
+ };
609
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system2.TooltipProvider, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
610
+ "div",
617
611
  {
618
- ref: boxRef,
619
- "data-compact": multi && compact ? "true" : void 0,
620
- className: "relative flex min-w-0 flex-1 items-center gap-1 overflow-hidden",
621
- title: name,
612
+ ref: rootRef,
613
+ role: "table",
614
+ "aria-label": "Values",
615
+ "data-density": density,
616
+ "data-layout": narrow ? "narrow" : "wide",
617
+ className: (0, import_design_system2.cn)("text-xs", className),
622
618
  children: [
623
- multi ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
624
- "span",
619
+ narrow ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
620
+ "div",
625
621
  {
626
- ref: fullRef,
627
- "aria-hidden": true,
628
- className: "pointer-events-none invisible absolute left-0 top-0 flex items-center gap-1 whitespace-nowrap",
629
- children: path.map((part, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React2.Fragment, { children: [
630
- i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u203A" }) : null,
631
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: part })
632
- ] }, `${i}:${part}`))
622
+ role: "row",
623
+ className: (0, import_design_system2.cn)(grid, "sticky top-0 z-10 h-7 border-b border-border bg-card font-medium text-muted-foreground"),
624
+ children: [
625
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", children: "Item" }),
626
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", className: "text-center", children: "Include" }),
627
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", className: "text-right", children: "Chars" }),
628
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { role: "columnheader", className: "pr-6 text-right", children: "Inline max" })
629
+ ]
633
630
  }
634
- ) : null,
635
- shown.map((part, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React2.Fragment, { children: [
636
- i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "shrink-0 text-muted-foreground", children: "\u203A" }) : null,
637
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
638
- "span",
639
- {
640
- className: (0, import_design_system2.cn)(
641
- i < shown.length - 1 ? "shrink-0 whitespace-nowrap text-muted-foreground" : "min-w-0 truncate"
642
- ),
643
- children: part
631
+ ),
632
+ levels.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-2 py-3 text-center text-muted-foreground", children: "None" }) : sectionsOf(levels).map((section) => {
633
+ if (section.label === null || !headed) return renderLevel(section.levels[0], 0);
634
+ const all = section.levels.flatMap(levelRows);
635
+ const several = section.levels.length > 1;
636
+ const toggleSection = several && !readOnly ? (next) => {
637
+ const changes = [];
638
+ for (const level of section.levels) {
639
+ if (level.master) level.master.onToggle?.(next);
640
+ else changes.push(...bulkChanges(levelRows(level), next));
644
641
  }
645
- )
646
- ] }, `${i}:${part}`))
642
+ if (changes.length > 0) onSetInclude?.(changes);
643
+ } : void 0;
644
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "rowgroup", "aria-label": section.label, "data-section": section.label, children: [
645
+ heading({
646
+ id: `h:${section.id}`,
647
+ kind: "section",
648
+ label: section.label,
649
+ switchName: section.label,
650
+ depth: 0,
651
+ rows: all,
652
+ checked: section.levels.some((l) => l.master ? l.master.on : levelRows(l).some((r) => r.include)),
653
+ onToggle: toggleSection,
654
+ noSwitch: !several
655
+ }),
656
+ section.levels.map((level) => renderLevel(level, 1))
657
+ ] }, section.id);
658
+ })
647
659
  ]
648
660
  }
649
- );
661
+ ) });
650
662
  }
651
- function LevelHeading({
663
+ function levelSwitch(level, bulk) {
664
+ if (level.master) return { checked: level.master.on, onToggle: level.master.onToggle };
665
+ return { checked: levelRows(level).some((r) => r.include), onToggle: bulk };
666
+ }
667
+ function Heading({
652
668
  kind,
653
- path,
669
+ label,
670
+ switchName,
671
+ depth,
654
672
  rows,
655
- density,
656
- readOnly,
657
673
  checked,
658
- onToggle
674
+ onToggle,
675
+ noSwitch,
676
+ grid,
677
+ comfortable,
678
+ readOnly
659
679
  }) {
660
- const name = path.join(" \u203A ");
661
680
  const { count, charsLabel } = summarizeContextRows(rows);
662
681
  const total = rows.length;
663
- const showSwitch = Boolean(onToggle) || readOnly && total > 0;
682
+ const showSwitch = !noSwitch && (Boolean(onToggle) || readOnly && total > 0);
664
683
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
665
684
  "div",
666
685
  {
667
686
  role: "row",
668
687
  "data-heading": kind,
669
688
  className: (0, import_design_system2.cn)(
670
- CONTEXT_RULES_GRID[density],
689
+ grid,
671
690
  "border-b border-border/50 font-medium",
672
- density === "comfortable" ? "min-h-11" : "h-7",
673
- kind === "level" ? "bg-muted/60 text-foreground" : "bg-muted/25 text-muted-foreground"
691
+ comfortable ? "min-h-11" : "h-7",
692
+ kind === "group" ? "bg-muted/25 text-muted-foreground" : "bg-muted/60 text-foreground"
674
693
  ),
675
694
  children: [
676
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "cell", className: (0, import_design_system2.cn)("flex min-w-0 items-center gap-1", kind === "group" && "pl-2"), children: [
677
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HeadingPath, { path, name }),
695
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "cell", className: (0, import_design_system2.cn)("flex min-w-0 items-center gap-1", indent(depth)), children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "min-w-0 truncate", title: label, children: label }),
678
697
  total > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "shrink-0 font-normal tabular-nums text-muted-foreground", children: count === total ? total : `${count}/${total}` }) : null
679
698
  ] }),
680
699
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { role: "cell", className: "flex justify-center", children: showSwitch ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
681
700
  import_design_system2.Switch,
682
701
  {
683
702
  size: "sm",
684
- "aria-label": `Include ${name}`,
703
+ "aria-label": `Include ${switchName}`,
685
704
  checked,
686
705
  disabled: readOnly || !onToggle,
687
706
  onCheckedChange: (next) => onToggle?.(next)
@@ -696,7 +715,8 @@ function LevelHeading({
696
715
  function ContextRuleRow({
697
716
  row,
698
717
  cap,
699
- density,
718
+ grid,
719
+ narrow,
700
720
  depth,
701
721
  comfortable,
702
722
  readOnly,
@@ -729,7 +749,7 @@ function ContextRuleRow({
729
749
  "data-mismatch": mismatches.length > 0 ? "true" : void 0,
730
750
  "aria-selected": selected || void 0,
731
751
  className: (0, import_design_system2.cn)(
732
- CONTEXT_RULES_GRID[density],
752
+ grid,
733
753
  "border-b border-border/50",
734
754
  comfortable ? "min-h-11" : "h-7",
735
755
  selected && "bg-accent"
@@ -741,8 +761,7 @@ function ContextRuleRow({
741
761
  role: "cell",
742
762
  className: (0, import_design_system2.cn)(
743
763
  "flex min-w-0 items-center gap-1.5",
744
- depth === 1 && "pl-2",
745
- depth === 2 && "pl-4",
764
+ indent(depth),
746
765
  !row.include && "opacity-50"
747
766
  ),
748
767
  children: [
@@ -794,7 +813,7 @@ function ContextRuleRow({
794
813
  ]
795
814
  }
796
815
  ),
797
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { role: "cell", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
816
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { role: "cell", children: narrow ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InlineMaxButton, { row, cap, readOnly, comfortable, onChange }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
798
817
  InlineMaxInput,
799
818
  {
800
819
  label: row.label,
@@ -811,6 +830,52 @@ function ContextRuleRow({
811
830
  }
812
831
  );
813
832
  }
833
+ function InlineMaxButton({
834
+ row,
835
+ cap,
836
+ readOnly,
837
+ comfortable,
838
+ onChange
839
+ }) {
840
+ const [open, setOpen] = React2.useState(false);
841
+ const own = row.userRule?.max_inline_chars ?? null;
842
+ const text = own !== null ? formatLimit(own) : limitPlaceholder(row, cap);
843
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system2.Popover, { open, onOpenChange: setOpen, children: [
844
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system2.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
845
+ "button",
846
+ {
847
+ type: "button",
848
+ "aria-label": `Inline max ${row.label}: ${text}`,
849
+ disabled: readOnly,
850
+ className: (0, import_design_system2.cn)(
851
+ "relative inline-flex min-w-[2.25rem] items-center justify-end gap-1 rounded px-1 tabular-nums hover:bg-accent disabled:opacity-60",
852
+ comfortable ? "h-8 after:absolute after:-inset-y-1.5 after:inset-x-0 after:content-['']" : "h-6",
853
+ own === null ? "text-muted-foreground" : "text-foreground"
854
+ ),
855
+ children: [
856
+ own !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": true, className: "h-1 w-1 rounded-full bg-primary" }) : null,
857
+ text
858
+ ]
859
+ }
860
+ ) }),
861
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system2.PopoverContent, { align: "end", className: "w-auto p-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
862
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-muted-foreground", children: "Inline max" }),
863
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
864
+ InlineMaxInput,
865
+ {
866
+ label: row.label,
867
+ value: own,
868
+ inherited: inheritedLimit(row, cap),
869
+ placeholder: limitPlaceholder(row, cap),
870
+ cap,
871
+ disabled: readOnly,
872
+ comfortable,
873
+ onCommit: (next) => onChange(row.key, row.surfaceKey, withLimit(row, next))
874
+ }
875
+ )
876
+ ] }) })
877
+ ] });
878
+ }
814
879
 
815
880
  // context/react/ContextRulesChip.tsx
816
881
  var React3 = __toESM(require("react"), 1);