@opengeni/react 3.1.0 → 3.3.2
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/accounts.js +87 -11
- package/dist/accounts.js.map +1 -1
- package/dist/{browser-viewer-AEFHUYZK.js → browser-viewer-MKKFRRRV.js} +3 -3
- package/dist/{chunk-W6NFJXSA.js → chunk-2DZVYHVO.js} +20 -4
- package/dist/chunk-2DZVYHVO.js.map +1 -0
- package/dist/{chunk-YJFGAFBD.js → chunk-3AGBGTRT.js} +226 -95
- package/dist/chunk-3AGBGTRT.js.map +1 -0
- package/dist/{chunk-YFKJ7VZH.js → chunk-7EAFGICR.js} +45 -11
- package/dist/chunk-7EAFGICR.js.map +1 -0
- package/dist/{chunk-MZ2G2XBA.js → chunk-IOLVN74D.js} +31 -4
- package/dist/chunk-IOLVN74D.js.map +1 -0
- package/dist/{chunk-D3UIAJKY.js → chunk-JAQ5K7W6.js} +3 -2
- package/dist/{chunk-D3UIAJKY.js.map → chunk-JAQ5K7W6.js.map} +1 -1
- package/dist/{chunk-LAKLF4PA.js → chunk-VTOREEXF.js} +8 -7
- package/dist/chunk-VTOREEXF.js.map +1 -0
- package/dist/{chunk-RGALCTWO.js → chunk-XYRDDSXF.js} +4 -4
- package/dist/{chunk-HQVCKCLG.js → chunk-YG4QEQF5.js} +354 -255
- package/dist/chunk-YG4QEQF5.js.map +1 -0
- package/dist/{chunk-XXWH2JLC.js → chunk-YVCHAQZY.js} +2 -2
- package/dist/{chunk-OAM4WAAM.js → chunk-ZPBTI3TE.js} +2 -2
- package/dist/components/fleet-tile.d.ts +2 -2
- package/dist/components/model-policy-picker.d.ts +9 -0
- package/dist/components/tip-follow.d.ts +16 -0
- package/dist/composer.js +5 -5
- package/dist/hooks/use-session-events.d.ts +3 -3
- package/dist/index.js +76 -68
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +2 -2
- package/dist/machines.js +2 -2
- package/dist/realtime.js +46 -7
- package/dist/realtime.js.map +1 -1
- package/dist/session-ui.js +4 -4
- package/dist/session.js +4 -4
- package/dist/timeline/entrance.d.ts +13 -1
- package/package.json +3 -2
- package/src/accounts.tsx +116 -14
- package/src/components/fleet-tile.tsx +4 -15
- package/src/components/message-timeline.tsx +237 -101
- package/src/components/model-policy-picker.tsx +24 -3
- package/src/components/tip-follow.ts +52 -0
- package/src/components/tooltip.tsx +38 -5
- package/src/hooks/use-available-models.ts +20 -14
- package/src/hooks/use-composer.ts +49 -3
- package/src/hooks/use-goal.ts +31 -7
- package/src/hooks/use-last-started-turn-policy.ts +11 -5
- package/src/hooks/use-session-events.ts +186 -61
- package/src/hooks/use-session-lineage.ts +20 -16
- package/src/hooks/use-session.ts +23 -19
- package/src/hooks/use-workspace-sessions.ts +31 -27
- package/src/lib/format.ts +8 -6
- package/src/realtime/realtime-control.tsx +55 -6
- package/src/timeline/entrance.tsx +28 -3
- package/src/timeline/projection.ts +4 -0
- package/dist/chunk-HQVCKCLG.js.map +0 -1
- package/dist/chunk-LAKLF4PA.js.map +0 -1
- package/dist/chunk-MZ2G2XBA.js.map +0 -1
- package/dist/chunk-W6NFJXSA.js.map +0 -1
- package/dist/chunk-YFKJ7VZH.js.map +0 -1
- package/dist/chunk-YJFGAFBD.js.map +0 -1
- /package/dist/{browser-viewer-AEFHUYZK.js.map → browser-viewer-MKKFRRRV.js.map} +0 -0
- /package/dist/{chunk-RGALCTWO.js.map → chunk-XYRDDSXF.js.map} +0 -0
- /package/dist/{chunk-XXWH2JLC.js.map → chunk-YVCHAQZY.js.map} +0 -0
- /package/dist/{chunk-OAM4WAAM.js.map → chunk-ZPBTI3TE.js.map} +0 -0
|
@@ -200,6 +200,11 @@ export function tipFollowNoteGrowth(
|
|
|
200
200
|
if (previous <= 0) {
|
|
201
201
|
return { ...state, lastHeight: height };
|
|
202
202
|
}
|
|
203
|
+
if (height < previous && previous - height <= TIP_FOLLOW_SHRINK_EPS_PX) {
|
|
204
|
+
// Match viewport-shrink deadband memory: the shell retains the paired
|
|
205
|
+
// pre-shrink scrollTop and this state retains the corresponding height.
|
|
206
|
+
return state;
|
|
207
|
+
}
|
|
203
208
|
if (height <= previous) {
|
|
204
209
|
return { ...state, lastHeight: height };
|
|
205
210
|
}
|
|
@@ -441,6 +446,53 @@ export function tipFollowCompensateShrink(
|
|
|
441
446
|
return Math.max(0, Math.min(maxScroll, scrollTop - delta));
|
|
442
447
|
}
|
|
443
448
|
|
|
449
|
+
export type TipFollowContentShrinkBaseline = {
|
|
450
|
+
scrollHeight: number;
|
|
451
|
+
scrollTop: number;
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
export type TipFollowContentShrinkObservation = {
|
|
455
|
+
baseline: TipFollowContentShrinkBaseline | null;
|
|
456
|
+
compensatedScrollTop: number | null;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Retain the geometry from the first sub-epsilon content-shrink frame until
|
|
461
|
+
* the cumulative collapse crosses the deadband. Browsers may clamp scrollTop
|
|
462
|
+
* after every tiny frame, so compensating from the latest DOM top would count
|
|
463
|
+
* those already-applied clamps twice and make the result animation-cadence
|
|
464
|
+
* dependent.
|
|
465
|
+
*/
|
|
466
|
+
export function tipFollowObserveContentShrink(
|
|
467
|
+
baseline: TipFollowContentShrinkBaseline | null,
|
|
468
|
+
previousHeight: number,
|
|
469
|
+
previousScrollTop: number,
|
|
470
|
+
nextHeight: number,
|
|
471
|
+
clientHeight: number,
|
|
472
|
+
epsPx: number = TIP_FOLLOW_SHRINK_EPS_PX,
|
|
473
|
+
): TipFollowContentShrinkObservation {
|
|
474
|
+
if (previousHeight <= 0 || nextHeight >= previousHeight) {
|
|
475
|
+
return { baseline: null, compensatedScrollTop: null };
|
|
476
|
+
}
|
|
477
|
+
const retained = baseline ?? {
|
|
478
|
+
scrollHeight: previousHeight,
|
|
479
|
+
scrollTop: previousScrollTop,
|
|
480
|
+
};
|
|
481
|
+
if (retained.scrollHeight - nextHeight <= epsPx) {
|
|
482
|
+
return { baseline: retained, compensatedScrollTop: null };
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
baseline: null,
|
|
486
|
+
compensatedScrollTop: tipFollowCompensateShrink(
|
|
487
|
+
retained.scrollTop,
|
|
488
|
+
retained.scrollHeight,
|
|
489
|
+
nextHeight,
|
|
490
|
+
clientHeight,
|
|
491
|
+
epsPx,
|
|
492
|
+
),
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
|
|
444
496
|
/**
|
|
445
497
|
* Viewport shrank (SessionChrome / composer / window). maxScroll rises by ≈Δc;
|
|
446
498
|
* keep the same tip distance: scrollTop += Δc. Without this, pinned follow only
|
|
@@ -8,10 +8,19 @@
|
|
|
8
8
|
* tips and look like a blank white bubble.
|
|
9
9
|
*/
|
|
10
10
|
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
createContext,
|
|
13
|
+
useContext,
|
|
14
|
+
useLayoutEffect,
|
|
15
|
+
useMemo,
|
|
16
|
+
useRef,
|
|
17
|
+
useState,
|
|
18
|
+
type ComponentProps,
|
|
19
|
+
type CSSProperties,
|
|
20
|
+
} from "react";
|
|
12
21
|
|
|
13
22
|
import { cn } from "../lib/cn";
|
|
14
|
-
import {
|
|
23
|
+
import { usePortalTokenStyle } from "../lib/use-portal-token-style";
|
|
15
24
|
|
|
16
25
|
type TooltipSourceContextValue = {
|
|
17
26
|
source: HTMLElement | null;
|
|
@@ -28,10 +37,34 @@ function TooltipProvider({
|
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
function Tooltip({ children, ...props }: ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
31
|
-
const
|
|
40
|
+
const { onOpenChange, ...rootProps } = props;
|
|
41
|
+
const sourceRef = useRef<HTMLElement | null>(null);
|
|
42
|
+
const sourcePublishedRef = useRef(false);
|
|
43
|
+
const [source, setSource] = useState<HTMLElement | null>(null);
|
|
44
|
+
const ref = useRef((node: HTMLElement | null) => {
|
|
45
|
+
sourceRef.current = node;
|
|
46
|
+
if (sourcePublishedRef.current) setSource(node);
|
|
47
|
+
}).current;
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
if (rootProps.open === true || rootProps.defaultOpen === true) {
|
|
50
|
+
sourcePublishedRef.current = true;
|
|
51
|
+
setSource(sourceRef.current);
|
|
52
|
+
}
|
|
53
|
+
}, [rootProps.defaultOpen, rootProps.open]);
|
|
54
|
+
const sourceContext = useMemo(() => ({ source, ref }), [ref, source]);
|
|
32
55
|
return (
|
|
33
|
-
<TooltipSourceContext.Provider value={
|
|
34
|
-
<TooltipPrimitive.Root
|
|
56
|
+
<TooltipSourceContext.Provider value={sourceContext}>
|
|
57
|
+
<TooltipPrimitive.Root
|
|
58
|
+
data-slot="tooltip"
|
|
59
|
+
onOpenChange={(open) => {
|
|
60
|
+
if (open) {
|
|
61
|
+
sourcePublishedRef.current = true;
|
|
62
|
+
setSource(sourceRef.current);
|
|
63
|
+
}
|
|
64
|
+
onOpenChange?.(open);
|
|
65
|
+
}}
|
|
66
|
+
{...rootProps}
|
|
67
|
+
>
|
|
35
68
|
{children}
|
|
36
69
|
</TooltipPrimitive.Root>
|
|
37
70
|
</TooltipSourceContext.Provider>
|
|
@@ -43,7 +43,10 @@ export function useAvailableModels(
|
|
|
43
43
|
options: UseAvailableModelsOptions = {},
|
|
44
44
|
): UseAvailableModelsResult {
|
|
45
45
|
const client = useOpenGeniClient(options);
|
|
46
|
-
const load = useCallback(
|
|
46
|
+
const load = useCallback(
|
|
47
|
+
async (signal?: AbortSignal) => await client.getClientConfig({ signal }),
|
|
48
|
+
[client],
|
|
49
|
+
);
|
|
47
50
|
const state = usePolledValue(load, {
|
|
48
51
|
pollIntervalMs: options.pollIntervalMs,
|
|
49
52
|
enabled: options.enabled,
|
|
@@ -62,19 +65,22 @@ export function useWorkspaceModelCatalog(
|
|
|
62
65
|
options: UseWorkspaceModelCatalogOptions,
|
|
63
66
|
): UseWorkspaceModelCatalogResult {
|
|
64
67
|
const client = useOpenGeniClient(options);
|
|
65
|
-
const load = useCallback(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
const load = useCallback(
|
|
69
|
+
async (signal?: AbortSignal) => {
|
|
70
|
+
if (!options.workspaceId) {
|
|
71
|
+
return { models: [], defaultModel: null };
|
|
72
|
+
}
|
|
73
|
+
const [catalog, config] = await Promise.all([
|
|
74
|
+
client.getWorkspaceModelCatalog(options.workspaceId, { signal }),
|
|
75
|
+
client.getClientConfig({ signal }),
|
|
76
|
+
]);
|
|
77
|
+
return {
|
|
78
|
+
models: catalog.models,
|
|
79
|
+
defaultModel: config.defaultModel,
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
[client, options.workspaceId],
|
|
83
|
+
);
|
|
78
84
|
const state = usePolledValue(load, {
|
|
79
85
|
pollIntervalMs: options.pollIntervalMs,
|
|
80
86
|
enabled: options.enabled !== false && Boolean(options.workspaceId),
|
|
@@ -569,9 +569,17 @@ function reconcileOptimisticSendFromEvents(
|
|
|
569
569
|
);
|
|
570
570
|
const triggerEventId = operation.triggerEventId ?? accepted?.id ?? null;
|
|
571
571
|
const turnId = operation.turnId ?? promptTurnIdForTrigger(triggerEventId, events);
|
|
572
|
+
const acceptedRouting = promptRoutingFromAcceptedEvent(accepted ?? null);
|
|
573
|
+
const destination =
|
|
574
|
+
acceptedRouting === "queued_for_execution"
|
|
575
|
+
? "queue"
|
|
576
|
+
: acceptedRouting === "accepted_for_execution" || acceptedRouting === "accepted_for_steering"
|
|
577
|
+
? "chat"
|
|
578
|
+
: operation.destination;
|
|
572
579
|
const needsAdmissionUpdate =
|
|
573
580
|
accepted !== undefined &&
|
|
574
581
|
(operation.state !== "queued" ||
|
|
582
|
+
operation.destination !== destination ||
|
|
575
583
|
operation.triggerEventId !== triggerEventId ||
|
|
576
584
|
operation.turnId !== turnId ||
|
|
577
585
|
operation.error !== undefined ||
|
|
@@ -580,6 +588,7 @@ function reconcileOptimisticSendFromEvents(
|
|
|
580
588
|
? {
|
|
581
589
|
...operation,
|
|
582
590
|
state: "queued",
|
|
591
|
+
destination,
|
|
583
592
|
triggerEventId,
|
|
584
593
|
turnId,
|
|
585
594
|
error: undefined,
|
|
@@ -697,6 +706,7 @@ export function useComposer(
|
|
|
697
706
|
const targetGeneration = useRef(0);
|
|
698
707
|
const draftReadGeneration = useRef(0);
|
|
699
708
|
const draftReadInFlightRef = useRef<string | null>(null);
|
|
709
|
+
const draftReadAbortRef = useRef<AbortController | null>(null);
|
|
700
710
|
const draftReadRetryRef = useRef<{
|
|
701
711
|
targetKey: string;
|
|
702
712
|
failures: number;
|
|
@@ -733,6 +743,8 @@ export function useComposer(
|
|
|
733
743
|
if (draftReadRetryRef.current.timer !== null) {
|
|
734
744
|
clearTimeout(draftReadRetryRef.current.timer);
|
|
735
745
|
}
|
|
746
|
+
draftReadAbortRef.current?.abort();
|
|
747
|
+
draftReadAbortRef.current = null;
|
|
736
748
|
draftReadRetryRef.current = { targetKey, failures: 0, timer: null };
|
|
737
749
|
targetKeyRef.current = targetKey;
|
|
738
750
|
targetGeneration.current += 1;
|
|
@@ -791,6 +803,11 @@ export function useComposer(
|
|
|
791
803
|
if (draftReadRetryRef.current.timer !== null) {
|
|
792
804
|
clearTimeout(draftReadRetryRef.current.timer);
|
|
793
805
|
}
|
|
806
|
+
targetGeneration.current += 1;
|
|
807
|
+
draftReadGeneration.current += 1;
|
|
808
|
+
draftReadInFlightRef.current = null;
|
|
809
|
+
draftReadAbortRef.current?.abort();
|
|
810
|
+
draftReadAbortRef.current = null;
|
|
794
811
|
},
|
|
795
812
|
[],
|
|
796
813
|
);
|
|
@@ -929,6 +946,9 @@ export function useComposer(
|
|
|
929
946
|
draftReadInFlightRef.current = targetKey;
|
|
930
947
|
const generation = targetGeneration.current;
|
|
931
948
|
const readTicket = ++draftReadGeneration.current;
|
|
949
|
+
const requestAbort = new AbortController();
|
|
950
|
+
draftReadAbortRef.current?.abort();
|
|
951
|
+
draftReadAbortRef.current = requestAbort;
|
|
932
952
|
const localAtStart = localEditRevision.current;
|
|
933
953
|
const baseAtStart = draftRef.current;
|
|
934
954
|
const policyAtStart = policyRef.current;
|
|
@@ -958,7 +978,9 @@ export function useComposer(
|
|
|
958
978
|
setDraftLoading(true);
|
|
959
979
|
}
|
|
960
980
|
try {
|
|
961
|
-
const fetched = await client.getComposerDraft(workspaceId, sessionId
|
|
981
|
+
const fetched = await client.getComposerDraft(workspaceId, sessionId, {
|
|
982
|
+
signal: requestAbort.signal,
|
|
983
|
+
});
|
|
962
984
|
if (
|
|
963
985
|
generation !== targetGeneration.current ||
|
|
964
986
|
targetKeyRef.current !== targetKey ||
|
|
@@ -1049,6 +1071,9 @@ export function useComposer(
|
|
|
1049
1071
|
if (draftReadInFlightRef.current === targetKey) {
|
|
1050
1072
|
draftReadInFlightRef.current = null;
|
|
1051
1073
|
}
|
|
1074
|
+
if (draftReadAbortRef.current === requestAbort) {
|
|
1075
|
+
draftReadAbortRef.current = null;
|
|
1076
|
+
}
|
|
1052
1077
|
}
|
|
1053
1078
|
},
|
|
1054
1079
|
[client, durableDrafts, sessionId, targetKey, workspaceId],
|
|
@@ -1463,10 +1488,13 @@ export function useComposer(
|
|
|
1463
1488
|
) {
|
|
1464
1489
|
return;
|
|
1465
1490
|
}
|
|
1491
|
+
const acceptedRouting =
|
|
1492
|
+
acceptedResult?.routing ?? promptRoutingFromAcceptedEvent(acceptedEvent);
|
|
1466
1493
|
const acceptedDestination =
|
|
1467
|
-
|
|
1494
|
+
acceptedRouting === "queued_for_execution"
|
|
1468
1495
|
? "queue"
|
|
1469
|
-
:
|
|
1496
|
+
: acceptedRouting === "accepted_for_execution" ||
|
|
1497
|
+
acceptedRouting === "accepted_for_steering"
|
|
1470
1498
|
? "chat"
|
|
1471
1499
|
: operation.destination;
|
|
1472
1500
|
if (options.events === undefined && acceptedDestination === "chat") {
|
|
@@ -2743,6 +2771,24 @@ function asError(cause: unknown): Error {
|
|
|
2743
2771
|
return cause instanceof Error ? cause : new Error(String(cause));
|
|
2744
2772
|
}
|
|
2745
2773
|
|
|
2774
|
+
function promptRoutingFromAcceptedEvent(
|
|
2775
|
+
event: SessionEvent | null,
|
|
2776
|
+
): "accepted_for_execution" | "queued_for_execution" | "accepted_for_steering" | null {
|
|
2777
|
+
if (
|
|
2778
|
+
typeof event?.payload !== "object" ||
|
|
2779
|
+
event.payload === null ||
|
|
2780
|
+
Array.isArray(event.payload)
|
|
2781
|
+
) {
|
|
2782
|
+
return null;
|
|
2783
|
+
}
|
|
2784
|
+
const routing = (event.payload as Record<string, unknown>).routing;
|
|
2785
|
+
return routing === "accepted_for_execution" ||
|
|
2786
|
+
routing === "queued_for_execution" ||
|
|
2787
|
+
routing === "accepted_for_steering"
|
|
2788
|
+
? routing
|
|
2789
|
+
: null;
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2746
2792
|
function isDraftConflictError(error: Error): boolean {
|
|
2747
2793
|
const apiError = error as Partial<OpenGeniApiError>;
|
|
2748
2794
|
return (
|
package/src/hooks/use-goal.ts
CHANGED
|
@@ -83,14 +83,26 @@ export function useGoal(
|
|
|
83
83
|
const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
|
|
84
84
|
const generation = useRef(0);
|
|
85
85
|
const targetKeyRef = useRef<string | null>(null);
|
|
86
|
+
const loadAbort = useRef<AbortController | null>(null);
|
|
87
|
+
|
|
88
|
+
const retireLoads = useCallback(() => {
|
|
89
|
+
generation.current += 1;
|
|
90
|
+
loadAbort.current?.abort();
|
|
91
|
+
loadAbort.current = null;
|
|
92
|
+
}, []);
|
|
86
93
|
|
|
87
94
|
const load = useCallback(async (): Promise<void> => {
|
|
88
95
|
if (!sessionId) {
|
|
89
96
|
return;
|
|
90
97
|
}
|
|
91
98
|
const ticket = ++generation.current;
|
|
99
|
+
loadAbort.current?.abort();
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
loadAbort.current = controller;
|
|
92
102
|
try {
|
|
93
|
-
const fetched = await client.getGoal(workspaceId, sessionId
|
|
103
|
+
const fetched = await client.getGoal(workspaceId, sessionId, {
|
|
104
|
+
signal: controller.signal,
|
|
105
|
+
});
|
|
94
106
|
if (ticket === generation.current) {
|
|
95
107
|
setGoal(fetched);
|
|
96
108
|
setError(null);
|
|
@@ -108,6 +120,8 @@ export function useGoal(
|
|
|
108
120
|
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
109
121
|
}
|
|
110
122
|
setLoading(false);
|
|
123
|
+
} finally {
|
|
124
|
+
if (loadAbort.current === controller) loadAbort.current = null;
|
|
111
125
|
}
|
|
112
126
|
}, [client, workspaceId, sessionId]);
|
|
113
127
|
|
|
@@ -119,13 +133,14 @@ export function useGoal(
|
|
|
119
133
|
setError(null);
|
|
120
134
|
}
|
|
121
135
|
if (!enabled || !pageLive) {
|
|
136
|
+
retireLoads();
|
|
122
137
|
setLoading(false);
|
|
123
138
|
return;
|
|
124
139
|
}
|
|
125
140
|
if (sharedFeed) {
|
|
126
141
|
setLoading(false);
|
|
127
142
|
return () => {
|
|
128
|
-
|
|
143
|
+
retireLoads();
|
|
129
144
|
};
|
|
130
145
|
}
|
|
131
146
|
setLoading(true);
|
|
@@ -133,7 +148,7 @@ export function useGoal(
|
|
|
133
148
|
if (pollIntervalMs === undefined || pollIntervalMs <= 0) {
|
|
134
149
|
void load();
|
|
135
150
|
return () => {
|
|
136
|
-
|
|
151
|
+
retireLoads();
|
|
137
152
|
};
|
|
138
153
|
}
|
|
139
154
|
let cancelled = false;
|
|
@@ -149,9 +164,18 @@ export function useGoal(
|
|
|
149
164
|
return () => {
|
|
150
165
|
cancelled = true;
|
|
151
166
|
if (timer !== null) clearTimeout(timer);
|
|
152
|
-
|
|
167
|
+
retireLoads();
|
|
153
168
|
};
|
|
154
|
-
}, [
|
|
169
|
+
}, [
|
|
170
|
+
load,
|
|
171
|
+
enabled,
|
|
172
|
+
pageLive,
|
|
173
|
+
workspaceId,
|
|
174
|
+
sessionId,
|
|
175
|
+
options.pollIntervalMs,
|
|
176
|
+
retireLoads,
|
|
177
|
+
sharedFeed,
|
|
178
|
+
]);
|
|
155
179
|
|
|
156
180
|
const scheduleRefresh = useDebouncedCallback(() => void load());
|
|
157
181
|
useSessionEventTrigger(client, workspaceId, sessionId, isGoalRefreshEvent, scheduleRefresh, {
|
|
@@ -203,11 +227,11 @@ export function useGoal(
|
|
|
203
227
|
return true as const;
|
|
204
228
|
});
|
|
205
229
|
if (ok) {
|
|
206
|
-
|
|
230
|
+
retireLoads();
|
|
207
231
|
setGoal(null);
|
|
208
232
|
setError(null);
|
|
209
233
|
}
|
|
210
|
-
}, [client, workspaceId, sessionId, run]);
|
|
234
|
+
}, [client, workspaceId, sessionId, run, retireLoads]);
|
|
211
235
|
|
|
212
236
|
return {
|
|
213
237
|
goal,
|
|
@@ -51,11 +51,17 @@ export function useLastStartedTurnPolicy(
|
|
|
51
51
|
useOpenGeni(options);
|
|
52
52
|
const enabled = (options.enabled ?? true) && Boolean(sessionId);
|
|
53
53
|
|
|
54
|
-
const load = useCallback(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
const load = useCallback(
|
|
55
|
+
async (signal?: AbortSignal): Promise<LastStartedTurnPolicy | null> => {
|
|
56
|
+
if (!sessionId) return null;
|
|
57
|
+
const turns = await client.listTurns(workspaceId, sessionId, {
|
|
58
|
+
latestStarted: true,
|
|
59
|
+
signal,
|
|
60
|
+
});
|
|
61
|
+
return policyFromTurn(turns[0]);
|
|
62
|
+
},
|
|
63
|
+
[client, workspaceId, sessionId],
|
|
64
|
+
);
|
|
59
65
|
|
|
60
66
|
const { data, loading, error, refresh } = usePolledValue(load, {
|
|
61
67
|
pollIntervalMs: options.pollIntervalMs,
|