@iota-uz/sdk 0.4.27 → 0.4.29

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.
@@ -1896,11 +1896,61 @@ function deriveInputSnapshot(state, methods) {
1896
1896
  };
1897
1897
  }
1898
1898
 
1899
+ // ui/src/bichat/utils/assistantTurnState.ts
1900
+ function isEmptyAssistantTurn(turn) {
1901
+ if (turn.content.trim().length > 0) {
1902
+ return false;
1903
+ }
1904
+ if ((turn.explanation?.trim().length ?? 0) > 0) {
1905
+ return false;
1906
+ }
1907
+ if ((turn.citations?.length ?? 0) > 0) {
1908
+ return false;
1909
+ }
1910
+ if ((turn.toolCalls?.length ?? 0) > 0) {
1911
+ return false;
1912
+ }
1913
+ if ((turn.charts?.length ?? 0) > 0) {
1914
+ return false;
1915
+ }
1916
+ if ((turn.renderTables?.length ?? 0) > 0) {
1917
+ return false;
1918
+ }
1919
+ if ((turn.artifacts?.length ?? 0) > 0) {
1920
+ return false;
1921
+ }
1922
+ if ((turn.codeOutputs?.length ?? 0) > 0) {
1923
+ return false;
1924
+ }
1925
+ if (turn.debug) {
1926
+ return false;
1927
+ }
1928
+ return true;
1929
+ }
1930
+ function isPlaceholderWaitingAssistantTurn(turn) {
1931
+ return turn.lifecycle === "waiting_for_human_input" && isEmptyAssistantTurn(turn);
1932
+ }
1933
+ function shouldRenderInlineRetry(turn, canRegenerate) {
1934
+ if (!canRegenerate) {
1935
+ return false;
1936
+ }
1937
+ if (turn.lifecycle === "waiting_for_human_input") {
1938
+ return false;
1939
+ }
1940
+ return isEmptyAssistantTurn(turn);
1941
+ }
1942
+
1899
1943
  // ui/src/bichat/machine/hitlLifecycle.ts
1900
1944
  function normalizeQuestionType(rawType) {
1901
1945
  const normalized = String(rawType || "").trim().toUpperCase().replace(/[\s-]+/g, "_");
1902
1946
  return normalized === "MULTIPLE_CHOICE" ? "MULTIPLE_CHOICE" : "SINGLE_CHOICE";
1903
1947
  }
1948
+ function isOpenQuestionStatus(status) {
1949
+ return status === "PENDING" || status === "ANSWER_SUBMITTED" || status === "REJECT_SUBMITTED" || status === "ANSWER_RESUME_FAILED" || status === "REJECT_RESUME_FAILED";
1950
+ }
1951
+ function shouldPromptForHumanInput(status) {
1952
+ return status === "PENDING" || status === "ANSWER_RESUME_FAILED" || status === "REJECT_RESUME_FAILED";
1953
+ }
1904
1954
  function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1905
1955
  if (!interrupt) {
1906
1956
  return null;
@@ -1928,7 +1978,7 @@ function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1928
1978
  };
1929
1979
  }
1930
1980
  function resolvePendingQuestionTurnIndex(turns, pendingQuestion) {
1931
- if (!pendingQuestion || pendingQuestion.status !== "PENDING" || turns.length === 0) {
1981
+ if (!pendingQuestion || !isOpenQuestionStatus(pendingQuestion.status) || turns.length === 0) {
1932
1982
  return -1;
1933
1983
  }
1934
1984
  const pendingTurnId = pendingQuestion.turnId?.trim();
@@ -1955,7 +2005,7 @@ function applyTurnLifecycleForPendingQuestion(turns, pendingQuestion) {
1955
2005
  let changed = false;
1956
2006
  const nextTurns = turns.map((turn, index) => {
1957
2007
  const shouldWaitForInput = pendingIndex === index;
1958
- const desiredLifecycle = shouldWaitForInput ? "waiting_for_human_input" : "complete";
2008
+ const desiredLifecycle = shouldWaitForInput ? shouldPromptForHumanInput(pendingQuestion?.status) ? "waiting_for_human_input" : "complete" : "complete";
1959
2009
  if (!turn.assistantTurn) {
1960
2010
  if (!shouldWaitForInput || !pendingQuestion) {
1961
2011
  return turn;
@@ -1975,6 +2025,13 @@ function applyTurnLifecycleForPendingQuestion(turns, pendingQuestion) {
1975
2025
  }
1976
2026
  };
1977
2027
  }
2028
+ if (!shouldWaitForInput && isPlaceholderWaitingAssistantTurn(turn.assistantTurn)) {
2029
+ changed = true;
2030
+ return {
2031
+ ...turn,
2032
+ assistantTurn: void 0
2033
+ };
2034
+ }
1978
2035
  if (turn.assistantTurn.lifecycle === desiredLifecycle) {
1979
2036
  return turn;
1980
2037
  }
@@ -2124,7 +2181,9 @@ var ChatMachine = class {
2124
2181
  this.onSessionCreated = config.onSessionCreated;
2125
2182
  this.reasoningEffortOptions = this.buildReasoningEffortOptions();
2126
2183
  this.reasoningEffortOptionSet = this.reasoningEffortOptions ? new Set(this.reasoningEffortOptions) : null;
2127
- const initialReasoningEffort = this.sanitizeReasoningEffort(loadReasoningEffort() || void 0);
2184
+ const initialReasoningEffort = this.sanitizeReasoningEffort(
2185
+ loadReasoningEffort() || void 0
2186
+ );
2128
2187
  if (!initialReasoningEffort) {
2129
2188
  clearReasoningEffort();
2130
2189
  }
@@ -2392,7 +2451,9 @@ var ChatMachine = class {
2392
2451
  */
2393
2452
  _setTurnsFromFetch(fetchedTurns, pendingQuestion) {
2394
2453
  if (!Array.isArray(fetchedTurns)) {
2395
- console.warn("[ChatMachine] Ignoring malformed turns payload from fetchSession");
2454
+ console.warn(
2455
+ "[ChatMachine] Ignoring malformed turns payload from fetchSession"
2456
+ );
2396
2457
  return;
2397
2458
  }
2398
2459
  const prev = this.state.messaging.turns;
@@ -2403,7 +2464,10 @@ var ChatMachine = class {
2403
2464
  patch.pendingQuestion = pendingQuestion;
2404
2465
  }
2405
2466
  if (hasPendingUserOnly && (!fetchedTurns || fetchedTurns.length === 0)) {
2406
- const lifecycleTurns = applyTurnLifecycleForPendingQuestion(prev, effectivePendingQuestion);
2467
+ const lifecycleTurns = applyTurnLifecycleForPendingQuestion(
2468
+ prev,
2469
+ effectivePendingQuestion
2470
+ );
2407
2471
  if (lifecycleTurns !== prev) {
2408
2472
  patch.turns = lifecycleTurns;
2409
2473
  }
@@ -2412,7 +2476,10 @@ var ChatMachine = class {
2412
2476
  }
2413
2477
  return;
2414
2478
  }
2415
- patch.turns = applyTurnLifecycleForPendingQuestion(fetchedTurns ?? prev, effectivePendingQuestion);
2479
+ patch.turns = applyTurnLifecycleForPendingQuestion(
2480
+ fetchedTurns ?? prev,
2481
+ effectivePendingQuestion
2482
+ );
2416
2483
  this._updateMessaging(patch);
2417
2484
  }
2418
2485
  /**
@@ -2469,10 +2536,16 @@ var ChatMachine = class {
2469
2536
  this._updateMessaging({ generationInProgress: false });
2470
2537
  this.dataSource.fetchSession(sessionId).then((result) => {
2471
2538
  if (this.state.session.currentSessionId === sessionId && result) {
2472
- this._setTurnsFromFetch(result.turns, result.pendingQuestion ?? null);
2539
+ this._setTurnsFromFetch(
2540
+ result.turns,
2541
+ result.pendingQuestion ?? null
2542
+ );
2473
2543
  }
2474
2544
  }).catch((err) => {
2475
- console.error("[ChatMachine] fetchSession after stream inactive:", err);
2545
+ console.error(
2546
+ "[ChatMachine] fetchSession after stream inactive:",
2547
+ err
2548
+ );
2476
2549
  });
2477
2550
  }
2478
2551
  }).catch((err) => {
@@ -2533,7 +2606,10 @@ var ChatMachine = class {
2533
2606
  if (this.disposed) {
2534
2607
  return;
2535
2608
  }
2536
- console.warn("[ChatMachine] resumeStream failed, switching to status polling fallback:", err);
2609
+ console.warn(
2610
+ "[ChatMachine] resumeStream failed, switching to status polling fallback:",
2611
+ err
2612
+ );
2537
2613
  const getStreamStatus2 = this.dataSource.getStreamStatus;
2538
2614
  const status = getStreamStatus2 ? await getStreamStatus2(sessionId).catch(() => null) : null;
2539
2615
  if (!status?.active) {
@@ -2574,9 +2650,11 @@ var ChatMachine = class {
2574
2650
  if (typeof window === "undefined") {
2575
2651
  return;
2576
2652
  }
2577
- window.dispatchEvent(new CustomEvent("bichat:sessions-updated", {
2578
- detail: { reason, sessionId }
2579
- }));
2653
+ window.dispatchEvent(
2654
+ new CustomEvent("bichat:sessions-updated", {
2655
+ detail: { reason, sessionId }
2656
+ })
2657
+ );
2580
2658
  }
2581
2659
  _cancel() {
2582
2660
  if (this.abortController) {
@@ -2624,10 +2702,15 @@ var ChatMachine = class {
2624
2702
  this._setDebugModeForSession(key3, nextDebugMode);
2625
2703
  if (nextDebugMode && this.state.session.currentSessionId && this.state.session.currentSessionId !== "new") {
2626
2704
  try {
2627
- const result = await this.dataSource.fetchSession(this.state.session.currentSessionId);
2705
+ const result = await this.dataSource.fetchSession(
2706
+ this.state.session.currentSessionId
2707
+ );
2628
2708
  if (result) {
2629
2709
  this._updateSession({ session: result.session });
2630
- this._setTurnsFromFetch(result.turns, result.pendingQuestion || null);
2710
+ this._setTurnsFromFetch(
2711
+ result.turns,
2712
+ result.pendingQuestion || null
2713
+ );
2631
2714
  }
2632
2715
  } catch (err) {
2633
2716
  console.error("Failed to refresh session for debug mode:", err);
@@ -2655,7 +2738,10 @@ var ChatMachine = class {
2655
2738
  }
2656
2739
  this._updateMessaging({ codeOutputs: [] });
2657
2740
  } catch (err) {
2658
- const normalized = normalizeRPCError(err, "Failed to clear session history");
2741
+ const normalized = normalizeRPCError(
2742
+ err,
2743
+ "Failed to clear session history"
2744
+ );
2659
2745
  this._updateInput({ inputError: normalized.userMessage });
2660
2746
  } finally {
2661
2747
  this._updateMessaging({ loading: false, isStreaming: false });
@@ -2676,7 +2762,12 @@ var ChatMachine = class {
2676
2762
  }
2677
2763
  this._updateMessaging({
2678
2764
  turns: applyTurnLifecycleForPendingQuestion(
2679
- [createCompactedSystemTurn(curSessionId, "Compacting conversation history...")],
2765
+ [
2766
+ createCompactedSystemTurn(
2767
+ curSessionId,
2768
+ "Compacting conversation history..."
2769
+ )
2770
+ ],
2680
2771
  null
2681
2772
  ),
2682
2773
  pendingQuestion: null
@@ -2686,17 +2777,27 @@ var ChatMachine = class {
2686
2777
  const result = await this.dataSource.fetchSession(curSessionId);
2687
2778
  if (result) {
2688
2779
  this._updateSession({ session: result.session });
2689
- this._setTurnsFromFetch(result.turns, result.pendingQuestion || null);
2780
+ this._setTurnsFromFetch(
2781
+ result.turns,
2782
+ result.pendingQuestion || null
2783
+ );
2690
2784
  } else {
2691
2785
  this._setTurnsFromFetch([], null);
2692
2786
  }
2693
2787
  this._updateMessaging({ codeOutputs: [] });
2694
2788
  }
2695
2789
  } catch (err) {
2696
- const normalized = normalizeRPCError(err, "Failed to compact session history");
2790
+ const normalized = normalizeRPCError(
2791
+ err,
2792
+ "Failed to compact session history"
2793
+ );
2697
2794
  this._updateInput({ inputError: normalized.userMessage });
2698
2795
  } finally {
2699
- this._updateMessaging({ isCompacting: false, loading: false, isStreaming: false });
2796
+ this._updateMessaging({
2797
+ isCompacting: false,
2798
+ loading: false,
2799
+ isStreaming: false
2800
+ });
2700
2801
  }
2701
2802
  return true;
2702
2803
  }
@@ -2708,9 +2809,13 @@ var ChatMachine = class {
2708
2809
  this._updateMessaging({ turns: [...prevTurns, tempTurn] });
2709
2810
  return;
2710
2811
  }
2711
- const idx = prevTurns.findIndex((turn) => turn.userTurn.id === replaceFromMessageID);
2812
+ const idx = prevTurns.findIndex(
2813
+ (turn) => turn.userTurn.id === replaceFromMessageID
2814
+ );
2712
2815
  if (idx === -1) {
2713
- console.warn(`[ChatMachine] replaceFromMessageID "${replaceFromMessageID}" not found; appending as new turn`);
2816
+ console.warn(
2817
+ `[ChatMachine] replaceFromMessageID "${replaceFromMessageID}" not found; appending as new turn`
2818
+ );
2714
2819
  this._updateMessaging({ turns: [...prevTurns, tempTurn] });
2715
2820
  return;
2716
2821
  }
@@ -2794,7 +2899,10 @@ var ChatMachine = class {
2794
2899
  if (chunk.sessionId) {
2795
2900
  createdSessionId = chunk.sessionId;
2796
2901
  }
2797
- const pendingFromInterrupt = pendingQuestionFromInterrupt(chunk.interrupt, tempTurnId);
2902
+ const pendingFromInterrupt = pendingQuestionFromInterrupt(
2903
+ chunk.interrupt,
2904
+ tempTurnId
2905
+ );
2798
2906
  if (pendingFromInterrupt) {
2799
2907
  this._updateMessaging({
2800
2908
  pendingQuestion: pendingFromInterrupt,
@@ -2868,7 +2976,9 @@ var ChatMachine = class {
2868
2976
  this._updateInput({ message: content });
2869
2977
  this._clearStreamError();
2870
2978
  this._updateMessaging({
2871
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurnId)
2979
+ turns: this.state.messaging.turns.filter(
2980
+ (turn) => turn.id !== tempTurnId
2981
+ )
2872
2982
  });
2873
2983
  const sessionId = this.sendingSessionId ?? this.state.session.currentSessionId;
2874
2984
  if (sessionId && sessionId !== "new") {
@@ -2878,7 +2988,9 @@ var ChatMachine = class {
2878
2988
  return false;
2879
2989
  }
2880
2990
  this._updateMessaging({
2881
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurnId)
2991
+ turns: this.state.messaging.turns.filter(
2992
+ (turn) => turn.id !== tempTurnId
2993
+ )
2882
2994
  });
2883
2995
  const normalized = normalizeRPCError(err, "Failed to send message");
2884
2996
  this._updateInput({ inputError: normalized.userMessage });
@@ -2946,7 +3058,11 @@ var ChatMachine = class {
2946
3058
  const curSessionId = this.state.session.currentSessionId;
2947
3059
  const curDebugMode = deriveDebugMode(this.state);
2948
3060
  const replaceFromMessageID = options?.replaceFromMessageID;
2949
- const tempTurn = createPendingTurn(curSessionId || "new", content, attachments);
3061
+ const tempTurn = createPendingTurn(
3062
+ curSessionId || "new",
3063
+ content,
3064
+ attachments
3065
+ );
2950
3066
  this.lastSendAttempt = { content, attachments, options };
2951
3067
  const prevTurns = this.state.messaging.turns;
2952
3068
  this._insertOptimisticTurn(prevTurns, tempTurn, replaceFromMessageID);
@@ -2954,22 +3070,22 @@ var ChatMachine = class {
2954
3070
  try {
2955
3071
  const { activeSessionId, shouldNavigateAfter } = await this._resolveSendSession(curSessionId, curDebugMode);
2956
3072
  this.sendingSessionId = activeSessionId || null;
2957
- const {
2958
- createdSessionId,
2959
- sessionFetched,
2960
- stopped
2961
- } = await this._runSendStream({
3073
+ const { createdSessionId, sessionFetched, stopped } = await this._runSendStream({
2962
3074
  activeSessionId,
2963
3075
  content,
2964
3076
  attachments,
2965
3077
  debugMode: curDebugMode,
2966
3078
  replaceFromMessageID,
2967
- reasoningEffort: this.sanitizeReasoningEffort(this.state.session.reasoningEffort),
3079
+ reasoningEffort: this.sanitizeReasoningEffort(
3080
+ this.state.session.reasoningEffort
3081
+ ),
2968
3082
  tempTurnId: tempTurn.id
2969
3083
  });
2970
3084
  if (stopped) {
2971
3085
  this._updateMessaging({
2972
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurn.id)
3086
+ turns: this.state.messaging.turns.filter(
3087
+ (turn) => turn.id !== tempTurn.id
3088
+ )
2973
3089
  });
2974
3090
  this._updateInput({ message: content });
2975
3091
  this._clearStreamError();
@@ -2979,7 +3095,11 @@ var ChatMachine = class {
2979
3095
  });
2980
3096
  }
2981
3097
  } else {
2982
- await this._ensureSessionSyncAfterStream(activeSessionId, createdSessionId, sessionFetched);
3098
+ await this._ensureSessionSyncAfterStream(
3099
+ activeSessionId,
3100
+ createdSessionId,
3101
+ sessionFetched
3102
+ );
2983
3103
  const targetSessionId = createdSessionId || activeSessionId;
2984
3104
  this._finalizeSuccessfulSend(targetSessionId, shouldNavigateAfter);
2985
3105
  }
@@ -3017,7 +3137,9 @@ var ChatMachine = class {
3017
3137
  }
3018
3138
  this._updateMessaging({ thinkingContent: updated });
3019
3139
  const steps = this.state.messaging.activeSteps;
3020
- const existing = steps.find((s) => s.type === "thinking" && s.status === "active");
3140
+ const existing = steps.find(
3141
+ (s) => s.type === "thinking" && s.status === "active"
3142
+ );
3021
3143
  if (!existing) {
3022
3144
  const step = {
3023
3145
  id: `thinking-${Date.now()}`,
@@ -3048,7 +3170,9 @@ var ChatMachine = class {
3048
3170
  }
3049
3171
  _handleToolEnd(tool) {
3050
3172
  const steps = [...this.state.messaging.activeSteps];
3051
- const idx = steps.findIndex((s) => s.status === "active" && this._matchStep(s, tool));
3173
+ const idx = steps.findIndex(
3174
+ (s) => s.status === "active" && this._matchStep(s, tool)
3175
+ );
3052
3176
  if (idx !== -1) {
3053
3177
  steps[idx] = {
3054
3178
  ...steps[idx],
@@ -3079,7 +3203,11 @@ var ChatMachine = class {
3079
3203
  }
3080
3204
  this._clearStreamError();
3081
3205
  this._updateInput({ inputError: null });
3082
- await this._sendMessageDirect(lastAttempt.content, lastAttempt.attachments, lastAttempt.options);
3206
+ await this._sendMessageDirect(
3207
+ lastAttempt.content,
3208
+ lastAttempt.attachments,
3209
+ lastAttempt.options
3210
+ );
3083
3211
  }
3084
3212
  // ── Regenerate / Edit ───────────────────────────────────────────────────
3085
3213
  async _handleRegenerate(turnId) {
@@ -3092,9 +3220,13 @@ var ChatMachine = class {
3092
3220
  return;
3093
3221
  }
3094
3222
  this._updateSession({ error: null, errorRetryable: false });
3095
- await this._sendMessageDirect(turn.userTurn.content, turn.userTurn.attachments, {
3096
- replaceFromMessageID: turn.userTurn.id
3097
- });
3223
+ await this._sendMessageDirect(
3224
+ turn.userTurn.content,
3225
+ turn.userTurn.attachments,
3226
+ {
3227
+ replaceFromMessageID: turn.userTurn.id
3228
+ }
3229
+ );
3098
3230
  }
3099
3231
  async _handleEdit(turnId, newContent) {
3100
3232
  const curSessionId = this.state.session.currentSessionId;
@@ -3107,7 +3239,10 @@ var ChatMachine = class {
3107
3239
  }
3108
3240
  const turn = this.state.messaging.turns.find((t) => t.id === turnId);
3109
3241
  if (!turn) {
3110
- this._updateSession({ error: "Failed to edit message", errorRetryable: false });
3242
+ this._updateSession({
3243
+ error: "Failed to edit message",
3244
+ errorRetryable: false
3245
+ });
3111
3246
  return;
3112
3247
  }
3113
3248
  this._updateSession({ error: null, errorRetryable: false });
@@ -3145,8 +3280,17 @@ var ChatMachine = class {
3145
3280
  }
3146
3281
  if (result.success) {
3147
3282
  this._updateMessaging({
3148
- pendingQuestion: null,
3149
- turns: applyTurnLifecycleForPendingQuestion(this.state.messaging.turns, null)
3283
+ pendingQuestion: {
3284
+ ...previousPendingQuestion,
3285
+ status: "ANSWER_SUBMITTED"
3286
+ },
3287
+ turns: applyTurnLifecycleForPendingQuestion(
3288
+ this.state.messaging.turns,
3289
+ {
3290
+ ...previousPendingQuestion,
3291
+ status: "ANSWER_SUBMITTED"
3292
+ }
3293
+ )
3150
3294
  });
3151
3295
  if (result.data) {
3152
3296
  await this._resumeAcceptedRunOrPoll(curSessionId, result.data.runId);
@@ -3157,9 +3301,15 @@ var ChatMachine = class {
3157
3301
  }
3158
3302
  if (fetchResult) {
3159
3303
  this._updateSession({ session: fetchResult.session });
3160
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3304
+ this._setTurnsFromFetch(
3305
+ fetchResult.turns,
3306
+ fetchResult.pendingQuestion || null
3307
+ );
3161
3308
  } else {
3162
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3309
+ this._updateSession({
3310
+ error: "Failed to load updated session",
3311
+ errorRetryable: true
3312
+ });
3163
3313
  }
3164
3314
  }
3165
3315
  } else if (curSessionId !== "new") {
@@ -3169,20 +3319,32 @@ var ChatMachine = class {
3169
3319
  }
3170
3320
  if (fetchResult) {
3171
3321
  this._updateSession({ session: fetchResult.session });
3172
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3322
+ this._setTurnsFromFetch(
3323
+ fetchResult.turns,
3324
+ fetchResult.pendingQuestion || null
3325
+ );
3173
3326
  } else {
3174
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3327
+ this._updateSession({
3328
+ error: "Failed to load updated session",
3329
+ errorRetryable: true
3330
+ });
3175
3331
  }
3176
3332
  }
3177
3333
  } else {
3178
- this._updateSession({ error: result.error || "Failed to submit answers", errorRetryable: false });
3334
+ this._updateSession({
3335
+ error: result.error || "Failed to submit answers",
3336
+ errorRetryable: false
3337
+ });
3179
3338
  }
3180
3339
  } catch (err) {
3181
3340
  if (this.disposed) {
3182
3341
  return;
3183
3342
  }
3184
3343
  const normalized = normalizeRPCError(err, "Failed to submit answers");
3185
- this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3344
+ this._updateSession({
3345
+ error: normalized.userMessage,
3346
+ errorRetryable: normalized.retryable
3347
+ });
3186
3348
  } finally {
3187
3349
  if (!this.disposed) {
3188
3350
  this._updateMessaging({ loading: false });
@@ -3201,12 +3363,37 @@ var ChatMachine = class {
3201
3363
  return;
3202
3364
  }
3203
3365
  if (result.success) {
3366
+ const submittedQuestion = {
3367
+ ...curPendingQuestion,
3368
+ status: "REJECT_SUBMITTED"
3369
+ };
3204
3370
  this._updateMessaging({
3205
- pendingQuestion: null,
3206
- turns: applyTurnLifecycleForPendingQuestion(this.state.messaging.turns, null)
3371
+ pendingQuestion: submittedQuestion,
3372
+ turns: applyTurnLifecycleForPendingQuestion(
3373
+ this.state.messaging.turns,
3374
+ submittedQuestion
3375
+ )
3207
3376
  });
3208
3377
  if (result.data) {
3209
3378
  await this._resumeAcceptedRunOrPoll(curSessionId, result.data.runId);
3379
+ if (!this.state.messaging.generationInProgress && curSessionId !== "new") {
3380
+ const fetchResult = await this.dataSource.fetchSession(curSessionId);
3381
+ if (this.disposed) {
3382
+ return;
3383
+ }
3384
+ if (fetchResult) {
3385
+ this._updateSession({ session: fetchResult.session });
3386
+ this._setTurnsFromFetch(
3387
+ fetchResult.turns,
3388
+ fetchResult.pendingQuestion || null
3389
+ );
3390
+ } else {
3391
+ this._updateSession({
3392
+ error: "Failed to load updated session",
3393
+ errorRetryable: true
3394
+ });
3395
+ }
3396
+ }
3210
3397
  } else if (curSessionId !== "new") {
3211
3398
  const fetchResult = await this.dataSource.fetchSession(curSessionId);
3212
3399
  if (this.disposed) {
@@ -3214,18 +3401,27 @@ var ChatMachine = class {
3214
3401
  }
3215
3402
  if (fetchResult) {
3216
3403
  this._updateSession({ session: fetchResult.session });
3217
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3404
+ this._setTurnsFromFetch(
3405
+ fetchResult.turns,
3406
+ fetchResult.pendingQuestion || null
3407
+ );
3218
3408
  }
3219
3409
  }
3220
3410
  } else {
3221
- this._updateSession({ error: result.error || "Failed to reject question", errorRetryable: false });
3411
+ this._updateSession({
3412
+ error: result.error || "Failed to reject question",
3413
+ errorRetryable: false
3414
+ });
3222
3415
  }
3223
3416
  } catch (err) {
3224
3417
  if (this.disposed) {
3225
3418
  return;
3226
3419
  }
3227
3420
  const normalized = normalizeRPCError(err, "Failed to reject question");
3228
- this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3421
+ this._updateSession({
3422
+ error: normalized.userMessage,
3423
+ errorRetryable: normalized.retryable
3424
+ });
3229
3425
  }
3230
3426
  }
3231
3427
  // ── Input / queue ───────────────────────────────────────────────────────
@@ -3272,7 +3468,10 @@ var ChatMachine = class {
3272
3468
  return false;
3273
3469
  }
3274
3470
  this._updateInput({
3275
- messageQueue: [...this.state.input.messageQueue, { content, attachments }]
3471
+ messageQueue: [
3472
+ ...this.state.input.messageQueue,
3473
+ { content, attachments }
3474
+ ]
3276
3475
  });
3277
3476
  return true;
3278
3477
  }
@@ -4425,7 +4624,7 @@ init_useTranslation();
4425
4624
  var COPY_FEEDBACK_MS = 2e3;
4426
4625
  var defaultClassNames = {
4427
4626
  root: "flex gap-3 justify-end group",
4428
- wrapper: "flex-1 flex flex-col items-end max-w-[var(--bichat-bubble-max-width)]",
4627
+ wrapper: "flex-1 min-w-0 flex flex-col items-end max-w-[var(--bichat-bubble-max-width)]",
4429
4628
  avatar: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-sm",
4430
4629
  bubble: "bg-primary-600 text-white rounded-2xl rounded-br-sm px-4 py-3 shadow-sm",
4431
4630
  content: "text-sm whitespace-pre-wrap break-words leading-relaxed",
@@ -5989,6 +6188,7 @@ function FullscreenOverlay({ title, onClose, closeLabel, children }) {
5989
6188
  )
5990
6189
  ] });
5991
6190
  }
6191
+ var FULL_WIDTH_CLASS = "w-full min-w-0 max-w-full";
5992
6192
  function getPageNumbers(current, total) {
5993
6193
  if (total <= 7) {
5994
6194
  return Array.from({ length: total }, (_, i) => i + 1);
@@ -6083,6 +6283,8 @@ var InteractiveTableCard = memo(function InteractiveTableCard2({
6083
6283
  const hasHiddenColumns = dt.columns.some((c) => !c.visible);
6084
6284
  const from = dt.totalFilteredRows === 0 ? 0 : (dt.page - 1) * dt.pageSize + 1;
6085
6285
  const to = Math.min(dt.page * dt.pageSize, dt.totalFilteredRows);
6286
+ const loadedRowsCount = table.rows.length;
6287
+ const reportedRowsCount = Math.max(table.totalRows || 0, loadedRowsCount);
6086
6288
  const renderToolbar = () => /* @__PURE__ */ jsx(
6087
6289
  DataTableToolbar,
6088
6290
  {
@@ -6103,9 +6305,12 @@ var InteractiveTableCard = memo(function InteractiveTableCard2({
6103
6305
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
6104
6306
  /* @__PURE__ */ jsx("h4", { className: "truncate text-sm font-semibold text-gray-900 dark:text-gray-100", children: table.title || t("BiChat.Table.QueryResults") }),
6105
6307
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
6106
- dt.totalFilteredRows === table.rows.length ? dt.totalFilteredRows === 1 ? t("BiChat.Table.OneRowLoaded") : t("BiChat.Table.RowsLoaded", { count: String(dt.totalFilteredRows) }) : t("BiChat.DataTable.FilteredRows", {
6308
+ dt.totalFilteredRows === loadedRowsCount ? loadedRowsCount === reportedRowsCount ? loadedRowsCount === 1 ? t("BiChat.Table.OneRowLoaded") : t("BiChat.Table.RowsLoaded", { count: String(loadedRowsCount) }) : t("BiChat.DataTable.FilteredRows", {
6309
+ filtered: String(loadedRowsCount),
6310
+ total: String(reportedRowsCount)
6311
+ }) : t("BiChat.DataTable.FilteredRows", {
6107
6312
  filtered: String(dt.totalFilteredRows),
6108
- total: String(table.rows.length)
6313
+ total: String(loadedRowsCount)
6109
6314
  }),
6110
6315
  table.truncated ? ` ${t("BiChat.Table.TruncatedSuffix")}` : ""
6111
6316
  ] })
@@ -6120,7 +6325,7 @@ var InteractiveTableCard = memo(function InteractiveTableCard2({
6120
6325
  }
6121
6326
  )
6122
6327
  ] });
6123
- const renderTable = (scrollClass) => /* @__PURE__ */ jsx("div", { className: scrollClass, children: /* @__PURE__ */ jsxs("table", { className: "min-w-full border-collapse text-sm", children: [
6328
+ const renderTable = (scrollClass) => /* @__PURE__ */ jsx("div", { className: `${FULL_WIDTH_CLASS} ${scrollClass}`, children: /* @__PURE__ */ jsxs("table", { className: "min-w-full border-collapse text-sm", children: [
6124
6329
  /* @__PURE__ */ jsx(
6125
6330
  DataTableHeader,
6126
6331
  {
@@ -6261,7 +6466,7 @@ var InteractiveTableCard = memo(function InteractiveTableCard2({
6261
6466
  ] });
6262
6467
  const renderTruncationNotice = () => table.truncated ? /* @__PURE__ */ jsx("p", { className: "border-t border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-700 dark:border-amber-700/60 dark:bg-amber-900/20 dark:text-amber-300", children: t("BiChat.Table.TruncatedNotice") }) : null;
6263
6468
  const fillHeight = host?.isFullscreen ?? false;
6264
- const sectionClassName = host ? `w-full min-w-0 overflow-hidden${fillHeight ? " flex flex-col flex-1" : ""}` : "w-full min-w-0 rounded-xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/40 overflow-hidden";
6469
+ const sectionClassName = host ? `${FULL_WIDTH_CLASS} overflow-hidden${fillHeight ? " flex flex-col flex-1" : ""}` : `${FULL_WIDTH_CLASS} rounded-xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/40 overflow-hidden`;
6265
6470
  return /* @__PURE__ */ jsxs(Fragment, { children: [
6266
6471
  /* @__PURE__ */ jsxs("section", { className: sectionClassName, children: [
6267
6472
  renderToolbar(),
@@ -6414,7 +6619,7 @@ var TabbedTableGroup = memo(function TabbedTableGroup2({
6414
6619
  const tabs = useMemo(
6415
6620
  () => tables.map((table, i) => ({
6416
6621
  id: table.id,
6417
- label: `${table.title || `${t("BiChat.Table.QueryResults")} ${i + 1}`} (${table.rows.length})`
6622
+ label: `${table.title || `${t("BiChat.Table.QueryResults")} ${i + 1}`} (${Math.max(table.totalRows || 0, table.rows.length)})`
6418
6623
  })),
6419
6624
  [tables, t]
6420
6625
  );
@@ -6785,7 +6990,9 @@ function DownloadCard({ artifact }) {
6785
6990
  );
6786
6991
  }
6787
6992
  init_useTranslation();
6788
- function InlineQuestionForm({ pendingQuestion }) {
6993
+ function InlineQuestionForm({
6994
+ pendingQuestion
6995
+ }) {
6789
6996
  const { handleSubmitQuestionAnswers, handleRejectPendingQuestion, loading } = useChatMessaging();
6790
6997
  const { t } = useTranslation();
6791
6998
  const [currentStep, setCurrentStep] = useState(0);
@@ -6796,6 +7003,7 @@ function InlineQuestionForm({ pendingQuestion }) {
6796
7003
  const isLastStep = currentStep === questions.length - 1;
6797
7004
  const isFirstStep = currentStep === 0;
6798
7005
  const totalSteps = questions.length;
7006
+ const isFailedRetry = pendingQuestion.status === "ANSWER_RESUME_FAILED" || pendingQuestion.status === "REJECT_RESUME_FAILED";
6799
7007
  const currentAnswer = answers[currentQuestion?.id];
6800
7008
  const currentOtherText = otherTexts[currentQuestion?.id] || "";
6801
7009
  const handleOptionChange = useCallback(
@@ -6924,7 +7132,13 @@ function InlineQuestionForm({ pendingQuestion }) {
6924
7132
  const canProceed = isCurrentAnswerValid();
6925
7133
  return /* @__PURE__ */ jsx("div", { className: "animate-slide-up rounded-2xl border border-gray-200 dark:border-gray-700/50 bg-gradient-to-b from-primary-50/80 to-white dark:from-primary-950/30 dark:to-gray-900/80 shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
6926
7134
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-4 pt-4 pb-3", children: [
6927
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-7 h-7 rounded-lg bg-primary-100 dark:bg-primary-900/40", children: /* @__PURE__ */ jsx(ChatCircleDots, { className: "w-4 h-4 text-primary-600 dark:text-primary-400", weight: "fill" }) }),
7135
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-7 h-7 rounded-lg bg-primary-100 dark:bg-primary-900/40", children: /* @__PURE__ */ jsx(
7136
+ ChatCircleDots,
7137
+ {
7138
+ className: "w-4 h-4 text-primary-600 dark:text-primary-400",
7139
+ weight: "fill"
7140
+ }
7141
+ ) }),
6928
7142
  /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
6929
7143
  /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wide text-primary-600 dark:text-primary-400", children: t("BiChat.InlineQuestion.InputNeeded") }),
6930
7144
  totalSteps > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[11px] tabular-nums text-gray-400 dark:text-gray-500", children: [
@@ -6945,6 +7159,10 @@ function InlineQuestionForm({ pendingQuestion }) {
6945
7159
  }
6946
7160
  )
6947
7161
  ] }),
7162
+ isFailedRetry && /* @__PURE__ */ jsxs("div", { className: "mx-4 mb-3 rounded-xl border border-amber-200 dark:border-amber-700/40 bg-amber-50/80 dark:bg-amber-950/20 px-3 py-2", children: [
7163
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-amber-800 dark:text-amber-300", children: "Continuing after your last response failed." }),
7164
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-amber-700/80 dark:text-amber-200/80", children: "Review the answer and submit again, or dismiss the question if you want to skip it." })
7165
+ ] }),
6948
7166
  totalSteps > 1 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 px-4 pb-3", children: questions.map((_, index) => {
6949
7167
  const isCompleted = index < currentStep;
6950
7168
  const isCurrent = index === currentStep;
@@ -6998,10 +7216,16 @@ function InlineQuestionForm({ pendingQuestion }) {
6998
7216
  className: "sr-only"
6999
7217
  }
7000
7218
  ),
7001
- /* @__PURE__ */ jsx("span", { className: [
7002
- "text-sm transition-colors duration-150",
7003
- isSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7004
- ].join(" "), children: option.label })
7219
+ /* @__PURE__ */ jsx(
7220
+ "span",
7221
+ {
7222
+ className: [
7223
+ "text-sm transition-colors duration-150",
7224
+ isSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7225
+ ].join(" "),
7226
+ children: option.label
7227
+ }
7228
+ )
7005
7229
  ]
7006
7230
  },
7007
7231
  option.id
@@ -7038,10 +7262,16 @@ function InlineQuestionForm({ pendingQuestion }) {
7038
7262
  className: "sr-only"
7039
7263
  }
7040
7264
  ),
7041
- /* @__PURE__ */ jsx("span", { className: [
7042
- "text-sm transition-colors duration-150",
7043
- isOtherSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7044
- ].join(" "), children: t("BiChat.InlineQuestion.OtherOption") })
7265
+ /* @__PURE__ */ jsx(
7266
+ "span",
7267
+ {
7268
+ className: [
7269
+ "text-sm transition-colors duration-150",
7270
+ isOtherSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7271
+ ].join(" "),
7272
+ children: t("BiChat.InlineQuestion.OtherOption")
7273
+ }
7274
+ )
7045
7275
  ]
7046
7276
  }
7047
7277
  ),
@@ -7473,12 +7703,14 @@ function DebugPanel({ trace }) {
7473
7703
  // ui/src/bichat/components/AssistantMessage.tsx
7474
7704
  init_useTranslation();
7475
7705
  var MarkdownRenderer2 = lazy(
7476
- () => Promise.resolve().then(() => (init_MarkdownRenderer(), MarkdownRenderer_exports)).then((module) => ({ default: module.MarkdownRenderer }))
7706
+ () => Promise.resolve().then(() => (init_MarkdownRenderer(), MarkdownRenderer_exports)).then((module) => ({
7707
+ default: module.MarkdownRenderer
7708
+ }))
7477
7709
  );
7478
7710
  var COPY_FEEDBACK_MS2 = 2e3;
7479
7711
  var defaultClassNames2 = {
7480
- root: "flex gap-3 group",
7481
- wrapper: "flex-1 min-w-0 flex flex-col gap-3 max-w-[var(--bichat-bubble-assistant-max-width,85%)]",
7712
+ root: "flex min-w-0 gap-3 group",
7713
+ wrapper: "flex-1 w-full min-w-0 flex flex-col gap-3 max-w-[var(--bichat-bubble-assistant-max-width,85%)]",
7482
7714
  avatar: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-xs",
7483
7715
  bubble: "bg-white dark:bg-gray-800 rounded-2xl rounded-bl-sm px-4 py-3 shadow-sm",
7484
7716
  codeOutputs: "",
@@ -7531,7 +7763,9 @@ function AssistantMessage({
7531
7763
  const { t } = useTranslation();
7532
7764
  const [explanationExpanded, setExplanationExpanded] = useState(false);
7533
7765
  const [isCopied, setIsCopied] = useState(false);
7534
- const copyFeedbackTimeoutRef = useRef(null);
7766
+ const copyFeedbackTimeoutRef = useRef(
7767
+ null
7768
+ );
7535
7769
  const classes = mergeClassNames2(defaultClassNames2, classNameOverrides);
7536
7770
  const isSystemMessage = turn.role === "system";
7537
7771
  const avatarClassName = isSystemMessage ? "flex-shrink-0 w-8 h-8 rounded-full bg-gray-500 dark:bg-gray-600 flex items-center justify-center text-white font-medium text-xs" : classes.avatar;
@@ -7547,8 +7781,11 @@ function AssistantMessage({
7547
7781
  const hasContent = turn.content?.trim().length > 0;
7548
7782
  const hasExplanation = !!turn.explanation?.trim();
7549
7783
  const isAwaitingHumanInput = turn.lifecycle === "waiting_for_human_input";
7550
- const pendingQuestionMatchesTurn = !!pendingQuestion && pendingQuestion.status === "PENDING" && (pendingQuestion.turnId === turnId || pendingQuestion.turnId === turn.id || !pendingQuestion.turnId && isLastTurn);
7784
+ const pendingQuestionStatus = pendingQuestion?.status;
7785
+ const pendingQuestionMatchesTurn = !!pendingQuestion && (pendingQuestionStatus === "PENDING" || pendingQuestionStatus === "ANSWER_SUBMITTED" || pendingQuestionStatus === "REJECT_SUBMITTED" || pendingQuestionStatus === "ANSWER_RESUME_FAILED" || pendingQuestionStatus === "REJECT_RESUME_FAILED") && (pendingQuestion.turnId === turnId || pendingQuestion.turnId === turn.id || !pendingQuestion.turnId && isLastTurn);
7551
7786
  const hasPendingQuestion = pendingQuestionMatchesTurn && !!pendingQuestion;
7787
+ const showQuestionForm = hasPendingQuestion && (pendingQuestionStatus === "PENDING" || pendingQuestionStatus === "ANSWER_RESUME_FAILED" || pendingQuestionStatus === "REJECT_RESUME_FAILED");
7788
+ const showResumeState = hasPendingQuestion && (pendingQuestionStatus === "ANSWER_SUBMITTED" || pendingQuestionStatus === "REJECT_SUBMITTED");
7552
7789
  const hasCodeOutputs = !!turn.codeOutputs?.length;
7553
7790
  const hasChart = !!turn.charts?.length;
7554
7791
  const hasTables = !!turn.renderTables?.length;
@@ -7556,8 +7793,8 @@ function AssistantMessage({
7556
7793
  const hasDebug = showDebug && !!turn.debug;
7557
7794
  const hasAnyRenderedContent = hasContent || hasExplanation || hasCodeOutputs || hasChart || hasTables || hasArtifacts || hasDebug;
7558
7795
  const canRegenerate = !!onRegenerate && !!turnId && !isSystemMessage && isLastTurn;
7559
- const renderMode = hasPendingQuestion ? "hitl_form" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : canRegenerate ? "retry" : "empty";
7560
- const showInlineRetry = renderMode === "retry";
7796
+ const showInlineRetry = shouldRenderInlineRetry(turn, canRegenerate) && !hasAnyRenderedContent;
7797
+ const renderMode = showQuestionForm ? "hitl_form" : showResumeState ? "hitl_resuming" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : showInlineRetry ? "retry" : "empty";
7561
7798
  const handleCopyClick = useCallback(async () => {
7562
7799
  try {
7563
7800
  if (onCopy) {
@@ -7584,7 +7821,9 @@ function AssistantMessage({
7584
7821
  }
7585
7822
  }, [onRegenerate, turnId]);
7586
7823
  const timestamp = formatRelativeTime(turn.createdAt, t);
7587
- const avatarSlotProps = { text: isSystemMessage ? "SYS" : "AI" };
7824
+ const avatarSlotProps = {
7825
+ text: isSystemMessage ? "SYS" : "AI"
7826
+ };
7588
7827
  const contentSlotProps = {
7589
7828
  content: turn.content,
7590
7829
  citations: turn.citations,
@@ -7627,11 +7866,21 @@ function AssistantMessage({
7627
7866
  return slot;
7628
7867
  };
7629
7868
  return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
7630
- !hideAvatar && /* @__PURE__ */ jsx("div", { className: avatarClassName, children: renderSlot(slots?.avatar, avatarSlotProps, isSystemMessage ? "SYS" : "AI") }),
7869
+ !hideAvatar && /* @__PURE__ */ jsx("div", { className: avatarClassName, children: renderSlot(
7870
+ slots?.avatar,
7871
+ avatarSlotProps,
7872
+ isSystemMessage ? "SYS" : "AI"
7873
+ ) }),
7631
7874
  /* @__PURE__ */ jsxs("div", { className: classes.wrapper, children: [
7632
- /* @__PURE__ */ jsx(AnimatePresence, { children: showInlineRetry && /* @__PURE__ */ jsx(RetryActionArea, { onRetry: () => {
7633
- void handleRegenerateClick();
7634
- } }, "inline-retry") }),
7875
+ /* @__PURE__ */ jsx(AnimatePresence, { children: showInlineRetry && /* @__PURE__ */ jsx(
7876
+ RetryActionArea,
7877
+ {
7878
+ onRetry: () => {
7879
+ void handleRegenerateClick();
7880
+ }
7881
+ },
7882
+ "inline-retry"
7883
+ ) }),
7635
7884
  turn.codeOutputs && turn.codeOutputs.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.codeOutputs, children: renderSlot(
7636
7885
  slots?.codeOutputs,
7637
7886
  codeOutputsSlotProps,
@@ -7714,7 +7963,13 @@ function AssistantMessage({
7714
7963
  ]
7715
7964
  }
7716
7965
  ),
7717
- explanationExpanded && /* @__PURE__ */ jsx("div", { className: "pt-3 text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { children: t("BiChat.Common.Loading") }), children: /* @__PURE__ */ jsx(MarkdownRenderer2, { content: turn.explanation }) }) })
7966
+ explanationExpanded && /* @__PURE__ */ jsx("div", { className: "pt-3 text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsx(
7967
+ Suspense,
7968
+ {
7969
+ fallback: /* @__PURE__ */ jsx("div", { children: t("BiChat.Common.Loading") }),
7970
+ children: /* @__PURE__ */ jsx(MarkdownRenderer2, { content: turn.explanation })
7971
+ }
7972
+ ) })
7718
7973
  ] })
7719
7974
  ) }),
7720
7975
  showDebug && /* @__PURE__ */ jsx(DebugPanel, { trace: turn.debug })
@@ -7722,40 +7977,56 @@ function AssistantMessage({
7722
7977
  turn.artifacts && turn.artifacts.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.artifacts, children: renderSlot(
7723
7978
  slots?.artifacts,
7724
7979
  artifactsSlotProps,
7725
- turn.artifacts.map((artifact, index) => /* @__PURE__ */ jsx(DownloadCard, { artifact }, `${artifact.filename}-${index}`))
7980
+ turn.artifacts.map((artifact, index) => /* @__PURE__ */ jsx(
7981
+ DownloadCard,
7982
+ {
7983
+ artifact
7984
+ },
7985
+ `${artifact.filename}-${index}`
7986
+ ))
7726
7987
  ) }),
7727
7988
  renderMode === "hitl_waiting" && /* @__PURE__ */ jsxs("div", { className: "animate-slide-up rounded-2xl border border-primary-200 dark:border-primary-700/40 bg-gradient-to-b from-primary-50/70 to-white dark:from-primary-900/20 dark:to-gray-900/80 shadow-sm p-4", children: [
7728
7989
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-primary-700 dark:text-primary-300", children: t("BiChat.InlineQuestion.InputNeeded") }),
7729
7990
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: t("BiChat.InlineQuestion.WaitingForDetails") })
7730
7991
  ] }),
7992
+ renderMode === "hitl_resuming" && /* @__PURE__ */ jsxs("div", { className: "animate-slide-up rounded-2xl border border-emerald-200 dark:border-emerald-700/40 bg-gradient-to-b from-emerald-50/80 to-white dark:from-emerald-950/20 dark:to-gray-900/80 shadow-sm p-4", children: [
7993
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-emerald-700 dark:text-emerald-300", children: pendingQuestion?.status === "REJECT_SUBMITTED" ? "Dismissal submitted" : "Answer submitted" }),
7994
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: "Continuing the run. This state will update automatically when the resume finishes." })
7995
+ ] }),
7731
7996
  renderMode === "hitl_form" && pendingQuestion && /* @__PURE__ */ jsx(InlineQuestionForm, { pendingQuestion }),
7732
- hasContent && !hideActions && /* @__PURE__ */ jsx("div", { className: `${classes.actions} ${isCopied ? "opacity-100" : ""}`, children: renderSlot(
7733
- slots?.actions,
7734
- actionsSlotProps,
7735
- /* @__PURE__ */ jsxs(Fragment, { children: [
7736
- !hideTimestamp && /* @__PURE__ */ jsx("span", { className: classes.timestamp, children: timestamp }),
7737
- /* @__PURE__ */ jsx(
7738
- "button",
7739
- {
7740
- onClick: handleCopyClick,
7741
- className: `cursor-pointer ${classes.actionButton} ${isCopied ? "text-green-600 dark:text-green-400" : ""}`,
7742
- "aria-label": t("BiChat.Message.CopyMessage"),
7743
- title: isCopied ? t("BiChat.Message.Copied") : t("BiChat.Message.Copy"),
7744
- children: isCopied ? /* @__PURE__ */ jsx(Check, { size: 14, weight: "bold" }) : /* @__PURE__ */ jsx(Copy, { size: 14, weight: "regular" })
7745
- }
7746
- ),
7747
- canRegenerate && /* @__PURE__ */ jsx(
7748
- "button",
7749
- {
7750
- onClick: handleRegenerateClick,
7751
- className: `cursor-pointer ${classes.actionButton}`,
7752
- "aria-label": t("BiChat.Message.Regenerate"),
7753
- title: t("BiChat.Message.Regenerate"),
7754
- children: /* @__PURE__ */ jsx(ArrowsClockwise, { size: 14, weight: "regular" })
7755
- }
7997
+ hasContent && !hideActions && /* @__PURE__ */ jsx(
7998
+ "div",
7999
+ {
8000
+ className: `${classes.actions} ${isCopied ? "opacity-100" : ""}`,
8001
+ children: renderSlot(
8002
+ slots?.actions,
8003
+ actionsSlotProps,
8004
+ /* @__PURE__ */ jsxs(Fragment, { children: [
8005
+ !hideTimestamp && /* @__PURE__ */ jsx("span", { className: classes.timestamp, children: timestamp }),
8006
+ /* @__PURE__ */ jsx(
8007
+ "button",
8008
+ {
8009
+ onClick: handleCopyClick,
8010
+ className: `cursor-pointer ${classes.actionButton} ${isCopied ? "text-green-600 dark:text-green-400" : ""}`,
8011
+ "aria-label": t("BiChat.Message.CopyMessage"),
8012
+ title: isCopied ? t("BiChat.Message.Copied") : t("BiChat.Message.Copy"),
8013
+ children: isCopied ? /* @__PURE__ */ jsx(Check, { size: 14, weight: "bold" }) : /* @__PURE__ */ jsx(Copy, { size: 14, weight: "regular" })
8014
+ }
8015
+ ),
8016
+ canRegenerate && /* @__PURE__ */ jsx(
8017
+ "button",
8018
+ {
8019
+ onClick: handleRegenerateClick,
8020
+ className: `cursor-pointer ${classes.actionButton}`,
8021
+ "aria-label": t("BiChat.Message.Regenerate"),
8022
+ title: t("BiChat.Message.Regenerate"),
8023
+ children: /* @__PURE__ */ jsx(ArrowsClockwise, { size: 14, weight: "regular" })
8024
+ }
8025
+ )
8026
+ ] })
7756
8027
  )
7757
- ] })
7758
- ) })
8028
+ }
8029
+ )
7759
8030
  ] })
7760
8031
  ] });
7761
8032
  }
@@ -7949,7 +8220,7 @@ function AssistantTurnView({
7949
8220
  );
7950
8221
  }
7951
8222
  var defaultClassNames3 = {
7952
- root: "space-y-4",
8223
+ root: "space-y-4 min-w-0",
7953
8224
  userTurn: "",
7954
8225
  assistantTurn: ""
7955
8226
  };
@@ -8782,9 +9053,9 @@ function MessageListSkeleton() {
8782
9053
  ] });
8783
9054
  }
8784
9055
  function StreamingBubble({ content, normalizedContent }) {
8785
- return /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
9056
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 gap-3", children: [
8786
9057
  /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-xs", children: "AI" }),
8787
- /* @__PURE__ */ jsxs("div", { className: "flex-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-2xl rounded-bl-sm px-4 py-3 text-gray-900 dark:text-gray-100", style: { maxWidth: "var(--bichat-bubble-assistant-max-width, 85%)" }, children: [
9058
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-2xl rounded-bl-sm px-4 py-3 text-gray-900 dark:text-gray-100", style: { maxWidth: "var(--bichat-bubble-assistant-max-width, 85%)" }, children: [
8788
9059
  /* @__PURE__ */ jsx(
8789
9060
  Suspense,
8790
9061
  {
@@ -8815,8 +9086,8 @@ function MessageList({ renderUserTurn, renderAssistantTurn, thinkingVerbs, readO
8815
9086
  );
8816
9087
  const showAuthorNames = Boolean(session?.isGroup);
8817
9088
  const showEphemeral = showActivityTrace || showTypingIndicator;
8818
- return /* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-h-0", children: [
8819
- /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full overflow-y-auto overflow-x-hidden px-4 py-6", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto space-y-6", children: [
9089
+ return /* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0 min-h-0", children: [
9090
+ /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full overflow-y-auto overflow-x-hidden px-4 py-6", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full min-w-0 space-y-6", children: [
8820
9091
  fetching && turns.length === 0 && /* @__PURE__ */ jsx(MessageListSkeleton, {}),
8821
9092
  turns.map((turn, index) => {
8822
9093
  const turnDate = new Date(turn.createdAt);
@@ -10228,6 +10499,14 @@ function readString(value) {
10228
10499
  return trimmed.length > 0 ? trimmed : null;
10229
10500
  }
10230
10501
  function readPositiveInteger(value) {
10502
+ if (typeof value === "string") {
10503
+ const trimmed = value.trim();
10504
+ if (!/^\d+$/.test(trimmed)) {
10505
+ return null;
10506
+ }
10507
+ const parsed = Number(trimmed);
10508
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
10509
+ }
10231
10510
  if (typeof value !== "number" || !Number.isFinite(value)) {
10232
10511
  return null;
10233
10512
  }
@@ -10278,7 +10557,7 @@ function parseRenderTableDataFromObject(parsed, fallbackId) {
10278
10557
  const headers = headersRaw.length === columns.length ? headersRaw : columns;
10279
10558
  const columnTypesRaw = Array.isArray(parsed.column_types) ? parsed.column_types : Array.isArray(parsed.columnTypes) ? parsed.columnTypes : [];
10280
10559
  const columnTypes = columnTypesRaw.length === columns.length ? columnTypesRaw.map((t) => readString(t) || "string") : void 0;
10281
- const totalRows = readPositiveInteger(parsed.total_rows) || readPositiveInteger(parsed.totalRows) || rows.length;
10560
+ const totalRows = readPositiveInteger(parsed.total_rows) || readPositiveInteger(parsed.totalRows) || readPositiveInteger(parsed.row_count) || readPositiveInteger(parsed.rowCount) || rows.length;
10282
10561
  const pageSize = readPositiveInteger(parsed.page_size) || readPositiveInteger(parsed.pageSize) || 25;
10283
10562
  const query = readString(parsed.query) || readString(parsed.sql);
10284
10563
  if (!query) {
@@ -12052,7 +12331,7 @@ function ChatSessionCore({
12052
12331
  return /* @__PURE__ */ jsxs(
12053
12332
  "main",
12054
12333
  {
12055
- className: `flex min-h-0 flex-1 flex-col overflow-hidden bg-gray-50 dark:bg-gray-900 ${className}`,
12334
+ className: `flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden bg-gray-50 dark:bg-gray-900 ${className}`,
12056
12335
  children: [
12057
12336
  headerSlot || /* @__PURE__ */ jsx(
12058
12337
  ChatHeader,
@@ -14559,10 +14838,14 @@ function Sidebar2({
14559
14838
  sessions: Array.isArray(group.sessions) ? group.sessions : []
14560
14839
  })) : [];
14561
14840
  }, [unpinnedSessions, t]);
14841
+ const orderedUnpinnedSessions = useMemo(
14842
+ () => sessionGroups.flatMap((group) => group.sessions),
14843
+ [sessionGroups]
14844
+ );
14562
14845
  const collapsedIndicators = useMemo(() => {
14563
14846
  const seen = /* @__PURE__ */ new Set();
14564
14847
  const result = [];
14565
- for (const s of [...pinnedSessions, ...unpinnedSessions]) {
14848
+ for (const s of [...pinnedSessions, ...orderedUnpinnedSessions]) {
14566
14849
  if (seen.has(s.id)) {
14567
14850
  continue;
14568
14851
  }
@@ -14573,7 +14856,7 @@ function Sidebar2({
14573
14856
  }
14574
14857
  }
14575
14858
  return result;
14576
- }, [pinnedSessions, unpinnedSessions]);
14859
+ }, [pinnedSessions, orderedUnpinnedSessions]);
14577
14860
  const totalSessionCount = filteredSessions.length;
14578
14861
  const overflowCount = Math.max(0, totalSessionCount - collapsedIndicators.length);
14579
14862
  const handleSessionListKeyDown = useCallback(
@@ -15394,7 +15677,7 @@ function BiChatLayout({
15394
15677
  const content = routeKey ? /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: /* @__PURE__ */ jsx(
15395
15678
  motion.div,
15396
15679
  {
15397
- className: "flex flex-1 min-h-0",
15680
+ className: "flex flex-1 min-w-0 min-h-0",
15398
15681
  initial: { opacity: 0, y: 4 },
15399
15682
  animate: { opacity: 1, y: 0 },
15400
15683
  exit: { opacity: 0, y: -4 },
@@ -15402,7 +15685,7 @@ function BiChatLayout({
15402
15685
  children
15403
15686
  },
15404
15687
  routeKey
15405
- ) }) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 min-h-0", children });
15688
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 min-w-0 min-h-0", children });
15406
15689
  return /* @__PURE__ */ jsxs("div", { className: `relative flex flex-1 w-full h-full min-h-0 overflow-hidden ${className}`, children: [
15407
15690
  /* @__PURE__ */ jsx(SkipLink, {}),
15408
15691
  /* @__PURE__ */ jsx("div", { className: "hidden md:block", children: renderSidebar({}) }),
@@ -15438,7 +15721,7 @@ function BiChatLayout({
15438
15721
  "sidebar-drawer"
15439
15722
  )
15440
15723
  ] }) }),
15441
- /* @__PURE__ */ jsxs("main", { id: "main-content", className: "relative flex-1 flex flex-col min-h-0 overflow-hidden", children: [
15724
+ /* @__PURE__ */ jsxs("main", { id: "main-content", className: "relative flex-1 min-w-0 flex flex-col min-h-0 overflow-hidden", children: [
15442
15725
  isMobile && !isMobileOpen && /* @__PURE__ */ jsx(
15443
15726
  "button",
15444
15727
  {
@@ -17064,7 +17347,7 @@ function useHttpDataSourceConfigFromApplet(options) {
17064
17347
  streamEndpoint,
17065
17348
  csrfToken,
17066
17349
  rpcTimeoutMs: options?.rpcTimeoutMs ?? 12e4,
17067
- streamConnectTimeoutMs: options?.streamConnectTimeoutMs ?? 3e4
17350
+ streamConnectTimeoutMs: options?.streamConnectTimeoutMs
17068
17351
  };
17069
17352
  }, [options?.rpcTimeoutMs, options?.streamConnectTimeoutMs]);
17070
17353
  }
@@ -17473,7 +17756,10 @@ function toSession(session) {
17473
17756
  function toSessionArtifact(artifact) {
17474
17757
  const rawCreatedAt = readNonEmptyString(artifact.createdAt);
17475
17758
  if (!rawCreatedAt) {
17476
- warnMalformedSessionPayload("Artifact missing createdAt; defaulting to epoch", { id: artifact.id });
17759
+ warnMalformedSessionPayload(
17760
+ "Artifact missing createdAt; defaulting to epoch",
17761
+ { id: artifact.id }
17762
+ );
17477
17763
  }
17478
17764
  const createdAt = rawCreatedAt ?? "1970-01-01T00:00:00.000Z";
17479
17765
  return {
@@ -17495,6 +17781,21 @@ function normalizeQuestionType2(rawType) {
17495
17781
  const normalized = readString2(rawType).trim().toUpperCase().replace(/[\s-]+/g, "_");
17496
17782
  return normalized === "MULTIPLE_CHOICE" ? "MULTIPLE_CHOICE" : "SINGLE_CHOICE";
17497
17783
  }
17784
+ function normalizePendingQuestionStatus(rawStatus) {
17785
+ const normalized = readString2(rawStatus).trim().toUpperCase();
17786
+ switch (normalized) {
17787
+ case "ANSWER_SUBMITTED":
17788
+ case "REJECT_SUBMITTED":
17789
+ case "ANSWER_RESUME_FAILED":
17790
+ case "REJECT_RESUME_FAILED":
17791
+ case "ANSWERED":
17792
+ case "REJECTED":
17793
+ case "CANCELLED":
17794
+ return normalized;
17795
+ default:
17796
+ return "PENDING";
17797
+ }
17798
+ }
17498
17799
  function normalizeMessageRole(rawRole) {
17499
17800
  const normalized = readString2(rawRole).trim().toLowerCase();
17500
17801
  if (normalized === "user" /* User */) {
@@ -17510,11 +17811,17 @@ function normalizeMessageRole(rawRole) {
17510
17811
  }
17511
17812
  function sanitizeAttachment(rawAttachment, turnId, index) {
17512
17813
  if (!isRecord2(rawAttachment)) {
17513
- warnMalformedSessionPayload("Dropped malformed attachment entry", { turnId, index });
17814
+ warnMalformedSessionPayload("Dropped malformed attachment entry", {
17815
+ turnId,
17816
+ index
17817
+ });
17514
17818
  return null;
17515
17819
  }
17516
17820
  const filename = readString2(rawAttachment.filename, "attachment");
17517
- const mimeType = readString2(rawAttachment.mimeType, "application/octet-stream");
17821
+ const mimeType = readString2(
17822
+ rawAttachment.mimeType,
17823
+ "application/octet-stream"
17824
+ );
17518
17825
  const id = readNonEmptyString(rawAttachment.id) || void 0;
17519
17826
  const clientKey = readNonEmptyString(rawAttachment.clientKey) || id || `${turnId}-attachment-${index}`;
17520
17827
  return {
@@ -17550,7 +17857,10 @@ function sanitizeAssistantArtifacts(rawArtifacts, turnId) {
17550
17857
  for (let i = 0; i < rawArtifacts.length; i++) {
17551
17858
  const raw = rawArtifacts[i];
17552
17859
  if (!isRecord2(raw)) {
17553
- warnMalformedSessionPayload("Dropped malformed assistant artifact", { turnId, index: i });
17860
+ warnMalformedSessionPayload("Dropped malformed assistant artifact", {
17861
+ turnId,
17862
+ index: i
17863
+ });
17554
17864
  continue;
17555
17865
  }
17556
17866
  const type = readString2(raw.type).toLowerCase();
@@ -17559,7 +17869,10 @@ function sanitizeAssistantArtifacts(rawArtifacts, turnId) {
17559
17869
  }
17560
17870
  const url = readNonEmptyString(raw.url);
17561
17871
  if (!url) {
17562
- warnMalformedSessionPayload("Dropped assistant artifact without url", { turnId, index: i });
17872
+ warnMalformedSessionPayload("Dropped assistant artifact without url", {
17873
+ turnId,
17874
+ index: i
17875
+ });
17563
17876
  continue;
17564
17877
  }
17565
17878
  artifacts.push({
@@ -17578,12 +17891,16 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17578
17891
  return void 0;
17579
17892
  }
17580
17893
  if (!isRecord2(rawAssistantTurn)) {
17581
- warnMalformedSessionPayload("Dropped malformed assistant turn payload", { turnId });
17894
+ warnMalformedSessionPayload("Dropped malformed assistant turn payload", {
17895
+ turnId
17896
+ });
17582
17897
  return void 0;
17583
17898
  }
17584
17899
  const assistantID = readNonEmptyString(rawAssistantTurn.id);
17585
17900
  if (!assistantID) {
17586
- warnMalformedSessionPayload("Dropped assistant turn without id", { turnId });
17901
+ warnMalformedSessionPayload("Dropped assistant turn without id", {
17902
+ turnId
17903
+ });
17587
17904
  return void 0;
17588
17905
  }
17589
17906
  const citations = Array.isArray(rawAssistantTurn.citations) ? rawAssistantTurn.citations.filter((item) => isRecord2(item)).map((item, index) => ({
@@ -17620,17 +17937,27 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17620
17937
  schemaVersion: readNonEmptyString(rawAssistantTurn.debug.schemaVersion) || void 0,
17621
17938
  startedAt: readNonEmptyString(rawAssistantTurn.debug.startedAt) || void 0,
17622
17939
  completedAt: readNonEmptyString(rawAssistantTurn.debug.completedAt) || void 0,
17623
- generationMs: readOptionalFiniteNumber(rawAssistantTurn.debug.generationMs),
17940
+ generationMs: readOptionalFiniteNumber(
17941
+ rawAssistantTurn.debug.generationMs
17942
+ ),
17624
17943
  traceId: readNonEmptyString(rawAssistantTurn.debug.traceId) || void 0,
17625
17944
  traceUrl: readNonEmptyString(rawAssistantTurn.debug.traceUrl) || void 0,
17626
17945
  sessionId: readNonEmptyString(rawAssistantTurn.debug.sessionId) || void 0,
17627
17946
  thinking: readNonEmptyString(rawAssistantTurn.debug.thinking) || void 0,
17628
17947
  observationReason: readNonEmptyString(rawAssistantTurn.debug.observationReason) || void 0,
17629
17948
  usage: isRecord2(rawAssistantTurn.debug.usage) ? {
17630
- promptTokens: readFiniteNumber(rawAssistantTurn.debug.usage.promptTokens),
17631
- completionTokens: readFiniteNumber(rawAssistantTurn.debug.usage.completionTokens),
17632
- totalTokens: readFiniteNumber(rawAssistantTurn.debug.usage.totalTokens),
17633
- cachedTokens: readOptionalFiniteNumber(rawAssistantTurn.debug.usage.cachedTokens),
17949
+ promptTokens: readFiniteNumber(
17950
+ rawAssistantTurn.debug.usage.promptTokens
17951
+ ),
17952
+ completionTokens: readFiniteNumber(
17953
+ rawAssistantTurn.debug.usage.completionTokens
17954
+ ),
17955
+ totalTokens: readFiniteNumber(
17956
+ rawAssistantTurn.debug.usage.totalTokens
17957
+ ),
17958
+ cachedTokens: readOptionalFiniteNumber(
17959
+ rawAssistantTurn.debug.usage.cachedTokens
17960
+ ),
17634
17961
  cost: readOptionalFiniteNumber(rawAssistantTurn.debug.usage.cost)
17635
17962
  } : void 0,
17636
17963
  tools: Array.isArray(rawAssistantTurn.debug.tools) ? rawAssistantTurn.debug.tools.filter((tool) => isRecord2(tool)).map((tool) => ({
@@ -17648,7 +17975,9 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17648
17975
  provider: readNonEmptyString(attempt.provider) || void 0,
17649
17976
  finishReason: readNonEmptyString(attempt.finishReason) || void 0,
17650
17977
  promptTokens: readOptionalFiniteNumber(attempt.promptTokens),
17651
- completionTokens: readOptionalFiniteNumber(attempt.completionTokens),
17978
+ completionTokens: readOptionalFiniteNumber(
17979
+ attempt.completionTokens
17980
+ ),
17652
17981
  totalTokens: readOptionalFiniteNumber(attempt.totalTokens),
17653
17982
  cachedTokens: readOptionalFiniteNumber(attempt.cachedTokens),
17654
17983
  cost: readOptionalFiniteNumber(attempt.cost),
@@ -17717,16 +18046,25 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17717
18046
  }
17718
18047
  function sanitizeConversationTurn(rawTurn, index, fallbackSessionID) {
17719
18048
  if (!isRecord2(rawTurn)) {
17720
- warnMalformedSessionPayload("Dropped malformed turn payload (not an object)", { index });
18049
+ warnMalformedSessionPayload(
18050
+ "Dropped malformed turn payload (not an object)",
18051
+ { index }
18052
+ );
17721
18053
  return null;
17722
18054
  }
17723
18055
  if (!isRecord2(rawTurn.userTurn)) {
17724
- warnMalformedSessionPayload("Dropped malformed turn payload (missing user turn)", { index });
18056
+ warnMalformedSessionPayload(
18057
+ "Dropped malformed turn payload (missing user turn)",
18058
+ { index }
18059
+ );
17725
18060
  return null;
17726
18061
  }
17727
18062
  const userTurnID = readNonEmptyString(rawTurn.userTurn.id);
17728
18063
  if (!userTurnID) {
17729
- warnMalformedSessionPayload("Dropped malformed turn payload (missing user turn id)", { index });
18064
+ warnMalformedSessionPayload(
18065
+ "Dropped malformed turn payload (missing user turn id)",
18066
+ { index }
18067
+ );
17730
18068
  return null;
17731
18069
  }
17732
18070
  const turnID = readString2(rawTurn.id, userTurnID);
@@ -17740,17 +18078,27 @@ function sanitizeConversationTurn(rawTurn, index, fallbackSessionID) {
17740
18078
  userTurn: {
17741
18079
  id: userTurnID,
17742
18080
  content: readString2(rawTurn.userTurn.content),
17743
- attachments: sanitizeUserAttachments(rawTurn.userTurn.attachments, turnID),
18081
+ attachments: sanitizeUserAttachments(
18082
+ rawTurn.userTurn.attachments,
18083
+ turnID
18084
+ ),
17744
18085
  author: mapSessionUser(rawTurn.userTurn.author),
17745
18086
  createdAt: readString2(rawTurn.userTurn.createdAt, createdAt)
17746
18087
  },
17747
- assistantTurn: sanitizeAssistantTurn(rawTurn.assistantTurn, createdAt, turnID),
18088
+ assistantTurn: sanitizeAssistantTurn(
18089
+ rawTurn.assistantTurn,
18090
+ createdAt,
18091
+ turnID
18092
+ ),
17748
18093
  createdAt
17749
18094
  };
17750
18095
  }
17751
18096
  function sanitizeConversationTurns(rawTurns, sessionID) {
17752
18097
  if (!Array.isArray(rawTurns)) {
17753
- warnMalformedSessionPayload("Session payload contained non-array turns field", { sessionID });
18098
+ warnMalformedSessionPayload(
18099
+ "Session payload contained non-array turns field",
18100
+ { sessionID }
18101
+ );
17754
18102
  return [];
17755
18103
  }
17756
18104
  const turns = [];
@@ -17764,11 +18112,14 @@ function sanitizeConversationTurns(rawTurns, sessionID) {
17764
18112
  }
17765
18113
  }
17766
18114
  if (dropped > 0) {
17767
- warnMalformedSessionPayload("Dropped malformed turns from session payload", {
17768
- sessionID,
17769
- dropped,
17770
- total: rawTurns.length
17771
- });
18115
+ warnMalformedSessionPayload(
18116
+ "Dropped malformed turns from session payload",
18117
+ {
18118
+ sessionID,
18119
+ dropped,
18120
+ total: rawTurns.length
18121
+ }
18122
+ );
17772
18123
  }
17773
18124
  return turns;
17774
18125
  }
@@ -17778,39 +18129,57 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
17778
18129
  }
17779
18130
  const checkpointID = readNonEmptyString(rawPendingQuestion.checkpointId);
17780
18131
  if (!checkpointID) {
17781
- warnMalformedSessionPayload("Dropped malformed pendingQuestion without checkpointId", { sessionID });
18132
+ warnMalformedSessionPayload(
18133
+ "Dropped malformed pendingQuestion without checkpointId",
18134
+ { sessionID }
18135
+ );
17782
18136
  return null;
17783
18137
  }
17784
18138
  if (!Array.isArray(rawPendingQuestion.questions)) {
17785
- warnMalformedSessionPayload("Pending question had non-array questions payload", {
17786
- sessionID,
17787
- checkpointID
17788
- });
18139
+ warnMalformedSessionPayload(
18140
+ "Pending question had non-array questions payload",
18141
+ {
18142
+ sessionID,
18143
+ checkpointID
18144
+ }
18145
+ );
17789
18146
  }
17790
18147
  const questions = Array.isArray(rawPendingQuestion.questions) ? rawPendingQuestion.questions.filter((question) => {
17791
18148
  if (!question || !isRecord2(question)) {
17792
- warnMalformedSessionPayload("Dropped malformed question from pendingQuestion", {
17793
- sessionID,
17794
- checkpointID
17795
- });
18149
+ warnMalformedSessionPayload(
18150
+ "Dropped malformed question from pendingQuestion",
18151
+ {
18152
+ sessionID,
18153
+ checkpointID
18154
+ }
18155
+ );
17796
18156
  return false;
17797
18157
  }
17798
18158
  return true;
17799
18159
  }).map((question, index) => {
17800
- const questionID = readString2(question.id, `${checkpointID}-q-${index}`);
18160
+ const questionID = readString2(
18161
+ question.id,
18162
+ `${checkpointID}-q-${index}`
18163
+ );
17801
18164
  const options = Array.isArray(question.options) ? question.options.filter((option) => {
17802
18165
  if (!option || !isRecord2(option)) {
17803
- warnMalformedSessionPayload("Dropped malformed pendingQuestion option", {
17804
- sessionID,
17805
- checkpointID,
17806
- questionID
17807
- });
18166
+ warnMalformedSessionPayload(
18167
+ "Dropped malformed pendingQuestion option",
18168
+ {
18169
+ sessionID,
18170
+ checkpointID,
18171
+ questionID
18172
+ }
18173
+ );
17808
18174
  return false;
17809
18175
  }
17810
18176
  return true;
17811
18177
  }).map((option, optionIndex) => {
17812
18178
  const label = readString2(option.label);
17813
- const id = readString2(option.id, `${questionID}-opt-${optionIndex}`);
18179
+ const id = readString2(
18180
+ option.id,
18181
+ `${questionID}-opt-${optionIndex}`
18182
+ );
17814
18183
  return {
17815
18184
  id,
17816
18185
  label,
@@ -17829,7 +18198,7 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
17829
18198
  turnId: readString2(rawPendingQuestion.turnId),
17830
18199
  agentName: readNonEmptyString(rawPendingQuestion.agentName) || void 0,
17831
18200
  questions,
17832
- status: "PENDING"
18201
+ status: normalizePendingQuestionStatus(rawPendingQuestion.status)
17833
18202
  };
17834
18203
  }
17835
18204
  function formatSizeReadable(bytes) {
@@ -17850,13 +18219,17 @@ function parseRowCount(metadata) {
17850
18219
  if (!metadata) {
17851
18220
  return void 0;
17852
18221
  }
17853
- const raw = metadata.row_count ?? metadata.rowCount;
17854
- if (typeof raw === "number" && Number.isFinite(raw)) {
18222
+ const raw = metadata.row_count ?? metadata.rowCount ?? metadata.total_rows ?? metadata.totalRows;
18223
+ if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 0) {
17855
18224
  return raw;
17856
18225
  }
17857
18226
  if (typeof raw === "string") {
17858
- const parsed = Number.parseInt(raw, 10);
17859
- if (Number.isFinite(parsed)) {
18227
+ const trimmed = raw.trim();
18228
+ if (!/^\d+$/.test(trimmed)) {
18229
+ return void 0;
18230
+ }
18231
+ const parsed = Number(trimmed);
18232
+ if (Number.isSafeInteger(parsed)) {
17860
18233
  return parsed;
17861
18234
  }
17862
18235
  }
@@ -18034,7 +18407,9 @@ function attachArtifactsToTurns(turns, artifacts) {
18034
18407
  if (artifacts.length === 0) {
18035
18408
  return turns;
18036
18409
  }
18037
- const downloadArtifacts = artifacts.map((raw) => ({ raw, mapped: toDownloadArtifact(raw) })).filter((entry) => entry.mapped !== null).sort((a, b) => toMillis(a.raw.createdAt) - toMillis(b.raw.createdAt));
18410
+ const downloadArtifacts = artifacts.map((raw) => ({ raw, mapped: toDownloadArtifact(raw) })).filter(
18411
+ (entry) => entry.mapped !== null
18412
+ ).sort((a, b) => toMillis(a.raw.createdAt) - toMillis(b.raw.createdAt));
18038
18413
  const chartArtifacts = artifacts.filter((a) => a.type === "chart").sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
18039
18414
  const tableArtifacts = artifacts.filter((a) => a.type === "table").sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
18040
18415
  if (downloadArtifacts.length === 0 && chartArtifacts.length === 0 && tableArtifacts.length === 0) {
@@ -18123,14 +18498,19 @@ function attachArtifactsToTurns(turns, artifacts) {
18123
18498
  continue;
18124
18499
  }
18125
18500
  if (assistantTurn.renderTables === void 0) {
18126
- assistantTurn.renderTables = extractRenderTablesFromToolCalls(assistantTurn.toolCalls);
18501
+ assistantTurn.renderTables = extractRenderTablesFromToolCalls(
18502
+ assistantTurn.toolCalls
18503
+ );
18127
18504
  }
18128
18505
  const existing = assistantTurn.renderTables;
18129
18506
  const metadata = raw.metadata;
18130
18507
  if (!metadata || typeof metadata !== "object" || metadata === null) {
18131
18508
  continue;
18132
18509
  }
18133
- const tableData = parseRenderTableDataFromMetadata(metadata, raw.id);
18510
+ const tableData = parseRenderTableDataFromMetadata(
18511
+ metadata,
18512
+ raw.id
18513
+ );
18134
18514
  if (!tableData) {
18135
18515
  continue;
18136
18516
  }
@@ -18995,7 +19375,7 @@ var HttpDataSource = class {
18995
19375
  uploadEndpoint: "/api/uploads",
18996
19376
  ...config,
18997
19377
  rpcTimeoutMs: typeof config.rpcTimeoutMs === "number" ? config.rpcTimeoutMs : 12e4,
18998
- streamConnectTimeoutMs: typeof config.streamConnectTimeoutMs === "number" ? config.streamConnectTimeoutMs : 3e4
19378
+ streamConnectTimeoutMs: typeof config.streamConnectTimeoutMs === "number" ? config.streamConnectTimeoutMs : void 0
18999
19379
  };
19000
19380
  this.rpc = createAppletRPCClient({
19001
19381
  endpoint: `${this.config.baseUrl}${this.config.rpcEndpoint}`,