@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 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 ? void 0 : options.previousTurnId ?? "auto";
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 != null ? { 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
- yield* streamTurnEvents(
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, turnId, isContinuation) => {
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, turnId: pendingTurnId, isContinuation: pendingIsContinuation } = pending;
3098
+ const { update, isContinuation: pendingIsContinuation } = pending;
3087
3099
  setSnapshot(
3088
3100
  (prev) => replaceSessionSnapshot(prev, {
3089
3101
  activeStream: {
3090
- turnId: pendingTurnId,
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, turnId, isContinuation };
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
- turnId,
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]);