@ai-matrx/agents 0.41.0 → 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.
@@ -297,7 +297,9 @@ interface ContextRulesTableProps {
297
297
  className?: string;
298
298
  }
299
299
  /**
300
- * The context rules table: Item | Include | Chars | Inline max. Presentational
300
+ * The context rules table: Item | Include | Chars | Inline max, under nested
301
+ * heading rows — section ("Marketing"), page ("Marketing Brand Cockpit"), the
302
+ * page's own groups — each heading full width with its switch. Presentational
301
303
  * and state-agnostic — every edit goes out through `onChange`.
302
304
  */
303
305
  declare function ContextRulesTable({ rows, cap, readOnly, mismatches, onChange, onOpenRow, density, selectedKey, hierarchy, onSetInclude, renderRowLead, renderRowTrail, className, }: ContextRulesTableProps): react.JSX.Element;
@@ -297,7 +297,9 @@ interface ContextRulesTableProps {
297
297
  className?: string;
298
298
  }
299
299
  /**
300
- * The context rules table: Item | Include | Chars | Inline max. Presentational
300
+ * The context rules table: Item | Include | Chars | Inline max, under nested
301
+ * heading rows — section ("Marketing"), page ("Marketing Brand Cockpit"), the
302
+ * page's own groups — each heading full width with its switch. Presentational
301
303
  * and state-agnostic — every edit goes out through `onChange`.
302
304
  */
303
305
  declare function ContextRulesTable({ rows, cap, readOnly, mismatches, onChange, onOpenRow, density, selectedKey, hierarchy, onSetInclude, renderRowLead, renderRowTrail, className, }: ContextRulesTableProps): react.JSX.Element;
@@ -3,6 +3,9 @@
3
3
  // context/react/ContextRulesTable.tsx
4
4
  import * as React2 from "react";
5
5
  import {
6
+ Popover,
7
+ PopoverContent,
8
+ PopoverTrigger,
6
9
  Switch,
7
10
  Tooltip as Tooltip2,
8
11
  TooltipContent as TooltipContent2,
@@ -456,10 +459,43 @@ function summarizeContextRows(rows) {
456
459
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
457
460
  var CONTEXT_RULES_GRID = {
458
461
  compact: "grid grid-cols-[minmax(0,1fr)_2.75rem_4rem_6.5rem] items-center gap-x-2 px-2",
459
- // Phone widths (375px): the fixed columns stay compact so Item always keeps
460
- // the remaining width — ~125px at 375 — and truncates with an ellipsis.
461
462
  comfortable: "grid grid-cols-[minmax(0,1fr)_2.75rem_3.5rem_6.75rem] items-center gap-x-1.5 px-3"
462
463
  };
464
+ var NARROW_GRID = {
465
+ compact: "grid grid-cols-[minmax(0,1fr)_auto_auto_auto] items-center gap-x-1.5 px-2",
466
+ comfortable: "grid grid-cols-[minmax(0,1fr)_auto_auto_auto] items-center gap-x-1.5 px-3"
467
+ };
468
+ var CONTEXT_RULES_NARROW_BELOW = 400;
469
+ var useIsoLayoutEffect = typeof window === "undefined" ? React2.useEffect : React2.useLayoutEffect;
470
+ function useNarrow(ref) {
471
+ const [narrow, setNarrow] = React2.useState(false);
472
+ useIsoLayoutEffect(() => {
473
+ const el = ref.current;
474
+ if (!el) return void 0;
475
+ const fit = () => {
476
+ const width = el.clientWidth;
477
+ if (width > 0) setNarrow(width < CONTEXT_RULES_NARROW_BELOW);
478
+ };
479
+ fit();
480
+ if (typeof ResizeObserver === "undefined") return void 0;
481
+ const observer = new ResizeObserver(fit);
482
+ observer.observe(el);
483
+ return () => observer.disconnect();
484
+ }, [ref]);
485
+ return narrow;
486
+ }
487
+ var INDENT = ["", "pl-2", "pl-4", "pl-6"];
488
+ var indent = (depth) => INDENT[Math.min(depth, INDENT.length - 1)];
489
+ function sectionsOf(levels) {
490
+ const out = [];
491
+ for (const level of levels) {
492
+ const label = level.ref.path.length > 1 ? level.ref.path[0] : null;
493
+ const last = out[out.length - 1];
494
+ if (label !== null && last && last.label === label) last.levels.push(level);
495
+ else out.push({ id: label === null ? `level:${level.ref.id}` : `section:${label}`, label, levels: [level] });
496
+ }
497
+ return out;
498
+ }
463
499
  function ContextRulesTable({
464
500
  rows,
465
501
  cap,
@@ -476,14 +512,23 @@ function ContextRulesTable({
476
512
  className
477
513
  }) {
478
514
  const comfortable = density === "comfortable";
515
+ const rootRef = React2.useRef(null);
516
+ const narrow = useNarrow(rootRef);
517
+ const grid = narrow ? NARROW_GRID[density] : CONTEXT_RULES_GRID[density];
479
518
  const levels = buildContextLevels(rows, hierarchy);
480
519
  const headed = Boolean(hierarchy) || levels.length > 1;
520
+ const bulkChanges = (list, next) => includeChanges(list, next, cap);
521
+ const bulk = (list) => onSetInclude && !readOnly ? (next) => {
522
+ const changes = bulkChanges(list, next);
523
+ if (changes.length > 0) onSetInclude(changes);
524
+ } : void 0;
481
525
  const renderRow = (row, depth) => /* @__PURE__ */ jsx3(
482
526
  ContextRuleRow,
483
527
  {
484
528
  row,
485
529
  cap,
486
- density,
530
+ grid,
531
+ narrow,
487
532
  depth: headed ? depth : 0,
488
533
  readOnly,
489
534
  selected: selectedKey === row.key,
@@ -496,112 +541,131 @@ function ContextRulesTable({
496
541
  },
497
542
  rowId(row)
498
543
  );
499
- const bulk = (list) => onSetInclude && !readOnly ? (next) => {
500
- const changes = includeChanges(list, next, cap);
501
- if (changes.length > 0) onSetInclude(changes);
502
- } : void 0;
503
- return /* @__PURE__ */ jsx3(TooltipProvider, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ jsxs3("div", { role: "table", "aria-label": "Values", "data-density": density, className: cn2("text-xs", className), children: [
504
- /* @__PURE__ */ jsxs3(
505
- "div",
506
- {
507
- role: "row",
508
- className: cn2(
509
- CONTEXT_RULES_GRID[density],
510
- "sticky top-0 z-10 h-7 border-b border-border bg-card font-medium text-muted-foreground"
511
- ),
512
- children: [
513
- /* @__PURE__ */ jsx3("span", { role: "columnheader", children: "Item" }),
514
- /* @__PURE__ */ jsx3("span", { role: "columnheader", className: "text-center", children: "Include" }),
515
- /* @__PURE__ */ jsx3("span", { role: "columnheader", className: "text-right", children: "Chars" }),
516
- /* @__PURE__ */ jsx3("span", { role: "columnheader", className: "pr-6 text-right", children: "Inline max" })
517
- ]
518
- }
519
- ),
520
- levels.length === 0 ? /* @__PURE__ */ jsx3("div", { className: "px-2 py-3 text-center text-muted-foreground", children: "None" }) : levels.map((level) => {
521
- const all = levelRows(level);
522
- const name = level.ref.path.join(" \u203A ");
523
- return /* @__PURE__ */ jsxs3("div", { role: "rowgroup", "aria-label": headed ? name : void 0, "data-level": level.ref.id, children: [
524
- headed ? /* @__PURE__ */ jsx3(
525
- LevelHeading,
544
+ const heading = (props) => /* @__PURE__ */ jsx3(Heading, { ...props, grid, comfortable, readOnly }, props.id);
545
+ const renderLevel = (level, depth) => {
546
+ const all = levelRows(level);
547
+ const name = level.ref.path[level.ref.path.length - 1] ?? "";
548
+ return /* @__PURE__ */ jsxs3("div", { role: "rowgroup", "aria-label": headed ? level.ref.path.join(" \u203A ") : void 0, "data-level": level.ref.id, children: [
549
+ headed ? heading({
550
+ id: `h:${level.ref.id}`,
551
+ kind: "level",
552
+ label: name,
553
+ switchName: level.ref.path.join(" \u203A "),
554
+ depth,
555
+ rows: all,
556
+ ...levelSwitch(level, bulk(all))
557
+ }) : null,
558
+ level.rows.map((row) => renderRow(row, depth + 1)),
559
+ level.groups.map((group) => /* @__PURE__ */ jsxs3("div", { role: "rowgroup", "aria-label": group.ref.label, "data-group": group.ref.id, children: [
560
+ heading({
561
+ id: `h:${group.ref.id}`,
562
+ kind: "group",
563
+ label: group.ref.label,
564
+ switchName: group.ref.label,
565
+ depth: depth + 1,
566
+ rows: group.rows,
567
+ checked: group.rows.some((r) => r.include),
568
+ onToggle: bulk(group.rows)
569
+ }),
570
+ group.rows.map((row) => renderRow(row, depth + 2))
571
+ ] }, group.ref.id))
572
+ ] }, level.ref.id);
573
+ };
574
+ return /* @__PURE__ */ jsx3(TooltipProvider, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ jsxs3(
575
+ "div",
576
+ {
577
+ ref: rootRef,
578
+ role: "table",
579
+ "aria-label": "Values",
580
+ "data-density": density,
581
+ "data-layout": narrow ? "narrow" : "wide",
582
+ className: cn2("text-xs", className),
583
+ children: [
584
+ narrow ? null : /* @__PURE__ */ jsxs3(
585
+ "div",
526
586
  {
527
- kind: "level",
528
- path: level.ref.path,
529
- rows: all,
530
- density,
531
- readOnly,
532
- ...levelSwitch(level, bulk(all))
587
+ role: "row",
588
+ className: cn2(grid, "sticky top-0 z-10 h-7 border-b border-border bg-card font-medium text-muted-foreground"),
589
+ children: [
590
+ /* @__PURE__ */ jsx3("span", { role: "columnheader", children: "Item" }),
591
+ /* @__PURE__ */ jsx3("span", { role: "columnheader", className: "text-center", children: "Include" }),
592
+ /* @__PURE__ */ jsx3("span", { role: "columnheader", className: "text-right", children: "Chars" }),
593
+ /* @__PURE__ */ jsx3("span", { role: "columnheader", className: "pr-6 text-right", children: "Inline max" })
594
+ ]
533
595
  }
534
- ) : null,
535
- level.rows.map((row) => renderRow(row, 1)),
536
- level.groups.map((group) => /* @__PURE__ */ jsxs3("div", { role: "rowgroup", "aria-label": group.ref.label, "data-group": group.ref.id, children: [
537
- /* @__PURE__ */ jsx3(
538
- LevelHeading,
539
- {
540
- kind: "group",
541
- path: [group.ref.label],
542
- rows: group.rows,
543
- density,
544
- readOnly,
545
- onToggle: bulk(group.rows),
546
- checked: group.rows.some((r) => r.include)
596
+ ),
597
+ levels.length === 0 ? /* @__PURE__ */ jsx3("div", { className: "px-2 py-3 text-center text-muted-foreground", children: "None" }) : sectionsOf(levels).map((section) => {
598
+ if (section.label === null || !headed) return renderLevel(section.levels[0], 0);
599
+ const all = section.levels.flatMap(levelRows);
600
+ const several = section.levels.length > 1;
601
+ const toggleSection = several && !readOnly ? (next) => {
602
+ const changes = [];
603
+ for (const level of section.levels) {
604
+ if (level.master) level.master.onToggle?.(next);
605
+ else changes.push(...bulkChanges(levelRows(level), next));
547
606
  }
548
- ),
549
- group.rows.map((row) => renderRow(row, 2))
550
- ] }, group.ref.id))
551
- ] }, level.ref.id);
552
- })
553
- ] }) });
607
+ if (changes.length > 0) onSetInclude?.(changes);
608
+ } : void 0;
609
+ return /* @__PURE__ */ jsxs3("div", { role: "rowgroup", "aria-label": section.label, "data-section": section.label, children: [
610
+ heading({
611
+ id: `h:${section.id}`,
612
+ kind: "section",
613
+ label: section.label,
614
+ switchName: section.label,
615
+ depth: 0,
616
+ rows: all,
617
+ checked: section.levels.some((l) => l.master ? l.master.on : levelRows(l).some((r) => r.include)),
618
+ onToggle: toggleSection,
619
+ noSwitch: !several
620
+ }),
621
+ section.levels.map((level) => renderLevel(level, 1))
622
+ ] }, section.id);
623
+ })
624
+ ]
625
+ }
626
+ ) });
554
627
  }
555
628
  function levelSwitch(level, bulk) {
556
629
  if (level.master) return { checked: level.master.on, onToggle: level.master.onToggle };
557
630
  return { checked: levelRows(level).some((r) => r.include), onToggle: bulk };
558
631
  }
559
- function LevelHeading({
632
+ function Heading({
560
633
  kind,
561
- path,
634
+ label,
635
+ switchName,
636
+ depth,
562
637
  rows,
563
- density,
564
- readOnly,
565
638
  checked,
566
- onToggle
639
+ onToggle,
640
+ noSwitch,
641
+ grid,
642
+ comfortable,
643
+ readOnly
567
644
  }) {
568
- const name = path.join(" \u203A ");
569
645
  const { count, charsLabel } = summarizeContextRows(rows);
570
646
  const total = rows.length;
571
- const showSwitch = Boolean(onToggle) || readOnly && total > 0;
647
+ const showSwitch = !noSwitch && (Boolean(onToggle) || readOnly && total > 0);
572
648
  return /* @__PURE__ */ jsxs3(
573
649
  "div",
574
650
  {
575
651
  role: "row",
576
652
  "data-heading": kind,
577
653
  className: cn2(
578
- CONTEXT_RULES_GRID[density],
654
+ grid,
579
655
  "border-b border-border/50 font-medium",
580
- density === "comfortable" ? "min-h-11" : "h-7",
581
- kind === "level" ? "bg-muted/60 text-foreground" : "bg-muted/25 text-muted-foreground"
656
+ comfortable ? "min-h-11" : "h-7",
657
+ kind === "group" ? "bg-muted/25 text-muted-foreground" : "bg-muted/60 text-foreground"
582
658
  ),
583
659
  children: [
584
- /* @__PURE__ */ jsxs3("div", { role: "cell", className: cn2("flex min-w-0 items-center gap-1", kind === "group" && "pl-2"), children: [
585
- /* @__PURE__ */ jsx3("span", { className: "flex min-w-0 items-center gap-1 overflow-hidden", title: name, children: path.map((part, i) => /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
586
- i > 0 ? /* @__PURE__ */ jsx3("span", { className: "shrink-0 text-muted-foreground", children: "\u203A" }) : null,
587
- /* @__PURE__ */ jsx3(
588
- "span",
589
- {
590
- className: cn2(
591
- "truncate",
592
- i < path.length - 1 ? "max-w-[45%] shrink-0 text-muted-foreground" : "min-w-0"
593
- ),
594
- children: part
595
- }
596
- )
597
- ] }, `${i}:${part}`)) }),
660
+ /* @__PURE__ */ jsxs3("div", { role: "cell", className: cn2("flex min-w-0 items-center gap-1", indent(depth)), children: [
661
+ /* @__PURE__ */ jsx3("span", { className: "min-w-0 truncate", title: label, children: label }),
598
662
  total > 0 ? /* @__PURE__ */ jsx3("span", { className: "shrink-0 font-normal tabular-nums text-muted-foreground", children: count === total ? total : `${count}/${total}` }) : null
599
663
  ] }),
600
664
  /* @__PURE__ */ jsx3("div", { role: "cell", className: "flex justify-center", children: showSwitch ? /* @__PURE__ */ jsx3(
601
665
  Switch,
602
666
  {
603
667
  size: "sm",
604
- "aria-label": `Include ${name}`,
668
+ "aria-label": `Include ${switchName}`,
605
669
  checked,
606
670
  disabled: readOnly || !onToggle,
607
671
  onCheckedChange: (next) => onToggle?.(next)
@@ -616,7 +680,8 @@ function LevelHeading({
616
680
  function ContextRuleRow({
617
681
  row,
618
682
  cap,
619
- density,
683
+ grid,
684
+ narrow,
620
685
  depth,
621
686
  comfortable,
622
687
  readOnly,
@@ -649,7 +714,7 @@ function ContextRuleRow({
649
714
  "data-mismatch": mismatches.length > 0 ? "true" : void 0,
650
715
  "aria-selected": selected || void 0,
651
716
  className: cn2(
652
- CONTEXT_RULES_GRID[density],
717
+ grid,
653
718
  "border-b border-border/50",
654
719
  comfortable ? "min-h-11" : "h-7",
655
720
  selected && "bg-accent"
@@ -661,8 +726,7 @@ function ContextRuleRow({
661
726
  role: "cell",
662
727
  className: cn2(
663
728
  "flex min-w-0 items-center gap-1.5",
664
- depth === 1 && "pl-2",
665
- depth === 2 && "pl-4",
729
+ indent(depth),
666
730
  !row.include && "opacity-50"
667
731
  ),
668
732
  children: [
@@ -714,7 +778,7 @@ function ContextRuleRow({
714
778
  ]
715
779
  }
716
780
  ),
717
- /* @__PURE__ */ jsx3("div", { role: "cell", children: /* @__PURE__ */ jsx3(
781
+ /* @__PURE__ */ jsx3("div", { role: "cell", children: narrow ? /* @__PURE__ */ jsx3(InlineMaxButton, { row, cap, readOnly, comfortable, onChange }) : /* @__PURE__ */ jsx3(
718
782
  InlineMaxInput,
719
783
  {
720
784
  label: row.label,
@@ -731,14 +795,60 @@ function ContextRuleRow({
731
795
  }
732
796
  );
733
797
  }
798
+ function InlineMaxButton({
799
+ row,
800
+ cap,
801
+ readOnly,
802
+ comfortable,
803
+ onChange
804
+ }) {
805
+ const [open, setOpen] = React2.useState(false);
806
+ const own = row.userRule?.max_inline_chars ?? null;
807
+ const text = own !== null ? formatLimit(own) : limitPlaceholder(row, cap);
808
+ return /* @__PURE__ */ jsxs3(Popover, { open, onOpenChange: setOpen, children: [
809
+ /* @__PURE__ */ jsx3(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
810
+ "button",
811
+ {
812
+ type: "button",
813
+ "aria-label": `Inline max ${row.label}: ${text}`,
814
+ disabled: readOnly,
815
+ className: cn2(
816
+ "relative inline-flex min-w-[2.25rem] items-center justify-end gap-1 rounded px-1 tabular-nums hover:bg-accent disabled:opacity-60",
817
+ comfortable ? "h-8 after:absolute after:-inset-y-1.5 after:inset-x-0 after:content-['']" : "h-6",
818
+ own === null ? "text-muted-foreground" : "text-foreground"
819
+ ),
820
+ children: [
821
+ own !== null ? /* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: "h-1 w-1 rounded-full bg-primary" }) : null,
822
+ text
823
+ ]
824
+ }
825
+ ) }),
826
+ /* @__PURE__ */ jsx3(PopoverContent, { align: "end", className: "w-auto p-2", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-xs", children: [
827
+ /* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: "Inline max" }),
828
+ /* @__PURE__ */ jsx3(
829
+ InlineMaxInput,
830
+ {
831
+ label: row.label,
832
+ value: own,
833
+ inherited: inheritedLimit(row, cap),
834
+ placeholder: limitPlaceholder(row, cap),
835
+ cap,
836
+ disabled: readOnly,
837
+ comfortable,
838
+ onCommit: (next) => onChange(row.key, row.surfaceKey, withLimit(row, next))
839
+ }
840
+ )
841
+ ] }) })
842
+ ] });
843
+ }
734
844
 
735
845
  // context/react/ContextRulesChip.tsx
736
846
  import * as React3 from "react";
737
847
  import {
738
848
  BottomSheet,
739
- Popover,
740
- PopoverContent,
741
- PopoverTrigger,
849
+ Popover as Popover2,
850
+ PopoverContent as PopoverContent2,
851
+ PopoverTrigger as PopoverTrigger2,
742
852
  Switch as Switch2,
743
853
  Tooltip as Tooltip3,
744
854
  TooltipContent as TooltipContent3,
@@ -904,10 +1014,10 @@ function ContextRulesChip({
904
1014
  /* @__PURE__ */ jsx4(BottomSheet, { open, onOpenChange: setOpen, title: name || faceName, surface: "solid", children: body })
905
1015
  ] });
906
1016
  }
907
- return /* @__PURE__ */ jsx4(TooltipProvider2, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ jsxs4(Popover, { open, onOpenChange: setOpen, children: [
908
- withBlindTip(/* @__PURE__ */ jsx4(PopoverTrigger, { asChild: true, children: faceButton })),
1017
+ return /* @__PURE__ */ jsx4(TooltipProvider2, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ jsxs4(Popover2, { open, onOpenChange: setOpen, children: [
1018
+ withBlindTip(/* @__PURE__ */ jsx4(PopoverTrigger2, { asChild: true, children: faceButton })),
909
1019
  /* @__PURE__ */ jsx4(
910
- PopoverContent,
1020
+ PopoverContent2,
911
1021
  {
912
1022
  align: "end",
913
1023
  className: "w-[26rem] max-w-[calc(100vw-1rem)] overflow-hidden p-0",
@@ -1140,7 +1250,7 @@ function ContextReceiptBlockDetail({
1140
1250
  }
1141
1251
 
1142
1252
  // context/react/ContextRulesPanelBody.tsx
1143
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1253
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1144
1254
  function layerCells(row) {
1145
1255
  const { surface, agent, default_max } = row.layers ?? {};
1146
1256
  const declared = agent?.declared === true;
@@ -1347,7 +1457,7 @@ function ContextRulesPanelBody({
1347
1457
  }
1348
1458
  ) : null;
1349
1459
  if (isMobile) {
1350
- return /* @__PURE__ */ jsx7(TooltipProvider3, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ jsx7("div", { className: cn6("flex h-full min-h-0 flex-col", className), children: detail ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
1460
+ return /* @__PURE__ */ jsx7(TooltipProvider3, { delayDuration: 300, titleTooltips: false, children: /* @__PURE__ */ jsx7("div", { className: cn6("flex h-full min-h-0 flex-col", className), children: detail ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
1351
1461
  /* @__PURE__ */ jsx7("div", { className: "flex h-12 shrink-0 items-center border-b border-border px-1", children: /* @__PURE__ */ jsxs7(
1352
1462
  "button",
1353
1463
  {
@@ -1361,7 +1471,7 @@ function ContextRulesPanelBody({
1361
1471
  }
1362
1472
  ) }),
1363
1473
  /* @__PURE__ */ jsx7("div", { className: "min-h-0 flex-1 overflow-y-auto", children: detail })
1364
- ] }) : /* @__PURE__ */ jsxs7(Fragment3, { children: [
1474
+ ] }) : /* @__PURE__ */ jsxs7(Fragment2, { children: [
1365
1475
  search,
1366
1476
  table
1367
1477
  ] }) }) });