@truefoundry/assistant-ui-runtime 0.1.3-rc.1 → 0.1.3-rc.3
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.js +46 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/streamTurn.test.ts +85 -0
- package/src/streamTurn.ts +40 -6
- package/src/useTrueFoundryAgentMessages.ts +49 -10
package/dist/index.js
CHANGED
|
@@ -2830,18 +2830,25 @@ function bindAbort(session, abortSignal) {
|
|
|
2830
2830
|
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
2831
2831
|
return onAbort;
|
|
2832
2832
|
}
|
|
2833
|
-
async function* streamTurnContent(session, foldState, options, abortSignal, groupRootBaseline) {
|
|
2834
|
-
const previousTurnId = options.previousTurnId === null ?
|
|
2833
|
+
async function* streamTurnContent(session, foldState, options, abortSignal, groupRootBaseline, onTurnIdAvailable) {
|
|
2834
|
+
const previousTurnId = options.previousTurnId === null ? null : options.previousTurnId ?? "auto";
|
|
2835
2835
|
const turn = session.prepareTurn({
|
|
2836
2836
|
input: buildTurnInput(options),
|
|
2837
|
-
...previousTurnId
|
|
2837
|
+
...previousTurnId !== void 0 ? { previousTurnId } : {}
|
|
2838
2838
|
});
|
|
2839
2839
|
const onAbort = bindAbort(session, abortSignal);
|
|
2840
2840
|
if (abortSignal.aborted) {
|
|
2841
2841
|
return;
|
|
2842
2842
|
}
|
|
2843
|
+
let turnIdNotified = false;
|
|
2844
|
+
const notifyTurnIdIfAvailable = () => {
|
|
2845
|
+
if (!turnIdNotified && turn.id != null) {
|
|
2846
|
+
onTurnIdAvailable?.(turn.id);
|
|
2847
|
+
turnIdNotified = true;
|
|
2848
|
+
}
|
|
2849
|
+
};
|
|
2843
2850
|
try {
|
|
2844
|
-
|
|
2851
|
+
for await (const update of streamTurnEvents(
|
|
2845
2852
|
turn.execute(
|
|
2846
2853
|
{ stream: true },
|
|
2847
2854
|
{
|
|
@@ -2851,8 +2858,13 @@ async function* streamTurnContent(session, foldState, options, abortSignal, grou
|
|
|
2851
2858
|
),
|
|
2852
2859
|
foldState,
|
|
2853
2860
|
groupRootBaseline
|
|
2854
|
-
)
|
|
2861
|
+
)) {
|
|
2862
|
+
notifyTurnIdIfAvailable();
|
|
2863
|
+
yield update;
|
|
2864
|
+
}
|
|
2865
|
+
notifyTurnIdIfAvailable();
|
|
2855
2866
|
} catch (error) {
|
|
2867
|
+
notifyTurnIdIfAvailable();
|
|
2856
2868
|
if (error instanceof Error && error.name === "AbortError") {
|
|
2857
2869
|
return;
|
|
2858
2870
|
}
|
|
@@ -3067,7 +3079,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3067
3079
|
[snapshot, projectOptions]
|
|
3068
3080
|
);
|
|
3069
3081
|
const runStream = useCallback2(
|
|
3070
|
-
(createStream,
|
|
3082
|
+
(createStream, turnIdRef, isContinuation) => {
|
|
3071
3083
|
const streamGeneration = ++streamGenerationRef.current;
|
|
3072
3084
|
abortControllerRef.current?.abort();
|
|
3073
3085
|
const abortController = new AbortController();
|
|
@@ -3083,11 +3095,14 @@ function useTrueFoundryAgentMessages({
|
|
|
3083
3095
|
if (pending == null || streamGeneration !== streamGenerationRef.current) {
|
|
3084
3096
|
return;
|
|
3085
3097
|
}
|
|
3086
|
-
const { update,
|
|
3098
|
+
const { update, isContinuation: pendingIsContinuation } = pending;
|
|
3087
3099
|
setSnapshot(
|
|
3088
3100
|
(prev) => replaceSessionSnapshot(prev, {
|
|
3089
3101
|
activeStream: {
|
|
3090
|
-
|
|
3102
|
+
// Read from the ref so we always use the latest ID,
|
|
3103
|
+
// including any gateway ID that arrived after the RAf
|
|
3104
|
+
// was scheduled.
|
|
3105
|
+
turnId: turnIdRef.current,
|
|
3091
3106
|
update,
|
|
3092
3107
|
isContinuation: pendingIsContinuation
|
|
3093
3108
|
}
|
|
@@ -3095,7 +3110,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3095
3110
|
);
|
|
3096
3111
|
};
|
|
3097
3112
|
const applyStreamUpdate = (update) => {
|
|
3098
|
-
pendingStreamUpdate = { update,
|
|
3113
|
+
pendingStreamUpdate = { update, isContinuation };
|
|
3099
3114
|
if (streamUpdateRaf == null) {
|
|
3100
3115
|
streamUpdateRaf = requestAnimationFrame(flushPendingStreamUpdate);
|
|
3101
3116
|
}
|
|
@@ -3208,7 +3223,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3208
3223
|
void 0,
|
|
3209
3224
|
loadedSnapshot.groupRootBaseline
|
|
3210
3225
|
),
|
|
3211
|
-
turn.id,
|
|
3226
|
+
{ current: turn.id },
|
|
3212
3227
|
isContinuation
|
|
3213
3228
|
).catch(() => void 0);
|
|
3214
3229
|
}
|
|
@@ -3247,6 +3262,8 @@ function useTrueFoundryAgentMessages({
|
|
|
3247
3262
|
const isContinuation = "inputs" in options || "resumeMcpAuth" in options && options.resumeMcpAuth === true;
|
|
3248
3263
|
const continuationTurnId = snapshotRef.current.activeStream?.turnId;
|
|
3249
3264
|
const turnId = isContinuation && continuationTurnId != null ? continuationTurnId : generateId();
|
|
3265
|
+
const isFirstTurnInSession = "userMessage" in options && options.previousTurnId === void 0 && snapshotRef.current.turns.length === 0 && snapshotRef.current.pendingUser == null && snapshotRef.current.activeStream == null;
|
|
3266
|
+
const turnIdRef = { current: turnId };
|
|
3250
3267
|
if ("inputs" in options) {
|
|
3251
3268
|
applyUserToolResponsesToFold(
|
|
3252
3269
|
snapshotRef.current.fold,
|
|
@@ -3321,14 +3338,29 @@ function useTrueFoundryAgentMessages({
|
|
|
3321
3338
|
snapshotRef.current.fold,
|
|
3322
3339
|
{
|
|
3323
3340
|
userMessage: options.userMessage,
|
|
3324
|
-
...options.previousTurnId !== void 0 ? { previousTurnId: options.previousTurnId } : {},
|
|
3341
|
+
...options.previousTurnId !== void 0 ? { previousTurnId: options.previousTurnId } : isFirstTurnInSession ? { previousTurnId: null } : {},
|
|
3325
3342
|
...streamHeaders
|
|
3326
3343
|
},
|
|
3327
3344
|
signal,
|
|
3328
|
-
groupRootBaseline
|
|
3345
|
+
groupRootBaseline,
|
|
3346
|
+
// Rename the optimistic local ID to the gateway turn ID
|
|
3347
|
+
// so that edit/retry can resolve the turn via the gateway.
|
|
3348
|
+
(gatewayTurnId) => {
|
|
3349
|
+
const oldId = turnIdRef.current;
|
|
3350
|
+
if (gatewayTurnId === oldId) return;
|
|
3351
|
+
turnIdRef.current = gatewayTurnId;
|
|
3352
|
+
const renamePendingUser = (prev) => {
|
|
3353
|
+
if (prev.pendingUser?.turnId !== oldId) return prev;
|
|
3354
|
+
return replaceSessionSnapshot(prev, {
|
|
3355
|
+
pendingUser: { ...prev.pendingUser, turnId: gatewayTurnId }
|
|
3356
|
+
});
|
|
3357
|
+
};
|
|
3358
|
+
snapshotRef.current = renamePendingUser(snapshotRef.current);
|
|
3359
|
+
setSnapshot(renamePendingUser);
|
|
3360
|
+
}
|
|
3329
3361
|
);
|
|
3330
3362
|
},
|
|
3331
|
-
|
|
3363
|
+
turnIdRef,
|
|
3332
3364
|
isContinuation
|
|
3333
3365
|
);
|
|
3334
3366
|
},
|
|
@@ -3414,7 +3446,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3414
3446
|
void 0,
|
|
3415
3447
|
snapshotRef.current.groupRootBaseline
|
|
3416
3448
|
),
|
|
3417
|
-
turn.id,
|
|
3449
|
+
{ current: turn.id },
|
|
3418
3450
|
true
|
|
3419
3451
|
);
|
|
3420
3452
|
}, [runStream]);
|