@invergent/agent-chat-react 2.7.9 → 2.8.1

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.d.cts CHANGED
@@ -953,6 +953,16 @@ interface AgentChatProps {
953
953
  * Like `deepResearchEnabled`, the host owns the capability gate.
954
954
  */
955
955
  codeAgentsEnabled?: boolean;
956
+ /**
957
+ * Slash-command capability group (per-agent). These gate the always-on
958
+ * lightweight builtins and default to shown when omitted, so a host that
959
+ * hasn't wired them keeps the current menu. `/clear` has no flag and is
960
+ * always available; the host owns the capability gate.
961
+ */
962
+ loopsEnabled?: boolean;
963
+ missionsEnabled?: boolean;
964
+ goalsEnabled?: boolean;
965
+ compressEnabled?: boolean;
956
966
  /**
957
967
  * Called when the user clicks the integrations band under the composer.
958
968
  * Hosts navigate to their Integrations route. When omitted, the band is
@@ -967,7 +977,7 @@ interface AgentChatProps {
967
977
  */
968
978
  onOpenBilling?: () => void;
969
979
  }
970
- declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, deepResearchEnabled, researchEnabled, codeAgentsEnabled, onOpenIntegrations, onOpenBilling, }: AgentChatProps): react_jsx_runtime.JSX.Element;
980
+ declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, deepResearchEnabled, researchEnabled, codeAgentsEnabled, loopsEnabled, missionsEnabled, goalsEnabled, compressEnabled, onOpenIntegrations, onOpenBilling, }: AgentChatProps): react_jsx_runtime.JSX.Element;
971
981
 
972
982
  interface AgentChatAdapterContextValue {
973
983
  adapter: AgentChatAdapter;
@@ -1255,6 +1265,10 @@ declare function ScheduledWorkPanel({ adapter, agentId, title, limit, status, hi
1255
1265
  interface SessionTreePanelProps {
1256
1266
  adapter: AgentChatAdapter;
1257
1267
  sessionId?: string | null;
1268
+ /**
1269
+ * ID of the currently highlighted session. Defaults to `sessionId`.
1270
+ * Pass `""` (empty string) to clear the active highlight when `sessionId` is set.
1271
+ */
1258
1272
  activeSessionId?: string;
1259
1273
  agentId?: string;
1260
1274
  title?: string;
package/dist/index.d.ts CHANGED
@@ -953,6 +953,16 @@ interface AgentChatProps {
953
953
  * Like `deepResearchEnabled`, the host owns the capability gate.
954
954
  */
955
955
  codeAgentsEnabled?: boolean;
956
+ /**
957
+ * Slash-command capability group (per-agent). These gate the always-on
958
+ * lightweight builtins and default to shown when omitted, so a host that
959
+ * hasn't wired them keeps the current menu. `/clear` has no flag and is
960
+ * always available; the host owns the capability gate.
961
+ */
962
+ loopsEnabled?: boolean;
963
+ missionsEnabled?: boolean;
964
+ goalsEnabled?: boolean;
965
+ compressEnabled?: boolean;
956
966
  /**
957
967
  * Called when the user clicks the integrations band under the composer.
958
968
  * Hosts navigate to their Integrations route. When omitted, the band is
@@ -967,7 +977,7 @@ interface AgentChatProps {
967
977
  */
968
978
  onOpenBilling?: () => void;
969
979
  }
970
- declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, deepResearchEnabled, researchEnabled, codeAgentsEnabled, onOpenIntegrations, onOpenBilling, }: AgentChatProps): react_jsx_runtime.JSX.Element;
980
+ declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, deepResearchEnabled, researchEnabled, codeAgentsEnabled, loopsEnabled, missionsEnabled, goalsEnabled, compressEnabled, onOpenIntegrations, onOpenBilling, }: AgentChatProps): react_jsx_runtime.JSX.Element;
971
981
 
972
982
  interface AgentChatAdapterContextValue {
973
983
  adapter: AgentChatAdapter;
@@ -1255,6 +1265,10 @@ declare function ScheduledWorkPanel({ adapter, agentId, title, limit, status, hi
1255
1265
  interface SessionTreePanelProps {
1256
1266
  adapter: AgentChatAdapter;
1257
1267
  sessionId?: string | null;
1268
+ /**
1269
+ * ID of the currently highlighted session. Defaults to `sessionId`.
1270
+ * Pass `""` (empty string) to clear the active highlight when `sessionId` is set.
1271
+ */
1258
1272
  activeSessionId?: string;
1259
1273
  agentId?: string;
1260
1274
  title?: string;
package/dist/index.js CHANGED
@@ -6160,6 +6160,10 @@ function ChatComposerInner({
6160
6160
  deepResearchEnabled = false,
6161
6161
  researchEnabled = false,
6162
6162
  codeAgentsEnabled = false,
6163
+ loopsEnabled = true,
6164
+ missionsEnabled = true,
6165
+ goalsEnabled = true,
6166
+ compressEnabled = true,
6163
6167
  viewMode = "simple",
6164
6168
  onViewModeChange
6165
6169
  }) {
@@ -6206,22 +6210,38 @@ function ChatComposerInner({
6206
6210
  const builtinCommands = useMemo(
6207
6211
  () => {
6208
6212
  const base = [
6209
- { value: "/clear", label: "/clear", description: "Clear conversation" },
6210
- { value: "/compress", label: "/compress", description: "Compress context" },
6211
- { value: "/goal", label: "/goal", description: "Define an outcome goal" },
6212
- { value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
6213
- { value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
6214
- { value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
6215
- { value: "/goal clear", label: "/goal clear", description: "Clear the current goal" },
6216
- { value: "/mission ", label: "/mission", description: "Start an orchestrated rubric-judged mission" },
6217
- { value: "/mission status", label: "/mission status", description: "Show current mission status" },
6218
- { value: "/mission pause", label: "/mission pause", description: "Pause the mission evaluator" },
6219
- { value: "/mission resume", label: "/mission resume", description: "Resume a paused mission" },
6220
- { value: "/mission cancel", label: "/mission cancel", description: "Cancel the mission" },
6221
- { value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
6222
- { value: "/loop list", label: "/loop list", description: "List active loops" },
6223
- { value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
6213
+ { value: "/clear", label: "/clear", description: "Clear conversation" }
6224
6214
  ];
6215
+ if (compressEnabled) {
6216
+ base.push(
6217
+ { value: "/compress", label: "/compress", description: "Compress context" }
6218
+ );
6219
+ }
6220
+ if (goalsEnabled) {
6221
+ base.push(
6222
+ { value: "/goal", label: "/goal", description: "Define an outcome goal" },
6223
+ { value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
6224
+ { value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
6225
+ { value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
6226
+ { value: "/goal clear", label: "/goal clear", description: "Clear the current goal" }
6227
+ );
6228
+ }
6229
+ if (missionsEnabled) {
6230
+ base.push(
6231
+ { value: "/mission ", label: "/mission", description: "Start an orchestrated rubric-judged mission" },
6232
+ { value: "/mission status", label: "/mission status", description: "Show current mission status" },
6233
+ { value: "/mission pause", label: "/mission pause", description: "Pause the mission evaluator" },
6234
+ { value: "/mission resume", label: "/mission resume", description: "Resume a paused mission" },
6235
+ { value: "/mission cancel", label: "/mission cancel", description: "Cancel the mission" }
6236
+ );
6237
+ }
6238
+ if (loopsEnabled) {
6239
+ base.push(
6240
+ { value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
6241
+ { value: "/loop list", label: "/loop list", description: "List active loops" },
6242
+ { value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
6243
+ );
6244
+ }
6225
6245
  if (deepResearchEnabled) {
6226
6246
  base.push({
6227
6247
  value: "/deep-research ",
@@ -6247,7 +6267,15 @@ function ChatComposerInner({
6247
6267
  }
6248
6268
  return base;
6249
6269
  },
6250
- [deepResearchEnabled, researchEnabled, codeAgentsEnabled]
6270
+ [
6271
+ compressEnabled,
6272
+ goalsEnabled,
6273
+ missionsEnabled,
6274
+ loopsEnabled,
6275
+ deepResearchEnabled,
6276
+ researchEnabled,
6277
+ codeAgentsEnabled
6278
+ ]
6251
6279
  );
6252
6280
  const scheduledExamples = useMemo(
6253
6281
  () => [
@@ -6405,7 +6433,7 @@ function ChatComposerInner({
6405
6433
  ]
6406
6434
  }
6407
6435
  ),
6408
- /* @__PURE__ */ jsxs(
6436
+ loopsEnabled && /* @__PURE__ */ jsxs(
6409
6437
  Button,
6410
6438
  {
6411
6439
  type: "button",
@@ -9790,6 +9818,10 @@ function ChatThread({
9790
9818
  deepResearchEnabled = false,
9791
9819
  researchEnabled = false,
9792
9820
  codeAgentsEnabled = false,
9821
+ loopsEnabled = true,
9822
+ missionsEnabled = true,
9823
+ goalsEnabled = true,
9824
+ compressEnabled = true,
9793
9825
  researchSources = [],
9794
9826
  hideTurnSummary = false,
9795
9827
  agentId,
@@ -9856,7 +9888,11 @@ function ChatThread({
9856
9888
  onViewModeChange,
9857
9889
  deepResearchEnabled,
9858
9890
  researchEnabled,
9859
- codeAgentsEnabled
9891
+ codeAgentsEnabled,
9892
+ loopsEnabled,
9893
+ missionsEnabled,
9894
+ goalsEnabled,
9895
+ compressEnabled
9860
9896
  }
9861
9897
  ),
9862
9898
  onOpenIntegrations && /* @__PURE__ */ jsx(
@@ -12358,6 +12394,10 @@ function AgentChat({
12358
12394
  deepResearchEnabled = false,
12359
12395
  researchEnabled = false,
12360
12396
  codeAgentsEnabled = false,
12397
+ loopsEnabled = true,
12398
+ missionsEnabled = true,
12399
+ goalsEnabled = true,
12400
+ compressEnabled = true,
12361
12401
  onOpenIntegrations,
12362
12402
  onOpenBilling
12363
12403
  }) {
@@ -12511,6 +12551,10 @@ function AgentChat({
12511
12551
  deepResearchEnabled,
12512
12552
  researchEnabled,
12513
12553
  codeAgentsEnabled,
12554
+ loopsEnabled,
12555
+ missionsEnabled,
12556
+ goalsEnabled,
12557
+ compressEnabled,
12514
12558
  researchSources: runtime.researchSources,
12515
12559
  hideTurnSummary,
12516
12560
  agentId,
@@ -16038,10 +16082,20 @@ function fallbackSessionTitle(entry) {
16038
16082
  if (entry.runKind === "scheduled") return "Scheduled run";
16039
16083
  return "New session";
16040
16084
  }
16085
+ function rowStateClass(isActive, isInActiveGroup) {
16086
+ if (isActive) {
16087
+ return "bg-faint/30 dark:bg-[#1e2840] text-foreground border-l-primary";
16088
+ }
16089
+ if (isInActiveGroup) {
16090
+ return "bg-line/70 dark:bg-line/60 text-foreground/80 hover:bg-input hover:text-foreground border-l-transparent";
16091
+ }
16092
+ return "bg-transparent text-foreground/80 hover:bg-input hover:text-foreground border-l-transparent";
16093
+ }
16041
16094
  function TreeNodeRow({
16042
16095
  entry,
16043
16096
  depth,
16044
16097
  activeSessionId,
16098
+ activeGroupRootId,
16045
16099
  canStop,
16046
16100
  canDelete,
16047
16101
  onSelect,
@@ -16053,11 +16107,15 @@ function TreeNodeRow({
16053
16107
  const isActive = entry.id === activeSessionId;
16054
16108
  const isRunning = entry.status === "active";
16055
16109
  const isChildSession = entry.parentId != null;
16110
+ const isInActiveGroup = activeGroupRootId !== null && (entry.id === activeGroupRootId || entry.parentId === activeGroupRootId);
16056
16111
  const title = entry.title ?? fallbackSessionTitle(entry);
16057
16112
  const subtitle = [
16058
16113
  formatRunKind(entry.runKind),
16059
16114
  formatSessionTime(entry.updatedAt)
16060
16115
  ].filter(Boolean).join(" \xB7 ");
16116
+ useEffect(() => {
16117
+ if (hasChildren) setExpanded(isInActiveGroup);
16118
+ }, [isInActiveGroup, hasChildren]);
16061
16119
  return /* @__PURE__ */ jsxs(Fragment, { children: [
16062
16120
  /* @__PURE__ */ jsxs(
16063
16121
  "div",
@@ -16071,7 +16129,7 @@ function TreeNodeRow({
16071
16129
  className: cn(
16072
16130
  "group flex items-center gap-2 w-full py-2 pr-2 text-left cursor-pointer transition-colors border-l-2",
16073
16131
  "min-h-11 md:min-h-0",
16074
- isActive ? "bg-line text-foreground border-l-primary" : "bg-transparent text-foreground/80 hover:bg-input hover:text-foreground border-l-transparent"
16132
+ rowStateClass(isActive, isInActiveGroup)
16075
16133
  ),
16076
16134
  style: { paddingLeft: `${depth * 12 + 12}px` },
16077
16135
  children: [
@@ -16130,6 +16188,7 @@ function TreeNodeRow({
16130
16188
  entry: child,
16131
16189
  depth: depth + 1,
16132
16190
  activeSessionId,
16191
+ activeGroupRootId,
16133
16192
  canStop,
16134
16193
  canDelete,
16135
16194
  onSelect,
@@ -16246,6 +16305,21 @@ function SessionTreePanel({
16246
16305
  return () => clearInterval(id);
16247
16306
  }, [refetch, runningCount]);
16248
16307
  const roots = useMemo(() => buildTree(nodes), [nodes]);
16308
+ const activeGroupRootId = useMemo(() => {
16309
+ if (!activeSessionId) return null;
16310
+ const parentOf = /* @__PURE__ */ new Map();
16311
+ for (const n of nodes) parentOf.set(n.id, n.parentId ?? null);
16312
+ const visited = /* @__PURE__ */ new Set();
16313
+ let current = activeSessionId;
16314
+ let parent = parentOf.get(current);
16315
+ while (parent != null) {
16316
+ if (visited.has(parent)) break;
16317
+ visited.add(current);
16318
+ current = parent;
16319
+ parent = parentOf.get(current);
16320
+ }
16321
+ return parentOf.has(current) ? current : null;
16322
+ }, [activeSessionId, nodes]);
16249
16323
  const handleSelect = useCallback(
16250
16324
  (id) => {
16251
16325
  onSessionSelect?.(id);
@@ -16309,6 +16383,7 @@ function SessionTreePanel({
16309
16383
  entry,
16310
16384
  depth: 0,
16311
16385
  activeSessionId: activeSessionId ?? "",
16386
+ activeGroupRootId,
16312
16387
  canStop: Boolean(adapter.stopSession),
16313
16388
  canDelete: Boolean(adapter.deleteSession),
16314
16389
  onSelect: handleSelect,