@opengeni/react 0.20.0 → 0.23.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.
Files changed (44) hide show
  1. package/dist/{chunk-6BXBGJ3B.js → chunk-6XUS5VFM.js} +2 -2
  2. package/dist/{chunk-LAZ2A743.js → chunk-CATATY77.js} +3 -3
  3. package/dist/{chunk-HHFA4AFX.js → chunk-I3BJZIG5.js} +15 -1
  4. package/dist/chunk-I3BJZIG5.js.map +1 -0
  5. package/dist/{chunk-6UT5OC3P.js → chunk-UAHPKLB6.js} +113 -9
  6. package/dist/chunk-UAHPKLB6.js.map +1 -0
  7. package/dist/{chunk-MRSECXRP.js → chunk-UQS7OQDE.js} +82 -54
  8. package/dist/chunk-UQS7OQDE.js.map +1 -0
  9. package/dist/{chunk-EBTT3MYN.js → chunk-YDNWMKXO.js} +11 -1
  10. package/dist/chunk-YDNWMKXO.js.map +1 -0
  11. package/dist/{composer-DvUaa5ki.d.ts → composer-CVm5uoUI.d.ts} +2 -2
  12. package/dist/composer.d.ts +3 -3
  13. package/dist/composer.js +3 -3
  14. package/dist/index.d.ts +8 -8
  15. package/dist/index.js +140 -26
  16. package/dist/index.js.map +1 -1
  17. package/dist/machines.d.ts +1 -1
  18. package/dist/machines.js +2 -2
  19. package/dist/{queue-surface-implementation-NQMV2ML3.js → queue-surface-implementation-3UW3MIIR.js} +9 -9
  20. package/dist/queue-surface-implementation-3UW3MIIR.js.map +1 -0
  21. package/dist/{session-Gd4iVPYw.d.ts → session-Db00TRwl.d.ts} +32 -11
  22. package/dist/{session-context-DIFFlXKc.d.ts → session-context-rgrfElMl.d.ts} +7 -1
  23. package/dist/session.d.ts +3 -3
  24. package/dist/session.js +7 -3
  25. package/dist/{use-composer-BCfm4mzX.d.ts → use-composer-By1wn3MM.d.ts} +5 -18
  26. package/package.json +2 -2
  27. package/src/client.ts +4 -0
  28. package/src/components/message-timeline.tsx +195 -23
  29. package/src/components/queue-draft-policy.ts +18 -0
  30. package/src/components/queue-surface-implementation.tsx +6 -10
  31. package/src/components/queue-surface.tsx +1 -0
  32. package/src/hooks/use-composer.ts +128 -78
  33. package/src/hooks/use-session-mcp-approval-policy.ts +161 -0
  34. package/src/index.ts +9 -0
  35. package/src/session-context.ts +25 -0
  36. package/src/session.ts +10 -0
  37. package/src/timeline/types.ts +8 -15
  38. package/dist/chunk-6UT5OC3P.js.map +0 -1
  39. package/dist/chunk-EBTT3MYN.js.map +0 -1
  40. package/dist/chunk-HHFA4AFX.js.map +0 -1
  41. package/dist/chunk-MRSECXRP.js.map +0 -1
  42. package/dist/queue-surface-implementation-NQMV2ML3.js.map +0 -1
  43. /package/dist/{chunk-6BXBGJ3B.js.map → chunk-6XUS5VFM.js.map} +0 -0
  44. /package/dist/{chunk-LAZ2A743.js.map → chunk-CATATY77.js.map} +0 -0
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ import {
36
36
  useChatComposerController,
37
37
  useSlashCommands,
38
38
  useTranscription
39
- } from "./chunk-LAZ2A743.js";
39
+ } from "./chunk-CATATY77.js";
40
40
  import {
41
41
  CONNECTION_STATUS_META,
42
42
  ConnectionDot,
@@ -64,7 +64,7 @@ import {
64
64
  healthPulses,
65
65
  pointsFor,
66
66
  useMachines
67
- } from "./chunk-6BXBGJ3B.js";
67
+ } from "./chunk-6XUS5VFM.js";
68
68
  import {
69
69
  cn
70
70
  } from "./chunk-TK7G6XLT.js";
@@ -82,6 +82,7 @@ import {
82
82
  groupTimeline,
83
83
  humanInputRequestFromEvent,
84
84
  isHumanInputEvent,
85
+ isSessionMcpApprovalPolicyEvent,
85
86
  isTurnQueueEvent,
86
87
  projectPendingApprovals,
87
88
  projectPendingHumanInputRequests,
@@ -90,15 +91,16 @@ import {
90
91
  useHumanInputRequests,
91
92
  useSessionControl,
92
93
  useSessionEvents,
94
+ useSessionMcpApprovalPolicy,
93
95
  useTurnQueue
94
- } from "./chunk-6UT5OC3P.js";
96
+ } from "./chunk-UAHPKLB6.js";
95
97
  import {
96
98
  FILE_ONLY_MESSAGE_TEXT,
97
99
  composeSendInput,
98
100
  shouldSteerOnKey,
99
101
  shouldSubmitOnKey,
100
102
  useComposer
101
- } from "./chunk-MRSECXRP.js";
103
+ } from "./chunk-UQS7OQDE.js";
102
104
  import {
103
105
  CREDIT_EXHAUSTION_MESSAGE,
104
106
  formatBytes,
@@ -114,10 +116,10 @@ import {
114
116
  useOpenGeniClient,
115
117
  usePolledValue,
116
118
  useSessionEventTrigger
117
- } from "./chunk-HHFA4AFX.js";
119
+ } from "./chunk-I3BJZIG5.js";
118
120
  import {
119
121
  EmptyQueueStateSurface
120
- } from "./chunk-EBTT3MYN.js";
122
+ } from "./chunk-YDNWMKXO.js";
121
123
 
122
124
  // src/hooks/use-session.ts
123
125
  import { useCallback, useEffect, useState } from "react";
@@ -328,7 +330,7 @@ function useFileAttachments(options = {}) {
328
330
  import { Loader2Icon } from "lucide-react";
329
331
  import { lazy, Suspense } from "react";
330
332
  import { jsx, jsxs } from "react/jsx-runtime";
331
- var loadQueueSurface = () => import("./queue-surface-implementation-NQMV2ML3.js");
333
+ var loadQueueSurface = () => import("./queue-surface-implementation-3UW3MIIR.js");
332
334
  var QueueSurface = createQueueSurface(loadQueueSurface);
333
335
  function createQueueSurface(loadImplementation) {
334
336
  const LazyQueueSurface = lazy(async () => ({
@@ -6147,6 +6149,7 @@ import {
6147
6149
  import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
6148
6150
  import { Collapsible as Collapsible3 } from "radix-ui";
6149
6151
  import {
6152
+ memo as memo2,
6150
6153
  useCallback as useCallback20,
6151
6154
  useEffect as useEffect17,
6152
6155
  useLayoutEffect,
@@ -6389,6 +6392,7 @@ function StatusDot({ status, className }) {
6389
6392
 
6390
6393
  // src/components/message-timeline.tsx
6391
6394
  import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
6395
+ var INITIAL_MOUNTED_GROUPS = 1;
6392
6396
  function MessageTimeline({
6393
6397
  events,
6394
6398
  items,
@@ -6407,8 +6411,10 @@ function MessageTimeline({
6407
6411
  className
6408
6412
  }) {
6409
6413
  const resolvedItems = useMemo7(() => items ?? buildTimeline(events ?? []), [items, events]);
6410
- const groups = useMemo7(() => groupTimeline(resolvedItems), [resolvedItems]);
6411
- const firstGroupKey = groups[0] ? timelineGroupKey(groups[0]) : null;
6414
+ const allGroups = useMemo7(() => groupTimeline(resolvedItems), [resolvedItems]);
6415
+ const keyedGroups = useStableTimelineGroupKeys(allGroups);
6416
+ const { mountedGroups: groups, mountingOlderGroups } = useProgressivelyMountedGroups(keyedGroups);
6417
+ const firstGroupKey = allGroups[0] ? timelineGroupKey(allGroups[0]) : null;
6412
6418
  const scrollRef = useRef16(null);
6413
6419
  const topSentinelRef = useRef16(null);
6414
6420
  const previousBulkFirstKeyRef = useRef16(void 0);
@@ -6430,7 +6436,7 @@ function MessageTimeline({
6430
6436
  const streaming = lastItem !== void 0 && (lastItem.kind === "agent-message" || lastItem.kind === "reasoning") && lastItem.streaming;
6431
6437
  const working = status === "running" && !streaming;
6432
6438
  const firstKeyChangedForBulk = previousBulkFirstKeyRef.current !== void 0 && previousBulkFirstKeyRef.current !== firstGroupKey;
6433
- const bulkRender = groups.length > 0 && (bulkActive || firstKeyChangedForBulk);
6439
+ const bulkRender = allGroups.length > 0 && (bulkActive || firstKeyChangedForBulk || mountingOlderGroups);
6434
6440
  const captureAnchor = useCallback20(() => {
6435
6441
  const node = scrollRef.current;
6436
6442
  const inner = node?.firstElementChild;
@@ -6461,23 +6467,26 @@ function MessageTimeline({
6461
6467
  }
6462
6468
  }, [resolvedItems, working, autoFollow, pinned, revealed, groups.length, assignScrollTop]);
6463
6469
  useLayoutEffect(() => {
6464
- if (groups.length === 0 && revealed) {
6470
+ if (allGroups.length === 0 && revealed) {
6465
6471
  setRevealed(false);
6466
6472
  }
6467
- }, [groups.length, revealed]);
6473
+ }, [allGroups.length, revealed]);
6468
6474
  useLayoutEffect(() => {
6469
6475
  previousBulkFirstKeyRef.current = firstGroupKey;
6470
6476
  if (!bulkRender) {
6471
6477
  return;
6472
6478
  }
6473
6479
  setBulkActive(true);
6480
+ if (mountingOlderGroups) {
6481
+ return;
6482
+ }
6474
6483
  const frame = requestFrame(() => setBulkActive(false));
6475
6484
  return () => cancelFrame(frame);
6476
- }, [bulkRender, firstGroupKey]);
6485
+ }, [bulkRender, firstGroupKey, mountingOlderGroups]);
6477
6486
  useEffect17(() => {
6478
6487
  const root = scrollRef.current;
6479
6488
  const target = topSentinelRef.current;
6480
- if (!root || !target || !hasOlder || loadingOlder || !onLoadOlder || typeof IntersectionObserver === "undefined") {
6489
+ if (!root || !target || mountingOlderGroups || !hasOlder || loadingOlder || !onLoadOlder || typeof IntersectionObserver === "undefined") {
6481
6490
  return;
6482
6491
  }
6483
6492
  const observer = new IntersectionObserver(
@@ -6490,7 +6499,7 @@ function MessageTimeline({
6490
6499
  );
6491
6500
  observer.observe(target);
6492
6501
  return () => observer.disconnect();
6493
- }, [hasOlder, loadingOlder, onLoadOlder, firstGroupKey]);
6502
+ }, [hasOlder, loadingOlder, onLoadOlder, firstGroupKey, mountingOlderGroups]);
6494
6503
  useEffect17(() => {
6495
6504
  const node = scrollRef.current;
6496
6505
  const inner = node?.firstElementChild;
@@ -6544,7 +6553,7 @@ function MessageTimeline({
6544
6553
  className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 [overflow-anchor:none] sm:px-6",
6545
6554
  children: /* @__PURE__ */ jsxs12("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: [
6546
6555
  groups.length === 0 && !working ? emptyState ?? /* @__PURE__ */ jsx15("p", { className: "py-10 text-center text-sm text-og-fg-subtle", children: "No activity yet." }) : null,
6547
- hasOlder ? /* @__PURE__ */ jsx15(
6556
+ hasOlder && !mountingOlderGroups ? /* @__PURE__ */ jsx15(
6548
6557
  "div",
6549
6558
  {
6550
6559
  ref: topSentinelRef,
@@ -6555,7 +6564,7 @@ function MessageTimeline({
6555
6564
  }
6556
6565
  ) : null,
6557
6566
  loadingOlder ? /* @__PURE__ */ jsx15("div", { "data-og-timeline-chrome": "", className: "flex items-center gap-2 text-sm", children: /* @__PURE__ */ jsx15("span", { className: "og-shimmer-text font-medium", children: "Loading earlier activity\u2026" }) }) : null,
6558
- groups.map((group, index) => /* @__PURE__ */ jsx15(
6567
+ groups.map(({ group, key }, index) => /* @__PURE__ */ jsx15(
6559
6568
  TimelineGroupView,
6560
6569
  {
6561
6570
  group,
@@ -6565,9 +6574,9 @@ function MessageTimeline({
6565
6574
  onReconnect,
6566
6575
  resolveProviderLogo,
6567
6576
  toolRegistry,
6568
- foldLiveCluster: isAgentProgress(groups[index + 1])
6577
+ foldLiveCluster: isAgentProgress(groups[index + 1]?.group)
6569
6578
  },
6570
- timelineGroupKey(group)
6579
+ key
6571
6580
  )),
6572
6581
  working ? /* @__PURE__ */ jsx15("div", { className: "flex items-center gap-2 text-sm", children: /* @__PURE__ */ jsx15("span", { className: "og-shimmer-text font-medium", children: "Working\u2026" }) }) : null
6573
6582
  ] })
@@ -6603,6 +6612,90 @@ function MessageTimeline({
6603
6612
  ) : null })
6604
6613
  ] }) }) });
6605
6614
  }
6615
+ function useStableTimelineGroupKeys(allGroups) {
6616
+ const previousRef = useRef16([]);
6617
+ const keyedGroups = useMemo7(() => {
6618
+ const previousByItemId = /* @__PURE__ */ new Map();
6619
+ for (const previous of previousRef.current) {
6620
+ for (const itemId of timelineGroupItemIds(previous.group)) {
6621
+ previousByItemId.set(itemId, previous);
6622
+ }
6623
+ }
6624
+ const usedKeys = /* @__PURE__ */ new Set();
6625
+ return allGroups.map((group, index) => {
6626
+ const itemIds = timelineGroupItemIds(group);
6627
+ let retainedKey;
6628
+ for (const itemId of itemIds) {
6629
+ const previous = previousByItemId.get(itemId);
6630
+ if (previous && !usedKeys.has(previous.key)) {
6631
+ retainedKey = previous.key;
6632
+ break;
6633
+ }
6634
+ }
6635
+ const canonicalKey = timelineGroupKey(group);
6636
+ let key = retainedKey ?? canonicalKey;
6637
+ let collision = 0;
6638
+ while (usedKeys.has(key)) {
6639
+ key = `${canonicalKey}:${index}:${collision}`;
6640
+ collision += 1;
6641
+ }
6642
+ usedKeys.add(key);
6643
+ return { group, key };
6644
+ });
6645
+ }, [allGroups]);
6646
+ useLayoutEffect(() => {
6647
+ previousRef.current = keyedGroups;
6648
+ }, [keyedGroups]);
6649
+ return keyedGroups;
6650
+ }
6651
+ function useProgressivelyMountedGroups(allGroups) {
6652
+ const previousGroupKeysRef = useRef16([]);
6653
+ const groupKeys = useMemo7(() => {
6654
+ const nextKeys = allGroups.map((group) => group.key);
6655
+ const previousKeys = previousGroupKeysRef.current;
6656
+ return nextKeys.length === previousKeys.length && nextKeys.every((key, index) => key === previousKeys[index]) ? previousKeys : nextKeys;
6657
+ }, [allGroups]);
6658
+ useLayoutEffect(() => {
6659
+ previousGroupKeysRef.current = groupKeys;
6660
+ }, [groupKeys]);
6661
+ const [window2, setWindow] = useState21(() => ({
6662
+ groupKeys,
6663
+ visibleStart: Math.max(0, allGroups.length - INITIAL_MOUNTED_GROUPS)
6664
+ }));
6665
+ const lastPossibleStart = Math.max(0, allGroups.length - INITIAL_MOUNTED_GROUPS);
6666
+ let visibleStart = 0;
6667
+ if (allGroups.length > 0) {
6668
+ const currentIndexByKey = new Map(groupKeys.map((key, index) => [key, index]));
6669
+ let retainedStart;
6670
+ for (const key of window2.groupKeys.slice(window2.visibleStart)) {
6671
+ const index = currentIndexByKey.get(key);
6672
+ if (index !== void 0) {
6673
+ retainedStart = index;
6674
+ break;
6675
+ }
6676
+ }
6677
+ visibleStart = retainedStart === void 0 ? lastPossibleStart : Math.min(retainedStart, lastPossibleStart);
6678
+ }
6679
+ useEffect17(() => {
6680
+ if (window2.groupKeys !== groupKeys || window2.visibleStart !== visibleStart) {
6681
+ setWindow({ groupKeys, visibleStart });
6682
+ return;
6683
+ }
6684
+ if (visibleStart === 0) {
6685
+ return;
6686
+ }
6687
+ const frame = requestFrame(() => {
6688
+ setWindow(
6689
+ (current) => current.groupKeys === groupKeys && current.visibleStart > 0 ? { ...current, visibleStart: current.visibleStart - 1 } : current
6690
+ );
6691
+ });
6692
+ return () => cancelFrame(frame);
6693
+ }, [groupKeys, visibleStart, window2.groupKeys, window2.visibleStart]);
6694
+ return {
6695
+ mountedGroups: allGroups.slice(visibleStart),
6696
+ mountingOlderGroups: visibleStart > 0
6697
+ };
6698
+ }
6606
6699
  function requestFrame(callback) {
6607
6700
  if (typeof requestAnimationFrame === "function") {
6608
6701
  return requestAnimationFrame(callback);
@@ -6616,7 +6709,7 @@ function cancelFrame(id) {
6616
6709
  }
6617
6710
  window.clearTimeout(id);
6618
6711
  }
6619
- function TimelineGroupView({
6712
+ var TimelineGroupView = memo2(function TimelineGroupView2({
6620
6713
  group,
6621
6714
  renderMessageText,
6622
6715
  onOpenSession,
@@ -6665,7 +6758,7 @@ function TimelineGroupView({
6665
6758
  case "turn": {
6666
6759
  const activityItems = flattenActivityItems(group.groups);
6667
6760
  const body = group.groups.map((child) => /* @__PURE__ */ jsx15(
6668
- TimelineGroupView,
6761
+ TimelineGroupView2,
6669
6762
  {
6670
6763
  group: child,
6671
6764
  renderMessageText,
@@ -6711,7 +6804,7 @@ function TimelineGroupView({
6711
6804
  }
6712
6805
  );
6713
6806
  }
6714
- }
6807
+ });
6715
6808
  function timelineGroupKey(group) {
6716
6809
  switch (group.kind) {
6717
6810
  case "item":
@@ -6722,6 +6815,16 @@ function timelineGroupKey(group) {
6722
6815
  return group.id;
6723
6816
  }
6724
6817
  }
6818
+ function timelineGroupItemIds(group) {
6819
+ switch (group.kind) {
6820
+ case "item":
6821
+ return [group.item.id];
6822
+ case "activity":
6823
+ return group.items.map((item) => item.id);
6824
+ case "turn":
6825
+ return group.groups.flatMap(timelineGroupItemIds);
6826
+ }
6827
+ }
6725
6828
  function isAgentProgress(next) {
6726
6829
  if (!next) {
6727
6830
  return false;
@@ -7044,6 +7147,8 @@ function AuthNeededRow({
7044
7147
  const [failed, setFailed] = useState21(false);
7045
7148
  const provider = providerLabel(item.providerDomain);
7046
7149
  const unavailable = item.reason === "unsupported_auth" || item.reason === "resource_scope_unavailable";
7150
+ const missing = item.reason === "missing_connection";
7151
+ const actionLabel = missing ? "Connect" : "Reconnect";
7047
7152
  const start = async () => {
7048
7153
  if (!onReconnect || busy) {
7049
7154
  return;
@@ -7069,7 +7174,7 @@ function AuthNeededRow({
7069
7174
  }
7070
7175
  ),
7071
7176
  /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
7072
- /* @__PURE__ */ jsx15("p", { className: "truncate text-og-md font-medium text-og-fg", children: unavailable ? `${provider} tools unavailable` : `Reconnect ${provider}` }),
7177
+ /* @__PURE__ */ jsx15("p", { className: "truncate text-og-md font-medium text-og-fg", children: unavailable ? `${provider} tools unavailable` : `${actionLabel} ${provider}` }),
7073
7178
  /* @__PURE__ */ jsx15("p", { className: "truncate text-og-sm text-og-fg-subtle", children: authReasonLine(item.reason) })
7074
7179
  ] })
7075
7180
  ] }),
@@ -7085,7 +7190,7 @@ function AuthNeededRow({
7085
7190
  ),
7086
7191
  children: [
7087
7192
  /* @__PURE__ */ jsx15(RefreshCwIcon, { className: cn("size-3.5", busy && "animate-og-spin"), "aria-hidden": true }),
7088
- busy ? "Reconnecting\u2026" : "Reconnect"
7193
+ busy ? "Opening\u2026" : actionLabel
7089
7194
  ]
7090
7195
  }
7091
7196
  ) : !unavailable && item.authorizationUrl ? /* @__PURE__ */ jsxs12(
@@ -7100,13 +7205,20 @@ function AuthNeededRow({
7100
7205
  ),
7101
7206
  children: [
7102
7207
  /* @__PURE__ */ jsx15(RefreshCwIcon, { className: "size-3.5", "aria-hidden": true }),
7103
- "Reconnect"
7208
+ actionLabel
7104
7209
  ]
7105
7210
  }
7106
7211
  ) : null
7107
7212
  ] }),
7213
+ !unavailable ? /* @__PURE__ */ jsxs12("p", { className: "px-1 text-og-xs text-og-fg-subtle", children: [
7214
+ "This tool call wasn't replayed. After ",
7215
+ missing ? "connecting" : "reconnecting",
7216
+ ", send a new message to try again."
7217
+ ] }) : null,
7108
7218
  failed ? /* @__PURE__ */ jsxs12("p", { className: "px-1 text-og-xs text-og-status-failed", children: [
7109
- "Couldn't start reconnecting ",
7219
+ "Couldn't start ",
7220
+ missing ? "connecting" : "reconnecting",
7221
+ " ",
7110
7222
  provider,
7111
7223
  ". Try again."
7112
7224
  ] }) : null
@@ -12317,6 +12429,7 @@ export {
12317
12429
  isGoalEvent,
12318
12430
  isHumanInputEvent,
12319
12431
  isLineageRefreshEvent,
12432
+ isSessionMcpApprovalPolicyEvent,
12320
12433
  isTitleEvent,
12321
12434
  isTurnQueueEvent,
12322
12435
  languageForPath,
@@ -12374,6 +12487,7 @@ export {
12374
12487
  useSessionControl,
12375
12488
  useSessionEvents,
12376
12489
  useSessionLineage,
12490
+ useSessionMcpApprovalPolicy,
12377
12491
  useSlashCommands,
12378
12492
  useTerminalStream,
12379
12493
  useTranscription,