@ai-matrx/agents 0.59.268 → 0.59.270

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/CHANGELOG.md CHANGED
@@ -1,10 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 0.59.268
3
+ ## 0.59.270
4
4
 
5
5
  UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
6
  Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/matrx-agents/src`.
7
7
 
8
+ ## 0.59.269
9
+
10
+ Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff 5b7c48a99c 4c08cba6c4 -- apps/shared/matrx-agents/src`
11
+ has no shipped-source changes outside tests, fixtures and docs). No consumer action required.
12
+
13
+ ## 0.59.268
14
+
15
+ Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff 06a190b44e 5b7c48a99c -- apps/shared/matrx-agents/src`
16
+ has no shipped-source changes outside tests, fixtures and docs). No consumer action required.
17
+
8
18
  ## 0.59.267
9
19
  ### a kept value with no schema stays editable; a value's source reaches a phone
10
20
 
@@ -43,6 +43,7 @@ __export(context_exports, {
43
43
  contextValueChars: () => contextValueChars,
44
44
  deliveredFields: () => deliveredFields,
45
45
  formatChars: () => formatChars,
46
+ hasNothingToSend: () => hasNothingToSend,
46
47
  isRichEnvelope: () => isRichEnvelope,
47
48
  isServerAuthoritativeKey: () => isServerAuthoritativeKey,
48
49
  isServerResolved: () => isServerResolved,
@@ -281,6 +282,16 @@ function isRichEnvelope(value) {
281
282
  function isLazyPointer(value) {
282
283
  return isPlainObject(value) && !hasOwn(value, "content") && onlyRichKeys(value) && hasLazySource(value);
283
284
  }
285
+ function hasNothingToSend(value) {
286
+ if (value === void 0 || value === null) return true;
287
+ if (typeof value === "string") return value.trim() === "";
288
+ if (Array.isArray(value)) return value.length === 0;
289
+ if (!isPlainObject(value)) return false;
290
+ if (value.__kind !== void 0) return false;
291
+ if (isRichEnvelope(value)) return !hasLazySource(value) && hasNothingToSend(value.content);
292
+ if (isLazyPointer(value)) return false;
293
+ return Object.keys(value).length === 0;
294
+ }
284
295
  function splitContextValue(value) {
285
296
  if (isRichEnvelope(value) || isLazyPointer(value)) {
286
297
  const { content = null, ...overrides } = value;
@@ -424,6 +424,14 @@ declare const RICH_ENVELOPE_KEYS: ReadonlySet<string>;
424
424
  * (a note `{ id, title, content }`) is raw content, not an envelope.
425
425
  */
426
426
  declare function isRichEnvelope(value: unknown): value is Record<string, unknown>;
427
+ /**
428
+ * True for a value with NOTHING to send: absent, `null`, a blank string, an empty list or an
429
+ * empty object — or a rich envelope whose `content` is one of those and that names no `source`
430
+ * for the server to read. Such a value is not a row (live walk 2026-10-23: Side Chat listed five
431
+ * included 0-character rows — Current selection, Text before/after selection, Primary content,
432
+ * Custom fields — and counted them). A directive the server acts on by shape is never "nothing".
433
+ */
434
+ declare function hasNothingToSend(value: unknown): boolean;
427
435
  /**
428
436
  * Split one wire value into `{ content, overrides }` exactly as aidream
429
437
  * `_split_rich_context_value`: a rich envelope or lazy pointer → its `content`
@@ -604,5 +612,5 @@ declare function attachmentContextKey(provider: string, resourceRef: string): st
604
612
  /** Compact size for a tabular column: `950`, `18.4k`, `184k`, `1.2M`, `—` for unknown. */
605
613
  declare function formatChars(n: number | null | undefined): string;
606
614
 
607
- export { CONTEXT_FETCHABLE_ROWS, CONTEXT_ROW_BLOCKS, CONTEXT_RULES_FEATURE, CONVERSATION_DOCUMENT_CONTEXT_KEYS, CONVERSATION_SCRATCHPAD_PREFIX, DEFAULT_INLINE_CAP, DEFAULT_INLINE_MAX_CHARS, DEFAULT_SURFACE_KEY, LAZY_SOURCE_DEFAULT_MAX, OWN_CONVERSATION_WITHHELD, PAGE_OFF_WITHHELD, PERSON_CONTEXT_VALUES, RESERVED_CONSUMED_KEYS, RICH_ENVELOPE_KEYS, SERVER_AUTHORITATIVE_KEYS, applyReceiptToRows, attachmentContextKey, blocksForRow, buildContextWire, compareReceipt, contextValueChars, deliveredFields, formatChars, isRichEnvelope, isServerAuthoritativeKey, isServerResolved, isWireDirective, lookupSavedRule, lookupSavedRuleFor, neverThePage, pageContextWithheldKeys, pageContextWithholds, receiptRowToResolved, resolveContextRow, resolveContextRule, serverDefaultMax, splitContextValue, systemRowsToResolved, unclaimedBlocks, withheldKeys };
615
+ export { CONTEXT_FETCHABLE_ROWS, CONTEXT_ROW_BLOCKS, CONTEXT_RULES_FEATURE, CONVERSATION_DOCUMENT_CONTEXT_KEYS, CONVERSATION_SCRATCHPAD_PREFIX, DEFAULT_INLINE_CAP, DEFAULT_INLINE_MAX_CHARS, DEFAULT_SURFACE_KEY, LAZY_SOURCE_DEFAULT_MAX, OWN_CONVERSATION_WITHHELD, PAGE_OFF_WITHHELD, PERSON_CONTEXT_VALUES, RESERVED_CONSUMED_KEYS, RICH_ENVELOPE_KEYS, SERVER_AUTHORITATIVE_KEYS, applyReceiptToRows, attachmentContextKey, blocksForRow, buildContextWire, compareReceipt, contextValueChars, deliveredFields, formatChars, hasNothingToSend, isRichEnvelope, isServerAuthoritativeKey, isServerResolved, isWireDirective, lookupSavedRule, lookupSavedRuleFor, neverThePage, pageContextWithheldKeys, pageContextWithholds, receiptRowToResolved, resolveContextRow, resolveContextRule, serverDefaultMax, splitContextValue, systemRowsToResolved, unclaimedBlocks, withheldKeys };
608
616
  export type { ContextAgentLayer, ContextBlockedBy, ContextConsumedAs, ContextDeliveredRef, ContextDelivery, ContextLayer, ContextReceipt, ContextReceiptBlock, ContextReceiptMismatch, ContextReceiptRow, ContextRowDelivery, ContextRowOrigin, ContextRowSource, ContextRuleInput, ContextRuleLayers, ContextRuleResult, ContextSurfaceLayer, ContextViewKind, ContextViewLoader, ContextViewTarget, ContextViewedText, PageContextDirective, PageContextMode, PageContextValueFacts, ResolvedContextRow, SavedContextRule, SavedContextRuleRows };
@@ -424,6 +424,14 @@ declare const RICH_ENVELOPE_KEYS: ReadonlySet<string>;
424
424
  * (a note `{ id, title, content }`) is raw content, not an envelope.
425
425
  */
426
426
  declare function isRichEnvelope(value: unknown): value is Record<string, unknown>;
427
+ /**
428
+ * True for a value with NOTHING to send: absent, `null`, a blank string, an empty list or an
429
+ * empty object — or a rich envelope whose `content` is one of those and that names no `source`
430
+ * for the server to read. Such a value is not a row (live walk 2026-10-23: Side Chat listed five
431
+ * included 0-character rows — Current selection, Text before/after selection, Primary content,
432
+ * Custom fields — and counted them). A directive the server acts on by shape is never "nothing".
433
+ */
434
+ declare function hasNothingToSend(value: unknown): boolean;
427
435
  /**
428
436
  * Split one wire value into `{ content, overrides }` exactly as aidream
429
437
  * `_split_rich_context_value`: a rich envelope or lazy pointer → its `content`
@@ -604,5 +612,5 @@ declare function attachmentContextKey(provider: string, resourceRef: string): st
604
612
  /** Compact size for a tabular column: `950`, `18.4k`, `184k`, `1.2M`, `—` for unknown. */
605
613
  declare function formatChars(n: number | null | undefined): string;
606
614
 
607
- export { CONTEXT_FETCHABLE_ROWS, CONTEXT_ROW_BLOCKS, CONTEXT_RULES_FEATURE, CONVERSATION_DOCUMENT_CONTEXT_KEYS, CONVERSATION_SCRATCHPAD_PREFIX, DEFAULT_INLINE_CAP, DEFAULT_INLINE_MAX_CHARS, DEFAULT_SURFACE_KEY, LAZY_SOURCE_DEFAULT_MAX, OWN_CONVERSATION_WITHHELD, PAGE_OFF_WITHHELD, PERSON_CONTEXT_VALUES, RESERVED_CONSUMED_KEYS, RICH_ENVELOPE_KEYS, SERVER_AUTHORITATIVE_KEYS, applyReceiptToRows, attachmentContextKey, blocksForRow, buildContextWire, compareReceipt, contextValueChars, deliveredFields, formatChars, isRichEnvelope, isServerAuthoritativeKey, isServerResolved, isWireDirective, lookupSavedRule, lookupSavedRuleFor, neverThePage, pageContextWithheldKeys, pageContextWithholds, receiptRowToResolved, resolveContextRow, resolveContextRule, serverDefaultMax, splitContextValue, systemRowsToResolved, unclaimedBlocks, withheldKeys };
615
+ export { CONTEXT_FETCHABLE_ROWS, CONTEXT_ROW_BLOCKS, CONTEXT_RULES_FEATURE, CONVERSATION_DOCUMENT_CONTEXT_KEYS, CONVERSATION_SCRATCHPAD_PREFIX, DEFAULT_INLINE_CAP, DEFAULT_INLINE_MAX_CHARS, DEFAULT_SURFACE_KEY, LAZY_SOURCE_DEFAULT_MAX, OWN_CONVERSATION_WITHHELD, PAGE_OFF_WITHHELD, PERSON_CONTEXT_VALUES, RESERVED_CONSUMED_KEYS, RICH_ENVELOPE_KEYS, SERVER_AUTHORITATIVE_KEYS, applyReceiptToRows, attachmentContextKey, blocksForRow, buildContextWire, compareReceipt, contextValueChars, deliveredFields, formatChars, hasNothingToSend, isRichEnvelope, isServerAuthoritativeKey, isServerResolved, isWireDirective, lookupSavedRule, lookupSavedRuleFor, neverThePage, pageContextWithheldKeys, pageContextWithholds, receiptRowToResolved, resolveContextRow, resolveContextRule, serverDefaultMax, splitContextValue, systemRowsToResolved, unclaimedBlocks, withheldKeys };
608
616
  export type { ContextAgentLayer, ContextBlockedBy, ContextConsumedAs, ContextDeliveredRef, ContextDelivery, ContextLayer, ContextReceipt, ContextReceiptBlock, ContextReceiptMismatch, ContextReceiptRow, ContextRowDelivery, ContextRowOrigin, ContextRowSource, ContextRuleInput, ContextRuleLayers, ContextRuleResult, ContextSurfaceLayer, ContextViewKind, ContextViewLoader, ContextViewTarget, ContextViewedText, PageContextDirective, PageContextMode, PageContextValueFacts, ResolvedContextRow, SavedContextRule, SavedContextRuleRows };
@@ -218,6 +218,16 @@ function isRichEnvelope(value) {
218
218
  function isLazyPointer(value) {
219
219
  return isPlainObject(value) && !hasOwn(value, "content") && onlyRichKeys(value) && hasLazySource(value);
220
220
  }
221
+ function hasNothingToSend(value) {
222
+ if (value === void 0 || value === null) return true;
223
+ if (typeof value === "string") return value.trim() === "";
224
+ if (Array.isArray(value)) return value.length === 0;
225
+ if (!isPlainObject(value)) return false;
226
+ if (value.__kind !== void 0) return false;
227
+ if (isRichEnvelope(value)) return !hasLazySource(value) && hasNothingToSend(value.content);
228
+ if (isLazyPointer(value)) return false;
229
+ return Object.keys(value).length === 0;
230
+ }
221
231
  function splitContextValue(value) {
222
232
  if (isRichEnvelope(value) || isLazyPointer(value)) {
223
233
  const { content = null, ...overrides } = value;
@@ -506,6 +516,7 @@ export {
506
516
  contextValueChars,
507
517
  deliveredFields,
508
518
  formatChars,
519
+ hasNothingToSend,
509
520
  isRichEnvelope,
510
521
  isServerAuthoritativeKey,
511
522
  isServerResolved,
@@ -216,7 +216,18 @@ function mergeLevels(a, b) {
216
216
  ref: { ...a.ref, order: Math.min(a.ref.order ?? 0, b.ref.order ?? 0) },
217
217
  rows: [...a.rows, ...b.rows],
218
218
  groups,
219
- master: a.master ?? b.master
219
+ master: mergeMasters(a.master, b.master)
220
+ };
221
+ }
222
+ function mergeMasters(a, b) {
223
+ if (!a || !b) return a ?? b;
224
+ return {
225
+ level: a.level,
226
+ on: a.on || b.on,
227
+ onToggle: (next) => {
228
+ a.onToggle?.(next);
229
+ b.onToggle?.(next);
230
+ }
220
231
  };
221
232
  }
222
233
  function buildContextTree(levels) {
@@ -365,6 +376,9 @@ function offByDefaultReason(row) {
365
376
  if (row.include || row.decided_by.include !== "page") return null;
366
377
  return row.layers?.surface?.auto_context === false ? "Off by default on this page" : null;
367
378
  }
379
+ function deliveredTextForPerson(text) {
380
+ return text.replace(/<object\b[^>]*>/g, (tag) => tag.replace(/\s+key="[^"]*"/g, ""));
381
+ }
368
382
 
369
383
  // context/react/InlineMaxInput.tsx
370
384
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -882,6 +896,7 @@ var import_icons7 = require("@ai-matrx/design-system/icons");
882
896
  var import_jsx_runtime4 = require("react/jsx-runtime");
883
897
  var BLIND_TOOLTIP = "Not sent to this model";
884
898
  var BLIND_LABEL = "Not read";
899
+ var PENDING_LABEL = "Included values";
885
900
  function IconButton({
886
901
  label,
887
902
  onClick,
@@ -923,6 +938,7 @@ function ContextRulesChip({
923
938
  open: openProp,
924
939
  onOpenChange,
925
940
  pressed,
941
+ countPending = false,
926
942
  className,
927
943
  variant = "outline"
928
944
  }) {
@@ -934,7 +950,7 @@ function ContextRulesChip({
934
950
  };
935
951
  const { count, charsLabel } = summarizeContextRows(rows);
936
952
  const name = label?.trim() ?? "";
937
- const faceName = name ? `${name} \xB7 ${count} included` : `${count} included`;
953
+ const faceName = countPending ? name || PENDING_LABEL : name ? `${name} \xB7 ${count} included` : `${count} included`;
938
954
  const anyOverride = rows.some(hasOverride);
939
955
  const blind = !modelReadsContext;
940
956
  const comfortable = !!isMobile;
@@ -953,7 +969,7 @@ function ContextRulesChip({
953
969
  icon: eyeOpen ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EyeIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons7.EyeOffIcon, {}),
954
970
  ...isMobile ? { onClick: () => setOpen(true) } : {},
955
971
  className: (0, import_design_system4.cn)("min-w-0", className),
956
- children: `${name ? `${name} \xB7 ` : ""}${count}`
972
+ children: countPending ? name || null : `${name ? `${name} \xB7 ` : ""}${count}`
957
973
  }
958
974
  );
959
975
  const faceTip = blind ? BLIND_TOOLTIP : name ? null : faceName;
@@ -979,7 +995,7 @@ function ContextRulesChip({
979
995
  children: [
980
996
  eyeOpen ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EyeIcon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons7.EyeOffIcon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
981
997
  headerName ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "min-w-0 truncate text-sm font-medium", children: headerName }) : null,
982
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: `${count} \xB7 ${charsLabel} chars` }),
998
+ countPending ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: `${count} \xB7 ${charsLabel} chars` }),
983
999
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-auto flex shrink-0 items-center gap-0.5", children: [
984
1000
  blind ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mr-1 text-xs text-muted-foreground", children: BLIND_LABEL }) : null,
985
1001
  canMaster ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -1009,7 +1025,7 @@ function ContextRulesChip({
1009
1025
  ]
1010
1026
  }
1011
1027
  ),
1012
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: (0, import_design_system4.cn)("min-h-0 overflow-y-auto", comfortable ? "max-h-[70dvh]" : "max-h-[min(24rem,60vh)]"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1028
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: (0, import_design_system4.cn)("min-h-0 overflow-y-auto", comfortable ? "max-h-[70dvh]" : "max-h-[min(24rem,60vh)]"), children: countPending ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { "data-testid": "context-rules-pending", role: "status", "aria-busy": "true", className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system4.Skeleton, { className: "h-16 w-full" }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1013
1029
  ContextRulesTable,
1014
1030
  {
1015
1031
  rows,
@@ -1182,7 +1198,7 @@ function DeliveredSection({
1182
1198
  "whitespace-pre-wrap break-words rounded border border-border",
1183
1199
  "bg-muted/40 p-2 font-mono text-[11px] text-foreground"
1184
1200
  ),
1185
- children: loaded.text
1201
+ children: deliveredTextForPerson(loaded.text)
1186
1202
  }
1187
1203
  )
1188
1204
  ] });
@@ -364,6 +364,13 @@ interface ContextRulesChipProps {
364
364
  * Omitted: the chip is a plain popover trigger, no pressed state.
365
365
  */
366
366
  pressed?: boolean | undefined;
367
+ /**
368
+ * True while what decides INCLUSION (the person's saved rules, a kill switch) has not answered:
369
+ * the face shows its eye and no number, and the opened surface shows no count and no switches
370
+ * yet — never a number that changes when it is opened (live walk 2026-10-23: 5 on the face, 3
371
+ * in the popover). Omitted: the rows are final.
372
+ */
373
+ countPending?: boolean | undefined;
367
374
  /** The face's skin: `outline` (default) or `quiet` (a composer row). */
368
375
  variant?: "outline" | "quiet";
369
376
  /** Placement only. */
@@ -374,7 +381,7 @@ interface ContextRulesChipProps {
374
381
  * "N · chars" summary, page master switch, reset-all, full view) over the
375
382
  * compact rules table. Popover on desktop, bottom sheet on mobile.
376
383
  */
377
- declare function ContextRulesChip({ label, rows, cap, on, onToggleAll, hierarchy, onSetInclude, onChange, onResetAll, onOpenFullView, modelReadsContext, onOpenRow, isMobile, readOnly, open: openProp, onOpenChange, pressed, className, variant, }: ContextRulesChipProps): React.JSX.Element;
384
+ declare function ContextRulesChip({ label, rows, cap, on, onToggleAll, hierarchy, onSetInclude, onChange, onResetAll, onOpenFullView, modelReadsContext, onOpenRow, isMobile, readOnly, open: openProp, onOpenChange, pressed, countPending, className, variant, }: ContextRulesChipProps): React.JSX.Element;
378
385
 
379
386
  interface ContextRulesPanelBodyProps {
380
387
  rows: readonly ResolvedContextRow[];
@@ -364,6 +364,13 @@ interface ContextRulesChipProps {
364
364
  * Omitted: the chip is a plain popover trigger, no pressed state.
365
365
  */
366
366
  pressed?: boolean | undefined;
367
+ /**
368
+ * True while what decides INCLUSION (the person's saved rules, a kill switch) has not answered:
369
+ * the face shows its eye and no number, and the opened surface shows no count and no switches
370
+ * yet — never a number that changes when it is opened (live walk 2026-10-23: 5 on the face, 3
371
+ * in the popover). Omitted: the rows are final.
372
+ */
373
+ countPending?: boolean | undefined;
367
374
  /** The face's skin: `outline` (default) or `quiet` (a composer row). */
368
375
  variant?: "outline" | "quiet";
369
376
  /** Placement only. */
@@ -374,7 +381,7 @@ interface ContextRulesChipProps {
374
381
  * "N · chars" summary, page master switch, reset-all, full view) over the
375
382
  * compact rules table. Popover on desktop, bottom sheet on mobile.
376
383
  */
377
- declare function ContextRulesChip({ label, rows, cap, on, onToggleAll, hierarchy, onSetInclude, onChange, onResetAll, onOpenFullView, modelReadsContext, onOpenRow, isMobile, readOnly, open: openProp, onOpenChange, pressed, className, variant, }: ContextRulesChipProps): React.JSX.Element;
384
+ declare function ContextRulesChip({ label, rows, cap, on, onToggleAll, hierarchy, onSetInclude, onChange, onResetAll, onOpenFullView, modelReadsContext, onOpenRow, isMobile, readOnly, open: openProp, onOpenChange, pressed, countPending, className, variant, }: ContextRulesChipProps): React.JSX.Element;
378
385
 
379
386
  interface ContextRulesPanelBodyProps {
380
387
  rows: readonly ResolvedContextRow[];
@@ -178,7 +178,18 @@ function mergeLevels(a, b) {
178
178
  ref: { ...a.ref, order: Math.min(a.ref.order ?? 0, b.ref.order ?? 0) },
179
179
  rows: [...a.rows, ...b.rows],
180
180
  groups,
181
- master: a.master ?? b.master
181
+ master: mergeMasters(a.master, b.master)
182
+ };
183
+ }
184
+ function mergeMasters(a, b) {
185
+ if (!a || !b) return a ?? b;
186
+ return {
187
+ level: a.level,
188
+ on: a.on || b.on,
189
+ onToggle: (next) => {
190
+ a.onToggle?.(next);
191
+ b.onToggle?.(next);
192
+ }
182
193
  };
183
194
  }
184
195
  function buildContextTree(levels) {
@@ -333,6 +344,9 @@ function offByDefaultReason(row) {
333
344
  if (row.include || row.decided_by.include !== "page") return null;
334
345
  return row.layers?.surface?.auto_context === false ? "Off by default on this page" : null;
335
346
  }
347
+ function deliveredTextForPerson(text) {
348
+ return text.replace(/<object\b[^>]*>/g, (tag) => tag.replace(/\s+key="[^"]*"/g, ""));
349
+ }
336
350
 
337
351
  // context/react/InlineMaxInput.tsx
338
352
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -848,6 +862,7 @@ import { Button } from "@ai-matrx/design-system/controls";
848
862
  import {
849
863
  BottomSheet,
850
864
  Popover as Popover2,
865
+ Skeleton,
851
866
  PopoverContent as PopoverContent2,
852
867
  PopoverTrigger as PopoverTrigger2,
853
868
  Switch as Switch2,
@@ -861,6 +876,7 @@ import { EyeOffIcon, PanelRightIcon } from "@ai-matrx/design-system/icons";
861
876
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
862
877
  var BLIND_TOOLTIP = "Not sent to this model";
863
878
  var BLIND_LABEL = "Not read";
879
+ var PENDING_LABEL = "Included values";
864
880
  function IconButton({
865
881
  label,
866
882
  onClick,
@@ -902,6 +918,7 @@ function ContextRulesChip({
902
918
  open: openProp,
903
919
  onOpenChange,
904
920
  pressed,
921
+ countPending = false,
905
922
  className,
906
923
  variant = "outline"
907
924
  }) {
@@ -913,7 +930,7 @@ function ContextRulesChip({
913
930
  };
914
931
  const { count, charsLabel } = summarizeContextRows(rows);
915
932
  const name = label?.trim() ?? "";
916
- const faceName = name ? `${name} \xB7 ${count} included` : `${count} included`;
933
+ const faceName = countPending ? name || PENDING_LABEL : name ? `${name} \xB7 ${count} included` : `${count} included`;
917
934
  const anyOverride = rows.some(hasOverride);
918
935
  const blind = !modelReadsContext;
919
936
  const comfortable = !!isMobile;
@@ -932,7 +949,7 @@ function ContextRulesChip({
932
949
  icon: eyeOpen ? /* @__PURE__ */ jsx4(EyeIcon, {}) : /* @__PURE__ */ jsx4(EyeOffIcon, {}),
933
950
  ...isMobile ? { onClick: () => setOpen(true) } : {},
934
951
  className: cn4("min-w-0", className),
935
- children: `${name ? `${name} \xB7 ` : ""}${count}`
952
+ children: countPending ? name || null : `${name ? `${name} \xB7 ` : ""}${count}`
936
953
  }
937
954
  );
938
955
  const faceTip = blind ? BLIND_TOOLTIP : name ? null : faceName;
@@ -958,7 +975,7 @@ function ContextRulesChip({
958
975
  children: [
959
976
  eyeOpen ? /* @__PURE__ */ jsx4(EyeIcon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ jsx4(EyeOffIcon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
960
977
  headerName ? /* @__PURE__ */ jsx4("span", { className: "min-w-0 truncate text-sm font-medium", children: headerName }) : null,
961
- /* @__PURE__ */ jsx4("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: `${count} \xB7 ${charsLabel} chars` }),
978
+ countPending ? null : /* @__PURE__ */ jsx4("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: `${count} \xB7 ${charsLabel} chars` }),
962
979
  /* @__PURE__ */ jsxs4("div", { className: "ml-auto flex shrink-0 items-center gap-0.5", children: [
963
980
  blind ? /* @__PURE__ */ jsx4("span", { className: "mr-1 text-xs text-muted-foreground", children: BLIND_LABEL }) : null,
964
981
  canMaster ? /* @__PURE__ */ jsx4(
@@ -988,7 +1005,7 @@ function ContextRulesChip({
988
1005
  ]
989
1006
  }
990
1007
  ),
991
- /* @__PURE__ */ jsx4("div", { className: cn4("min-h-0 overflow-y-auto", comfortable ? "max-h-[70dvh]" : "max-h-[min(24rem,60vh)]"), children: /* @__PURE__ */ jsx4(
1008
+ /* @__PURE__ */ jsx4("div", { className: cn4("min-h-0 overflow-y-auto", comfortable ? "max-h-[70dvh]" : "max-h-[min(24rem,60vh)]"), children: countPending ? /* @__PURE__ */ jsx4("div", { "data-testid": "context-rules-pending", role: "status", "aria-busy": "true", className: "p-3", children: /* @__PURE__ */ jsx4(Skeleton, { className: "h-16 w-full" }) }) : /* @__PURE__ */ jsx4(
992
1009
  ContextRulesTable,
993
1010
  {
994
1011
  rows,
@@ -1035,7 +1052,7 @@ import { ChevronLeftIcon, SearchIcon } from "@ai-matrx/design-system/icons";
1035
1052
 
1036
1053
  // context/react/ContextDeliveredValue.tsx
1037
1054
  import * as React4 from "react";
1038
- import { Skeleton, cn as cn5 } from "@ai-matrx/design-system";
1055
+ import { Skeleton as Skeleton2, cn as cn5 } from "@ai-matrx/design-system";
1039
1056
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1040
1057
  function ContextDeliveredValue({
1041
1058
  row,
@@ -1143,7 +1160,7 @@ function DeliveredSection({
1143
1160
  }
1144
1161
  ) : null
1145
1162
  ] }),
1146
- unavailable ? null : !load ? /* @__PURE__ */ jsx5("span", { className: "text-xs text-muted-foreground", children: "\u2014" }) : loaded.state === "loading" ? /* @__PURE__ */ jsx5(Skeleton, { "data-testid": "context-delivered-loading", className: "h-16 w-full" }) : loaded.state === "error" ? (
1163
+ unavailable ? null : !load ? /* @__PURE__ */ jsx5("span", { className: "text-xs text-muted-foreground", children: "\u2014" }) : loaded.state === "loading" ? /* @__PURE__ */ jsx5(Skeleton2, { "data-testid": "context-delivered-loading", className: "h-16 w-full" }) : loaded.state === "error" ? (
1147
1164
  // Calm and one line: the server's words never reach the person (the host's loader files the error).
1148
1165
  /* @__PURE__ */ jsxs5("span", { "data-testid": "context-delivered-unavailable", className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
1149
1166
  /* @__PURE__ */ jsx5("span", { className: "min-w-0 truncate", children: "Text not kept for this message" }),
@@ -1166,7 +1183,7 @@ function DeliveredSection({
1166
1183
  "whitespace-pre-wrap break-words rounded border border-border",
1167
1184
  "bg-muted/40 p-2 font-mono text-[11px] text-foreground"
1168
1185
  ),
1169
- children: loaded.text
1186
+ children: deliveredTextForPerson(loaded.text)
1170
1187
  }
1171
1188
  )
1172
1189
  ] });