@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.
@@ -1908,11 +1908,61 @@ function deriveInputSnapshot(state, methods) {
1908
1908
  };
1909
1909
  }
1910
1910
 
1911
+ // ui/src/bichat/utils/assistantTurnState.ts
1912
+ function isEmptyAssistantTurn(turn) {
1913
+ if (turn.content.trim().length > 0) {
1914
+ return false;
1915
+ }
1916
+ if ((turn.explanation?.trim().length ?? 0) > 0) {
1917
+ return false;
1918
+ }
1919
+ if ((turn.citations?.length ?? 0) > 0) {
1920
+ return false;
1921
+ }
1922
+ if ((turn.toolCalls?.length ?? 0) > 0) {
1923
+ return false;
1924
+ }
1925
+ if ((turn.charts?.length ?? 0) > 0) {
1926
+ return false;
1927
+ }
1928
+ if ((turn.renderTables?.length ?? 0) > 0) {
1929
+ return false;
1930
+ }
1931
+ if ((turn.artifacts?.length ?? 0) > 0) {
1932
+ return false;
1933
+ }
1934
+ if ((turn.codeOutputs?.length ?? 0) > 0) {
1935
+ return false;
1936
+ }
1937
+ if (turn.debug) {
1938
+ return false;
1939
+ }
1940
+ return true;
1941
+ }
1942
+ function isPlaceholderWaitingAssistantTurn(turn) {
1943
+ return turn.lifecycle === "waiting_for_human_input" && isEmptyAssistantTurn(turn);
1944
+ }
1945
+ function shouldRenderInlineRetry(turn, canRegenerate) {
1946
+ if (!canRegenerate) {
1947
+ return false;
1948
+ }
1949
+ if (turn.lifecycle === "waiting_for_human_input") {
1950
+ return false;
1951
+ }
1952
+ return isEmptyAssistantTurn(turn);
1953
+ }
1954
+
1911
1955
  // ui/src/bichat/machine/hitlLifecycle.ts
1912
1956
  function normalizeQuestionType(rawType) {
1913
1957
  const normalized = String(rawType || "").trim().toUpperCase().replace(/[\s-]+/g, "_");
1914
1958
  return normalized === "MULTIPLE_CHOICE" ? "MULTIPLE_CHOICE" : "SINGLE_CHOICE";
1915
1959
  }
1960
+ function isOpenQuestionStatus(status) {
1961
+ return status === "PENDING" || status === "ANSWER_SUBMITTED" || status === "REJECT_SUBMITTED" || status === "ANSWER_RESUME_FAILED" || status === "REJECT_RESUME_FAILED";
1962
+ }
1963
+ function shouldPromptForHumanInput(status) {
1964
+ return status === "PENDING" || status === "ANSWER_RESUME_FAILED" || status === "REJECT_RESUME_FAILED";
1965
+ }
1916
1966
  function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1917
1967
  if (!interrupt) {
1918
1968
  return null;
@@ -1940,7 +1990,7 @@ function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1940
1990
  };
1941
1991
  }
1942
1992
  function resolvePendingQuestionTurnIndex(turns, pendingQuestion) {
1943
- if (!pendingQuestion || pendingQuestion.status !== "PENDING" || turns.length === 0) {
1993
+ if (!pendingQuestion || !isOpenQuestionStatus(pendingQuestion.status) || turns.length === 0) {
1944
1994
  return -1;
1945
1995
  }
1946
1996
  const pendingTurnId = pendingQuestion.turnId?.trim();
@@ -1967,7 +2017,7 @@ function applyTurnLifecycleForPendingQuestion(turns, pendingQuestion) {
1967
2017
  let changed = false;
1968
2018
  const nextTurns = turns.map((turn, index) => {
1969
2019
  const shouldWaitForInput = pendingIndex === index;
1970
- const desiredLifecycle = shouldWaitForInput ? "waiting_for_human_input" : "complete";
2020
+ const desiredLifecycle = shouldWaitForInput ? shouldPromptForHumanInput(pendingQuestion?.status) ? "waiting_for_human_input" : "complete" : "complete";
1971
2021
  if (!turn.assistantTurn) {
1972
2022
  if (!shouldWaitForInput || !pendingQuestion) {
1973
2023
  return turn;
@@ -1987,6 +2037,13 @@ function applyTurnLifecycleForPendingQuestion(turns, pendingQuestion) {
1987
2037
  }
1988
2038
  };
1989
2039
  }
2040
+ if (!shouldWaitForInput && isPlaceholderWaitingAssistantTurn(turn.assistantTurn)) {
2041
+ changed = true;
2042
+ return {
2043
+ ...turn,
2044
+ assistantTurn: void 0
2045
+ };
2046
+ }
1990
2047
  if (turn.assistantTurn.lifecycle === desiredLifecycle) {
1991
2048
  return turn;
1992
2049
  }
@@ -2136,7 +2193,9 @@ var ChatMachine = class {
2136
2193
  this.onSessionCreated = config.onSessionCreated;
2137
2194
  this.reasoningEffortOptions = this.buildReasoningEffortOptions();
2138
2195
  this.reasoningEffortOptionSet = this.reasoningEffortOptions ? new Set(this.reasoningEffortOptions) : null;
2139
- const initialReasoningEffort = this.sanitizeReasoningEffort(loadReasoningEffort() || void 0);
2196
+ const initialReasoningEffort = this.sanitizeReasoningEffort(
2197
+ loadReasoningEffort() || void 0
2198
+ );
2140
2199
  if (!initialReasoningEffort) {
2141
2200
  clearReasoningEffort();
2142
2201
  }
@@ -2404,7 +2463,9 @@ var ChatMachine = class {
2404
2463
  */
2405
2464
  _setTurnsFromFetch(fetchedTurns, pendingQuestion) {
2406
2465
  if (!Array.isArray(fetchedTurns)) {
2407
- console.warn("[ChatMachine] Ignoring malformed turns payload from fetchSession");
2466
+ console.warn(
2467
+ "[ChatMachine] Ignoring malformed turns payload from fetchSession"
2468
+ );
2408
2469
  return;
2409
2470
  }
2410
2471
  const prev = this.state.messaging.turns;
@@ -2415,7 +2476,10 @@ var ChatMachine = class {
2415
2476
  patch.pendingQuestion = pendingQuestion;
2416
2477
  }
2417
2478
  if (hasPendingUserOnly && (!fetchedTurns || fetchedTurns.length === 0)) {
2418
- const lifecycleTurns = applyTurnLifecycleForPendingQuestion(prev, effectivePendingQuestion);
2479
+ const lifecycleTurns = applyTurnLifecycleForPendingQuestion(
2480
+ prev,
2481
+ effectivePendingQuestion
2482
+ );
2419
2483
  if (lifecycleTurns !== prev) {
2420
2484
  patch.turns = lifecycleTurns;
2421
2485
  }
@@ -2424,7 +2488,10 @@ var ChatMachine = class {
2424
2488
  }
2425
2489
  return;
2426
2490
  }
2427
- patch.turns = applyTurnLifecycleForPendingQuestion(fetchedTurns ?? prev, effectivePendingQuestion);
2491
+ patch.turns = applyTurnLifecycleForPendingQuestion(
2492
+ fetchedTurns ?? prev,
2493
+ effectivePendingQuestion
2494
+ );
2428
2495
  this._updateMessaging(patch);
2429
2496
  }
2430
2497
  /**
@@ -2481,10 +2548,16 @@ var ChatMachine = class {
2481
2548
  this._updateMessaging({ generationInProgress: false });
2482
2549
  this.dataSource.fetchSession(sessionId).then((result) => {
2483
2550
  if (this.state.session.currentSessionId === sessionId && result) {
2484
- this._setTurnsFromFetch(result.turns, result.pendingQuestion ?? null);
2551
+ this._setTurnsFromFetch(
2552
+ result.turns,
2553
+ result.pendingQuestion ?? null
2554
+ );
2485
2555
  }
2486
2556
  }).catch((err) => {
2487
- console.error("[ChatMachine] fetchSession after stream inactive:", err);
2557
+ console.error(
2558
+ "[ChatMachine] fetchSession after stream inactive:",
2559
+ err
2560
+ );
2488
2561
  });
2489
2562
  }
2490
2563
  }).catch((err) => {
@@ -2545,7 +2618,10 @@ var ChatMachine = class {
2545
2618
  if (this.disposed) {
2546
2619
  return;
2547
2620
  }
2548
- console.warn("[ChatMachine] resumeStream failed, switching to status polling fallback:", err);
2621
+ console.warn(
2622
+ "[ChatMachine] resumeStream failed, switching to status polling fallback:",
2623
+ err
2624
+ );
2549
2625
  const getStreamStatus2 = this.dataSource.getStreamStatus;
2550
2626
  const status = getStreamStatus2 ? await getStreamStatus2(sessionId).catch(() => null) : null;
2551
2627
  if (!status?.active) {
@@ -2586,9 +2662,11 @@ var ChatMachine = class {
2586
2662
  if (typeof window === "undefined") {
2587
2663
  return;
2588
2664
  }
2589
- window.dispatchEvent(new CustomEvent("bichat:sessions-updated", {
2590
- detail: { reason, sessionId }
2591
- }));
2665
+ window.dispatchEvent(
2666
+ new CustomEvent("bichat:sessions-updated", {
2667
+ detail: { reason, sessionId }
2668
+ })
2669
+ );
2592
2670
  }
2593
2671
  _cancel() {
2594
2672
  if (this.abortController) {
@@ -2636,10 +2714,15 @@ var ChatMachine = class {
2636
2714
  this._setDebugModeForSession(key3, nextDebugMode);
2637
2715
  if (nextDebugMode && this.state.session.currentSessionId && this.state.session.currentSessionId !== "new") {
2638
2716
  try {
2639
- const result = await this.dataSource.fetchSession(this.state.session.currentSessionId);
2717
+ const result = await this.dataSource.fetchSession(
2718
+ this.state.session.currentSessionId
2719
+ );
2640
2720
  if (result) {
2641
2721
  this._updateSession({ session: result.session });
2642
- this._setTurnsFromFetch(result.turns, result.pendingQuestion || null);
2722
+ this._setTurnsFromFetch(
2723
+ result.turns,
2724
+ result.pendingQuestion || null
2725
+ );
2643
2726
  }
2644
2727
  } catch (err) {
2645
2728
  console.error("Failed to refresh session for debug mode:", err);
@@ -2667,7 +2750,10 @@ var ChatMachine = class {
2667
2750
  }
2668
2751
  this._updateMessaging({ codeOutputs: [] });
2669
2752
  } catch (err) {
2670
- const normalized = normalizeRPCError(err, "Failed to clear session history");
2753
+ const normalized = normalizeRPCError(
2754
+ err,
2755
+ "Failed to clear session history"
2756
+ );
2671
2757
  this._updateInput({ inputError: normalized.userMessage });
2672
2758
  } finally {
2673
2759
  this._updateMessaging({ loading: false, isStreaming: false });
@@ -2688,7 +2774,12 @@ var ChatMachine = class {
2688
2774
  }
2689
2775
  this._updateMessaging({
2690
2776
  turns: applyTurnLifecycleForPendingQuestion(
2691
- [createCompactedSystemTurn(curSessionId, "Compacting conversation history...")],
2777
+ [
2778
+ createCompactedSystemTurn(
2779
+ curSessionId,
2780
+ "Compacting conversation history..."
2781
+ )
2782
+ ],
2692
2783
  null
2693
2784
  ),
2694
2785
  pendingQuestion: null
@@ -2698,17 +2789,27 @@ var ChatMachine = class {
2698
2789
  const result = await this.dataSource.fetchSession(curSessionId);
2699
2790
  if (result) {
2700
2791
  this._updateSession({ session: result.session });
2701
- this._setTurnsFromFetch(result.turns, result.pendingQuestion || null);
2792
+ this._setTurnsFromFetch(
2793
+ result.turns,
2794
+ result.pendingQuestion || null
2795
+ );
2702
2796
  } else {
2703
2797
  this._setTurnsFromFetch([], null);
2704
2798
  }
2705
2799
  this._updateMessaging({ codeOutputs: [] });
2706
2800
  }
2707
2801
  } catch (err) {
2708
- const normalized = normalizeRPCError(err, "Failed to compact session history");
2802
+ const normalized = normalizeRPCError(
2803
+ err,
2804
+ "Failed to compact session history"
2805
+ );
2709
2806
  this._updateInput({ inputError: normalized.userMessage });
2710
2807
  } finally {
2711
- this._updateMessaging({ isCompacting: false, loading: false, isStreaming: false });
2808
+ this._updateMessaging({
2809
+ isCompacting: false,
2810
+ loading: false,
2811
+ isStreaming: false
2812
+ });
2712
2813
  }
2713
2814
  return true;
2714
2815
  }
@@ -2720,9 +2821,13 @@ var ChatMachine = class {
2720
2821
  this._updateMessaging({ turns: [...prevTurns, tempTurn] });
2721
2822
  return;
2722
2823
  }
2723
- const idx = prevTurns.findIndex((turn) => turn.userTurn.id === replaceFromMessageID);
2824
+ const idx = prevTurns.findIndex(
2825
+ (turn) => turn.userTurn.id === replaceFromMessageID
2826
+ );
2724
2827
  if (idx === -1) {
2725
- console.warn(`[ChatMachine] replaceFromMessageID "${replaceFromMessageID}" not found; appending as new turn`);
2828
+ console.warn(
2829
+ `[ChatMachine] replaceFromMessageID "${replaceFromMessageID}" not found; appending as new turn`
2830
+ );
2726
2831
  this._updateMessaging({ turns: [...prevTurns, tempTurn] });
2727
2832
  return;
2728
2833
  }
@@ -2806,7 +2911,10 @@ var ChatMachine = class {
2806
2911
  if (chunk.sessionId) {
2807
2912
  createdSessionId = chunk.sessionId;
2808
2913
  }
2809
- const pendingFromInterrupt = pendingQuestionFromInterrupt(chunk.interrupt, tempTurnId);
2914
+ const pendingFromInterrupt = pendingQuestionFromInterrupt(
2915
+ chunk.interrupt,
2916
+ tempTurnId
2917
+ );
2810
2918
  if (pendingFromInterrupt) {
2811
2919
  this._updateMessaging({
2812
2920
  pendingQuestion: pendingFromInterrupt,
@@ -2880,7 +2988,9 @@ var ChatMachine = class {
2880
2988
  this._updateInput({ message: content });
2881
2989
  this._clearStreamError();
2882
2990
  this._updateMessaging({
2883
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurnId)
2991
+ turns: this.state.messaging.turns.filter(
2992
+ (turn) => turn.id !== tempTurnId
2993
+ )
2884
2994
  });
2885
2995
  const sessionId = this.sendingSessionId ?? this.state.session.currentSessionId;
2886
2996
  if (sessionId && sessionId !== "new") {
@@ -2890,7 +3000,9 @@ var ChatMachine = class {
2890
3000
  return false;
2891
3001
  }
2892
3002
  this._updateMessaging({
2893
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurnId)
3003
+ turns: this.state.messaging.turns.filter(
3004
+ (turn) => turn.id !== tempTurnId
3005
+ )
2894
3006
  });
2895
3007
  const normalized = normalizeRPCError(err, "Failed to send message");
2896
3008
  this._updateInput({ inputError: normalized.userMessage });
@@ -2958,7 +3070,11 @@ var ChatMachine = class {
2958
3070
  const curSessionId = this.state.session.currentSessionId;
2959
3071
  const curDebugMode = deriveDebugMode(this.state);
2960
3072
  const replaceFromMessageID = options?.replaceFromMessageID;
2961
- const tempTurn = createPendingTurn(curSessionId || "new", content, attachments);
3073
+ const tempTurn = createPendingTurn(
3074
+ curSessionId || "new",
3075
+ content,
3076
+ attachments
3077
+ );
2962
3078
  this.lastSendAttempt = { content, attachments, options };
2963
3079
  const prevTurns = this.state.messaging.turns;
2964
3080
  this._insertOptimisticTurn(prevTurns, tempTurn, replaceFromMessageID);
@@ -2966,22 +3082,22 @@ var ChatMachine = class {
2966
3082
  try {
2967
3083
  const { activeSessionId, shouldNavigateAfter } = await this._resolveSendSession(curSessionId, curDebugMode);
2968
3084
  this.sendingSessionId = activeSessionId || null;
2969
- const {
2970
- createdSessionId,
2971
- sessionFetched,
2972
- stopped
2973
- } = await this._runSendStream({
3085
+ const { createdSessionId, sessionFetched, stopped } = await this._runSendStream({
2974
3086
  activeSessionId,
2975
3087
  content,
2976
3088
  attachments,
2977
3089
  debugMode: curDebugMode,
2978
3090
  replaceFromMessageID,
2979
- reasoningEffort: this.sanitizeReasoningEffort(this.state.session.reasoningEffort),
3091
+ reasoningEffort: this.sanitizeReasoningEffort(
3092
+ this.state.session.reasoningEffort
3093
+ ),
2980
3094
  tempTurnId: tempTurn.id
2981
3095
  });
2982
3096
  if (stopped) {
2983
3097
  this._updateMessaging({
2984
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurn.id)
3098
+ turns: this.state.messaging.turns.filter(
3099
+ (turn) => turn.id !== tempTurn.id
3100
+ )
2985
3101
  });
2986
3102
  this._updateInput({ message: content });
2987
3103
  this._clearStreamError();
@@ -2991,7 +3107,11 @@ var ChatMachine = class {
2991
3107
  });
2992
3108
  }
2993
3109
  } else {
2994
- await this._ensureSessionSyncAfterStream(activeSessionId, createdSessionId, sessionFetched);
3110
+ await this._ensureSessionSyncAfterStream(
3111
+ activeSessionId,
3112
+ createdSessionId,
3113
+ sessionFetched
3114
+ );
2995
3115
  const targetSessionId = createdSessionId || activeSessionId;
2996
3116
  this._finalizeSuccessfulSend(targetSessionId, shouldNavigateAfter);
2997
3117
  }
@@ -3029,7 +3149,9 @@ var ChatMachine = class {
3029
3149
  }
3030
3150
  this._updateMessaging({ thinkingContent: updated });
3031
3151
  const steps = this.state.messaging.activeSteps;
3032
- const existing = steps.find((s) => s.type === "thinking" && s.status === "active");
3152
+ const existing = steps.find(
3153
+ (s) => s.type === "thinking" && s.status === "active"
3154
+ );
3033
3155
  if (!existing) {
3034
3156
  const step = {
3035
3157
  id: `thinking-${Date.now()}`,
@@ -3060,7 +3182,9 @@ var ChatMachine = class {
3060
3182
  }
3061
3183
  _handleToolEnd(tool) {
3062
3184
  const steps = [...this.state.messaging.activeSteps];
3063
- const idx = steps.findIndex((s) => s.status === "active" && this._matchStep(s, tool));
3185
+ const idx = steps.findIndex(
3186
+ (s) => s.status === "active" && this._matchStep(s, tool)
3187
+ );
3064
3188
  if (idx !== -1) {
3065
3189
  steps[idx] = {
3066
3190
  ...steps[idx],
@@ -3091,7 +3215,11 @@ var ChatMachine = class {
3091
3215
  }
3092
3216
  this._clearStreamError();
3093
3217
  this._updateInput({ inputError: null });
3094
- await this._sendMessageDirect(lastAttempt.content, lastAttempt.attachments, lastAttempt.options);
3218
+ await this._sendMessageDirect(
3219
+ lastAttempt.content,
3220
+ lastAttempt.attachments,
3221
+ lastAttempt.options
3222
+ );
3095
3223
  }
3096
3224
  // ── Regenerate / Edit ───────────────────────────────────────────────────
3097
3225
  async _handleRegenerate(turnId) {
@@ -3104,9 +3232,13 @@ var ChatMachine = class {
3104
3232
  return;
3105
3233
  }
3106
3234
  this._updateSession({ error: null, errorRetryable: false });
3107
- await this._sendMessageDirect(turn.userTurn.content, turn.userTurn.attachments, {
3108
- replaceFromMessageID: turn.userTurn.id
3109
- });
3235
+ await this._sendMessageDirect(
3236
+ turn.userTurn.content,
3237
+ turn.userTurn.attachments,
3238
+ {
3239
+ replaceFromMessageID: turn.userTurn.id
3240
+ }
3241
+ );
3110
3242
  }
3111
3243
  async _handleEdit(turnId, newContent) {
3112
3244
  const curSessionId = this.state.session.currentSessionId;
@@ -3119,7 +3251,10 @@ var ChatMachine = class {
3119
3251
  }
3120
3252
  const turn = this.state.messaging.turns.find((t) => t.id === turnId);
3121
3253
  if (!turn) {
3122
- this._updateSession({ error: "Failed to edit message", errorRetryable: false });
3254
+ this._updateSession({
3255
+ error: "Failed to edit message",
3256
+ errorRetryable: false
3257
+ });
3123
3258
  return;
3124
3259
  }
3125
3260
  this._updateSession({ error: null, errorRetryable: false });
@@ -3157,8 +3292,17 @@ var ChatMachine = class {
3157
3292
  }
3158
3293
  if (result.success) {
3159
3294
  this._updateMessaging({
3160
- pendingQuestion: null,
3161
- turns: applyTurnLifecycleForPendingQuestion(this.state.messaging.turns, null)
3295
+ pendingQuestion: {
3296
+ ...previousPendingQuestion,
3297
+ status: "ANSWER_SUBMITTED"
3298
+ },
3299
+ turns: applyTurnLifecycleForPendingQuestion(
3300
+ this.state.messaging.turns,
3301
+ {
3302
+ ...previousPendingQuestion,
3303
+ status: "ANSWER_SUBMITTED"
3304
+ }
3305
+ )
3162
3306
  });
3163
3307
  if (result.data) {
3164
3308
  await this._resumeAcceptedRunOrPoll(curSessionId, result.data.runId);
@@ -3169,9 +3313,15 @@ var ChatMachine = class {
3169
3313
  }
3170
3314
  if (fetchResult) {
3171
3315
  this._updateSession({ session: fetchResult.session });
3172
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3316
+ this._setTurnsFromFetch(
3317
+ fetchResult.turns,
3318
+ fetchResult.pendingQuestion || null
3319
+ );
3173
3320
  } else {
3174
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3321
+ this._updateSession({
3322
+ error: "Failed to load updated session",
3323
+ errorRetryable: true
3324
+ });
3175
3325
  }
3176
3326
  }
3177
3327
  } else if (curSessionId !== "new") {
@@ -3181,20 +3331,32 @@ var ChatMachine = class {
3181
3331
  }
3182
3332
  if (fetchResult) {
3183
3333
  this._updateSession({ session: fetchResult.session });
3184
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3334
+ this._setTurnsFromFetch(
3335
+ fetchResult.turns,
3336
+ fetchResult.pendingQuestion || null
3337
+ );
3185
3338
  } else {
3186
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3339
+ this._updateSession({
3340
+ error: "Failed to load updated session",
3341
+ errorRetryable: true
3342
+ });
3187
3343
  }
3188
3344
  }
3189
3345
  } else {
3190
- this._updateSession({ error: result.error || "Failed to submit answers", errorRetryable: false });
3346
+ this._updateSession({
3347
+ error: result.error || "Failed to submit answers",
3348
+ errorRetryable: false
3349
+ });
3191
3350
  }
3192
3351
  } catch (err) {
3193
3352
  if (this.disposed) {
3194
3353
  return;
3195
3354
  }
3196
3355
  const normalized = normalizeRPCError(err, "Failed to submit answers");
3197
- this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3356
+ this._updateSession({
3357
+ error: normalized.userMessage,
3358
+ errorRetryable: normalized.retryable
3359
+ });
3198
3360
  } finally {
3199
3361
  if (!this.disposed) {
3200
3362
  this._updateMessaging({ loading: false });
@@ -3213,12 +3375,37 @@ var ChatMachine = class {
3213
3375
  return;
3214
3376
  }
3215
3377
  if (result.success) {
3378
+ const submittedQuestion = {
3379
+ ...curPendingQuestion,
3380
+ status: "REJECT_SUBMITTED"
3381
+ };
3216
3382
  this._updateMessaging({
3217
- pendingQuestion: null,
3218
- turns: applyTurnLifecycleForPendingQuestion(this.state.messaging.turns, null)
3383
+ pendingQuestion: submittedQuestion,
3384
+ turns: applyTurnLifecycleForPendingQuestion(
3385
+ this.state.messaging.turns,
3386
+ submittedQuestion
3387
+ )
3219
3388
  });
3220
3389
  if (result.data) {
3221
3390
  await this._resumeAcceptedRunOrPoll(curSessionId, result.data.runId);
3391
+ if (!this.state.messaging.generationInProgress && curSessionId !== "new") {
3392
+ const fetchResult = await this.dataSource.fetchSession(curSessionId);
3393
+ if (this.disposed) {
3394
+ return;
3395
+ }
3396
+ if (fetchResult) {
3397
+ this._updateSession({ session: fetchResult.session });
3398
+ this._setTurnsFromFetch(
3399
+ fetchResult.turns,
3400
+ fetchResult.pendingQuestion || null
3401
+ );
3402
+ } else {
3403
+ this._updateSession({
3404
+ error: "Failed to load updated session",
3405
+ errorRetryable: true
3406
+ });
3407
+ }
3408
+ }
3222
3409
  } else if (curSessionId !== "new") {
3223
3410
  const fetchResult = await this.dataSource.fetchSession(curSessionId);
3224
3411
  if (this.disposed) {
@@ -3226,18 +3413,27 @@ var ChatMachine = class {
3226
3413
  }
3227
3414
  if (fetchResult) {
3228
3415
  this._updateSession({ session: fetchResult.session });
3229
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3416
+ this._setTurnsFromFetch(
3417
+ fetchResult.turns,
3418
+ fetchResult.pendingQuestion || null
3419
+ );
3230
3420
  }
3231
3421
  }
3232
3422
  } else {
3233
- this._updateSession({ error: result.error || "Failed to reject question", errorRetryable: false });
3423
+ this._updateSession({
3424
+ error: result.error || "Failed to reject question",
3425
+ errorRetryable: false
3426
+ });
3234
3427
  }
3235
3428
  } catch (err) {
3236
3429
  if (this.disposed) {
3237
3430
  return;
3238
3431
  }
3239
3432
  const normalized = normalizeRPCError(err, "Failed to reject question");
3240
- this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3433
+ this._updateSession({
3434
+ error: normalized.userMessage,
3435
+ errorRetryable: normalized.retryable
3436
+ });
3241
3437
  }
3242
3438
  }
3243
3439
  // ── Input / queue ───────────────────────────────────────────────────────
@@ -3284,7 +3480,10 @@ var ChatMachine = class {
3284
3480
  return false;
3285
3481
  }
3286
3482
  this._updateInput({
3287
- messageQueue: [...this.state.input.messageQueue, { content, attachments }]
3483
+ messageQueue: [
3484
+ ...this.state.input.messageQueue,
3485
+ { content, attachments }
3486
+ ]
3288
3487
  });
3289
3488
  return true;
3290
3489
  }
@@ -4437,7 +4636,7 @@ init_useTranslation();
4437
4636
  var COPY_FEEDBACK_MS = 2e3;
4438
4637
  var defaultClassNames = {
4439
4638
  root: "flex gap-3 justify-end group",
4440
- wrapper: "flex-1 flex flex-col items-end max-w-[var(--bichat-bubble-max-width)]",
4639
+ wrapper: "flex-1 min-w-0 flex flex-col items-end max-w-[var(--bichat-bubble-max-width)]",
4441
4640
  avatar: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-sm",
4442
4641
  bubble: "bg-primary-600 text-white rounded-2xl rounded-br-sm px-4 py-3 shadow-sm",
4443
4642
  content: "text-sm whitespace-pre-wrap break-words leading-relaxed",
@@ -6001,6 +6200,7 @@ function FullscreenOverlay({ title, onClose, closeLabel, children }) {
6001
6200
  )
6002
6201
  ] });
6003
6202
  }
6203
+ var FULL_WIDTH_CLASS = "w-full min-w-0 max-w-full";
6004
6204
  function getPageNumbers(current, total) {
6005
6205
  if (total <= 7) {
6006
6206
  return Array.from({ length: total }, (_, i) => i + 1);
@@ -6095,6 +6295,8 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6095
6295
  const hasHiddenColumns = dt.columns.some((c) => !c.visible);
6096
6296
  const from = dt.totalFilteredRows === 0 ? 0 : (dt.page - 1) * dt.pageSize + 1;
6097
6297
  const to = Math.min(dt.page * dt.pageSize, dt.totalFilteredRows);
6298
+ const loadedRowsCount = table.rows.length;
6299
+ const reportedRowsCount = Math.max(table.totalRows || 0, loadedRowsCount);
6098
6300
  const renderToolbar = () => /* @__PURE__ */ jsxRuntime.jsx(
6099
6301
  DataTableToolbar,
6100
6302
  {
@@ -6115,9 +6317,12 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6115
6317
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
6116
6318
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate text-sm font-semibold text-gray-900 dark:text-gray-100", children: table.title || t("BiChat.Table.QueryResults") }),
6117
6319
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
6118
- dt.totalFilteredRows === table.rows.length ? dt.totalFilteredRows === 1 ? t("BiChat.Table.OneRowLoaded") : t("BiChat.Table.RowsLoaded", { count: String(dt.totalFilteredRows) }) : t("BiChat.DataTable.FilteredRows", {
6320
+ dt.totalFilteredRows === loadedRowsCount ? loadedRowsCount === reportedRowsCount ? loadedRowsCount === 1 ? t("BiChat.Table.OneRowLoaded") : t("BiChat.Table.RowsLoaded", { count: String(loadedRowsCount) }) : t("BiChat.DataTable.FilteredRows", {
6321
+ filtered: String(loadedRowsCount),
6322
+ total: String(reportedRowsCount)
6323
+ }) : t("BiChat.DataTable.FilteredRows", {
6119
6324
  filtered: String(dt.totalFilteredRows),
6120
- total: String(table.rows.length)
6325
+ total: String(loadedRowsCount)
6121
6326
  }),
6122
6327
  table.truncated ? ` ${t("BiChat.Table.TruncatedSuffix")}` : ""
6123
6328
  ] })
@@ -6132,7 +6337,7 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6132
6337
  }
6133
6338
  )
6134
6339
  ] });
6135
- const renderTable = (scrollClass) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: scrollClass, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full border-collapse text-sm", children: [
6340
+ const renderTable = (scrollClass) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${FULL_WIDTH_CLASS} ${scrollClass}`, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full border-collapse text-sm", children: [
6136
6341
  /* @__PURE__ */ jsxRuntime.jsx(
6137
6342
  DataTableHeader,
6138
6343
  {
@@ -6273,7 +6478,7 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6273
6478
  ] });
6274
6479
  const renderTruncationNotice = () => table.truncated ? /* @__PURE__ */ jsxRuntime.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;
6275
6480
  const fillHeight = host?.isFullscreen ?? false;
6276
- 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";
6481
+ 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`;
6277
6482
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6278
6483
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: sectionClassName, children: [
6279
6484
  renderToolbar(),
@@ -6426,7 +6631,7 @@ var TabbedTableGroup = React.memo(function TabbedTableGroup2({
6426
6631
  const tabs = React.useMemo(
6427
6632
  () => tables.map((table, i) => ({
6428
6633
  id: table.id,
6429
- label: `${table.title || `${t("BiChat.Table.QueryResults")} ${i + 1}`} (${table.rows.length})`
6634
+ label: `${table.title || `${t("BiChat.Table.QueryResults")} ${i + 1}`} (${Math.max(table.totalRows || 0, table.rows.length)})`
6430
6635
  })),
6431
6636
  [tables, t]
6432
6637
  );
@@ -6797,7 +7002,9 @@ function DownloadCard({ artifact }) {
6797
7002
  );
6798
7003
  }
6799
7004
  init_useTranslation();
6800
- function InlineQuestionForm({ pendingQuestion }) {
7005
+ function InlineQuestionForm({
7006
+ pendingQuestion
7007
+ }) {
6801
7008
  const { handleSubmitQuestionAnswers, handleRejectPendingQuestion, loading } = useChatMessaging();
6802
7009
  const { t } = useTranslation();
6803
7010
  const [currentStep, setCurrentStep] = React.useState(0);
@@ -6808,6 +7015,7 @@ function InlineQuestionForm({ pendingQuestion }) {
6808
7015
  const isLastStep = currentStep === questions.length - 1;
6809
7016
  const isFirstStep = currentStep === 0;
6810
7017
  const totalSteps = questions.length;
7018
+ const isFailedRetry = pendingQuestion.status === "ANSWER_RESUME_FAILED" || pendingQuestion.status === "REJECT_RESUME_FAILED";
6811
7019
  const currentAnswer = answers[currentQuestion?.id];
6812
7020
  const currentOtherText = otherTexts[currentQuestion?.id] || "";
6813
7021
  const handleOptionChange = React.useCallback(
@@ -6936,7 +7144,13 @@ function InlineQuestionForm({ pendingQuestion }) {
6936
7144
  const canProceed = isCurrentAnswerValid();
6937
7145
  return /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
6938
7146
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 px-4 pt-4 pb-3", children: [
6939
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-7 h-7 rounded-lg bg-primary-100 dark:bg-primary-900/40", children: /* @__PURE__ */ jsxRuntime.jsx(react.ChatCircleDots, { className: "w-4 h-4 text-primary-600 dark:text-primary-400", weight: "fill" }) }),
7147
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-7 h-7 rounded-lg bg-primary-100 dark:bg-primary-900/40", children: /* @__PURE__ */ jsxRuntime.jsx(
7148
+ react.ChatCircleDots,
7149
+ {
7150
+ className: "w-4 h-4 text-primary-600 dark:text-primary-400",
7151
+ weight: "fill"
7152
+ }
7153
+ ) }),
6940
7154
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6941
7155
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold uppercase tracking-wide text-primary-600 dark:text-primary-400", children: t("BiChat.InlineQuestion.InputNeeded") }),
6942
7156
  totalSteps > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[11px] tabular-nums text-gray-400 dark:text-gray-500", children: [
@@ -6957,6 +7171,10 @@ function InlineQuestionForm({ pendingQuestion }) {
6957
7171
  }
6958
7172
  )
6959
7173
  ] }),
7174
+ isFailedRetry && /* @__PURE__ */ jsxRuntime.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: [
7175
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-amber-800 dark:text-amber-300", children: "Continuing after your last response failed." }),
7176
+ /* @__PURE__ */ jsxRuntime.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." })
7177
+ ] }),
6960
7178
  totalSteps > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 px-4 pb-3", children: questions.map((_, index) => {
6961
7179
  const isCompleted = index < currentStep;
6962
7180
  const isCurrent = index === currentStep;
@@ -7010,10 +7228,16 @@ function InlineQuestionForm({ pendingQuestion }) {
7010
7228
  className: "sr-only"
7011
7229
  }
7012
7230
  ),
7013
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: [
7014
- "text-sm transition-colors duration-150",
7015
- isSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7016
- ].join(" "), children: option.label })
7231
+ /* @__PURE__ */ jsxRuntime.jsx(
7232
+ "span",
7233
+ {
7234
+ className: [
7235
+ "text-sm transition-colors duration-150",
7236
+ isSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7237
+ ].join(" "),
7238
+ children: option.label
7239
+ }
7240
+ )
7017
7241
  ]
7018
7242
  },
7019
7243
  option.id
@@ -7050,10 +7274,16 @@ function InlineQuestionForm({ pendingQuestion }) {
7050
7274
  className: "sr-only"
7051
7275
  }
7052
7276
  ),
7053
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: [
7054
- "text-sm transition-colors duration-150",
7055
- isOtherSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7056
- ].join(" "), children: t("BiChat.InlineQuestion.OtherOption") })
7277
+ /* @__PURE__ */ jsxRuntime.jsx(
7278
+ "span",
7279
+ {
7280
+ className: [
7281
+ "text-sm transition-colors duration-150",
7282
+ isOtherSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7283
+ ].join(" "),
7284
+ children: t("BiChat.InlineQuestion.OtherOption")
7285
+ }
7286
+ )
7057
7287
  ]
7058
7288
  }
7059
7289
  ),
@@ -7485,12 +7715,14 @@ function DebugPanel({ trace }) {
7485
7715
  // ui/src/bichat/components/AssistantMessage.tsx
7486
7716
  init_useTranslation();
7487
7717
  var MarkdownRenderer2 = React.lazy(
7488
- () => Promise.resolve().then(() => (init_MarkdownRenderer(), MarkdownRenderer_exports)).then((module) => ({ default: module.MarkdownRenderer }))
7718
+ () => Promise.resolve().then(() => (init_MarkdownRenderer(), MarkdownRenderer_exports)).then((module) => ({
7719
+ default: module.MarkdownRenderer
7720
+ }))
7489
7721
  );
7490
7722
  var COPY_FEEDBACK_MS2 = 2e3;
7491
7723
  var defaultClassNames2 = {
7492
- root: "flex gap-3 group",
7493
- wrapper: "flex-1 min-w-0 flex flex-col gap-3 max-w-[var(--bichat-bubble-assistant-max-width,85%)]",
7724
+ root: "flex min-w-0 gap-3 group",
7725
+ wrapper: "flex-1 w-full min-w-0 flex flex-col gap-3 max-w-[var(--bichat-bubble-assistant-max-width,85%)]",
7494
7726
  avatar: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-xs",
7495
7727
  bubble: "bg-white dark:bg-gray-800 rounded-2xl rounded-bl-sm px-4 py-3 shadow-sm",
7496
7728
  codeOutputs: "",
@@ -7543,7 +7775,9 @@ function AssistantMessage({
7543
7775
  const { t } = useTranslation();
7544
7776
  const [explanationExpanded, setExplanationExpanded] = React.useState(false);
7545
7777
  const [isCopied, setIsCopied] = React.useState(false);
7546
- const copyFeedbackTimeoutRef = React.useRef(null);
7778
+ const copyFeedbackTimeoutRef = React.useRef(
7779
+ null
7780
+ );
7547
7781
  const classes = mergeClassNames2(defaultClassNames2, classNameOverrides);
7548
7782
  const isSystemMessage = turn.role === "system";
7549
7783
  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;
@@ -7559,8 +7793,11 @@ function AssistantMessage({
7559
7793
  const hasContent = turn.content?.trim().length > 0;
7560
7794
  const hasExplanation = !!turn.explanation?.trim();
7561
7795
  const isAwaitingHumanInput = turn.lifecycle === "waiting_for_human_input";
7562
- const pendingQuestionMatchesTurn = !!pendingQuestion && pendingQuestion.status === "PENDING" && (pendingQuestion.turnId === turnId || pendingQuestion.turnId === turn.id || !pendingQuestion.turnId && isLastTurn);
7796
+ const pendingQuestionStatus = pendingQuestion?.status;
7797
+ 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);
7563
7798
  const hasPendingQuestion = pendingQuestionMatchesTurn && !!pendingQuestion;
7799
+ const showQuestionForm = hasPendingQuestion && (pendingQuestionStatus === "PENDING" || pendingQuestionStatus === "ANSWER_RESUME_FAILED" || pendingQuestionStatus === "REJECT_RESUME_FAILED");
7800
+ const showResumeState = hasPendingQuestion && (pendingQuestionStatus === "ANSWER_SUBMITTED" || pendingQuestionStatus === "REJECT_SUBMITTED");
7564
7801
  const hasCodeOutputs = !!turn.codeOutputs?.length;
7565
7802
  const hasChart = !!turn.charts?.length;
7566
7803
  const hasTables = !!turn.renderTables?.length;
@@ -7568,8 +7805,8 @@ function AssistantMessage({
7568
7805
  const hasDebug = showDebug && !!turn.debug;
7569
7806
  const hasAnyRenderedContent = hasContent || hasExplanation || hasCodeOutputs || hasChart || hasTables || hasArtifacts || hasDebug;
7570
7807
  const canRegenerate = !!onRegenerate && !!turnId && !isSystemMessage && isLastTurn;
7571
- const renderMode = hasPendingQuestion ? "hitl_form" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : canRegenerate ? "retry" : "empty";
7572
- const showInlineRetry = renderMode === "retry";
7808
+ const showInlineRetry = shouldRenderInlineRetry(turn, canRegenerate) && !hasAnyRenderedContent;
7809
+ const renderMode = showQuestionForm ? "hitl_form" : showResumeState ? "hitl_resuming" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : showInlineRetry ? "retry" : "empty";
7573
7810
  const handleCopyClick = React.useCallback(async () => {
7574
7811
  try {
7575
7812
  if (onCopy) {
@@ -7596,7 +7833,9 @@ function AssistantMessage({
7596
7833
  }
7597
7834
  }, [onRegenerate, turnId]);
7598
7835
  const timestamp = formatRelativeTime(turn.createdAt, t);
7599
- const avatarSlotProps = { text: isSystemMessage ? "SYS" : "AI" };
7836
+ const avatarSlotProps = {
7837
+ text: isSystemMessage ? "SYS" : "AI"
7838
+ };
7600
7839
  const contentSlotProps = {
7601
7840
  content: turn.content,
7602
7841
  citations: turn.citations,
@@ -7639,11 +7878,21 @@ function AssistantMessage({
7639
7878
  return slot;
7640
7879
  };
7641
7880
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.root, children: [
7642
- !hideAvatar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: avatarClassName, children: renderSlot(slots?.avatar, avatarSlotProps, isSystemMessage ? "SYS" : "AI") }),
7881
+ !hideAvatar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: avatarClassName, children: renderSlot(
7882
+ slots?.avatar,
7883
+ avatarSlotProps,
7884
+ isSystemMessage ? "SYS" : "AI"
7885
+ ) }),
7643
7886
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.wrapper, children: [
7644
- /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showInlineRetry && /* @__PURE__ */ jsxRuntime.jsx(RetryActionArea, { onRetry: () => {
7645
- void handleRegenerateClick();
7646
- } }, "inline-retry") }),
7887
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showInlineRetry && /* @__PURE__ */ jsxRuntime.jsx(
7888
+ RetryActionArea,
7889
+ {
7890
+ onRetry: () => {
7891
+ void handleRegenerateClick();
7892
+ }
7893
+ },
7894
+ "inline-retry"
7895
+ ) }),
7647
7896
  turn.codeOutputs && turn.codeOutputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.codeOutputs, children: renderSlot(
7648
7897
  slots?.codeOutputs,
7649
7898
  codeOutputsSlotProps,
@@ -7726,7 +7975,13 @@ function AssistantMessage({
7726
7975
  ]
7727
7976
  }
7728
7977
  ),
7729
- explanationExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-3 text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("BiChat.Common.Loading") }), children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownRenderer2, { content: turn.explanation }) }) })
7978
+ explanationExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-3 text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsxRuntime.jsx(
7979
+ React.Suspense,
7980
+ {
7981
+ fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("BiChat.Common.Loading") }),
7982
+ children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownRenderer2, { content: turn.explanation })
7983
+ }
7984
+ ) })
7730
7985
  ] })
7731
7986
  ) }),
7732
7987
  showDebug && /* @__PURE__ */ jsxRuntime.jsx(DebugPanel, { trace: turn.debug })
@@ -7734,40 +7989,56 @@ function AssistantMessage({
7734
7989
  turn.artifacts && turn.artifacts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.artifacts, children: renderSlot(
7735
7990
  slots?.artifacts,
7736
7991
  artifactsSlotProps,
7737
- turn.artifacts.map((artifact, index) => /* @__PURE__ */ jsxRuntime.jsx(DownloadCard, { artifact }, `${artifact.filename}-${index}`))
7992
+ turn.artifacts.map((artifact, index) => /* @__PURE__ */ jsxRuntime.jsx(
7993
+ DownloadCard,
7994
+ {
7995
+ artifact
7996
+ },
7997
+ `${artifact.filename}-${index}`
7998
+ ))
7738
7999
  ) }),
7739
8000
  renderMode === "hitl_waiting" && /* @__PURE__ */ jsxRuntime.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: [
7740
8001
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-primary-700 dark:text-primary-300", children: t("BiChat.InlineQuestion.InputNeeded") }),
7741
8002
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: t("BiChat.InlineQuestion.WaitingForDetails") })
7742
8003
  ] }),
8004
+ renderMode === "hitl_resuming" && /* @__PURE__ */ jsxRuntime.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: [
8005
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-emerald-700 dark:text-emerald-300", children: pendingQuestion?.status === "REJECT_SUBMITTED" ? "Dismissal submitted" : "Answer submitted" }),
8006
+ /* @__PURE__ */ jsxRuntime.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." })
8007
+ ] }),
7743
8008
  renderMode === "hitl_form" && pendingQuestion && /* @__PURE__ */ jsxRuntime.jsx(InlineQuestionForm, { pendingQuestion }),
7744
- hasContent && !hideActions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classes.actions} ${isCopied ? "opacity-100" : ""}`, children: renderSlot(
7745
- slots?.actions,
7746
- actionsSlotProps,
7747
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7748
- !hideTimestamp && /* @__PURE__ */ jsxRuntime.jsx("span", { className: classes.timestamp, children: timestamp }),
7749
- /* @__PURE__ */ jsxRuntime.jsx(
7750
- "button",
7751
- {
7752
- onClick: handleCopyClick,
7753
- className: `cursor-pointer ${classes.actionButton} ${isCopied ? "text-green-600 dark:text-green-400" : ""}`,
7754
- "aria-label": t("BiChat.Message.CopyMessage"),
7755
- title: isCopied ? t("BiChat.Message.Copied") : t("BiChat.Message.Copy"),
7756
- children: isCopied ? /* @__PURE__ */ jsxRuntime.jsx(react.Check, { size: 14, weight: "bold" }) : /* @__PURE__ */ jsxRuntime.jsx(react.Copy, { size: 14, weight: "regular" })
7757
- }
7758
- ),
7759
- canRegenerate && /* @__PURE__ */ jsxRuntime.jsx(
7760
- "button",
7761
- {
7762
- onClick: handleRegenerateClick,
7763
- className: `cursor-pointer ${classes.actionButton}`,
7764
- "aria-label": t("BiChat.Message.Regenerate"),
7765
- title: t("BiChat.Message.Regenerate"),
7766
- children: /* @__PURE__ */ jsxRuntime.jsx(react.ArrowsClockwise, { size: 14, weight: "regular" })
7767
- }
8009
+ hasContent && !hideActions && /* @__PURE__ */ jsxRuntime.jsx(
8010
+ "div",
8011
+ {
8012
+ className: `${classes.actions} ${isCopied ? "opacity-100" : ""}`,
8013
+ children: renderSlot(
8014
+ slots?.actions,
8015
+ actionsSlotProps,
8016
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8017
+ !hideTimestamp && /* @__PURE__ */ jsxRuntime.jsx("span", { className: classes.timestamp, children: timestamp }),
8018
+ /* @__PURE__ */ jsxRuntime.jsx(
8019
+ "button",
8020
+ {
8021
+ onClick: handleCopyClick,
8022
+ className: `cursor-pointer ${classes.actionButton} ${isCopied ? "text-green-600 dark:text-green-400" : ""}`,
8023
+ "aria-label": t("BiChat.Message.CopyMessage"),
8024
+ title: isCopied ? t("BiChat.Message.Copied") : t("BiChat.Message.Copy"),
8025
+ children: isCopied ? /* @__PURE__ */ jsxRuntime.jsx(react.Check, { size: 14, weight: "bold" }) : /* @__PURE__ */ jsxRuntime.jsx(react.Copy, { size: 14, weight: "regular" })
8026
+ }
8027
+ ),
8028
+ canRegenerate && /* @__PURE__ */ jsxRuntime.jsx(
8029
+ "button",
8030
+ {
8031
+ onClick: handleRegenerateClick,
8032
+ className: `cursor-pointer ${classes.actionButton}`,
8033
+ "aria-label": t("BiChat.Message.Regenerate"),
8034
+ title: t("BiChat.Message.Regenerate"),
8035
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.ArrowsClockwise, { size: 14, weight: "regular" })
8036
+ }
8037
+ )
8038
+ ] })
7768
8039
  )
7769
- ] })
7770
- ) })
8040
+ }
8041
+ )
7771
8042
  ] })
7772
8043
  ] });
7773
8044
  }
@@ -7961,7 +8232,7 @@ function AssistantTurnView({
7961
8232
  );
7962
8233
  }
7963
8234
  var defaultClassNames3 = {
7964
- root: "space-y-4",
8235
+ root: "space-y-4 min-w-0",
7965
8236
  userTurn: "",
7966
8237
  assistantTurn: ""
7967
8238
  };
@@ -8794,9 +9065,9 @@ function MessageListSkeleton() {
8794
9065
  ] });
8795
9066
  }
8796
9067
  function StreamingBubble({ content, normalizedContent }) {
8797
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
9068
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 gap-3", children: [
8798
9069
  /* @__PURE__ */ jsxRuntime.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" }),
8799
- /* @__PURE__ */ jsxRuntime.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: [
9070
+ /* @__PURE__ */ jsxRuntime.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: [
8800
9071
  /* @__PURE__ */ jsxRuntime.jsx(
8801
9072
  React.Suspense,
8802
9073
  {
@@ -8827,8 +9098,8 @@ function MessageList({ renderUserTurn, renderAssistantTurn, thinkingVerbs, readO
8827
9098
  );
8828
9099
  const showAuthorNames = Boolean(session?.isGroup);
8829
9100
  const showEphemeral = showActivityTrace || showTypingIndicator;
8830
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-h-0", children: [
8831
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full overflow-y-auto overflow-x-hidden px-4 py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto space-y-6", children: [
9101
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0 min-h-0", children: [
9102
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full overflow-y-auto overflow-x-hidden px-4 py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full min-w-0 space-y-6", children: [
8832
9103
  fetching && turns.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(MessageListSkeleton, {}),
8833
9104
  turns.map((turn, index) => {
8834
9105
  const turnDate = new Date(turn.createdAt);
@@ -10240,6 +10511,14 @@ function readString(value) {
10240
10511
  return trimmed.length > 0 ? trimmed : null;
10241
10512
  }
10242
10513
  function readPositiveInteger(value) {
10514
+ if (typeof value === "string") {
10515
+ const trimmed = value.trim();
10516
+ if (!/^\d+$/.test(trimmed)) {
10517
+ return null;
10518
+ }
10519
+ const parsed = Number(trimmed);
10520
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
10521
+ }
10243
10522
  if (typeof value !== "number" || !Number.isFinite(value)) {
10244
10523
  return null;
10245
10524
  }
@@ -10290,7 +10569,7 @@ function parseRenderTableDataFromObject(parsed, fallbackId) {
10290
10569
  const headers = headersRaw.length === columns.length ? headersRaw : columns;
10291
10570
  const columnTypesRaw = Array.isArray(parsed.column_types) ? parsed.column_types : Array.isArray(parsed.columnTypes) ? parsed.columnTypes : [];
10292
10571
  const columnTypes = columnTypesRaw.length === columns.length ? columnTypesRaw.map((t) => readString(t) || "string") : void 0;
10293
- const totalRows = readPositiveInteger(parsed.total_rows) || readPositiveInteger(parsed.totalRows) || rows.length;
10572
+ const totalRows = readPositiveInteger(parsed.total_rows) || readPositiveInteger(parsed.totalRows) || readPositiveInteger(parsed.row_count) || readPositiveInteger(parsed.rowCount) || rows.length;
10294
10573
  const pageSize = readPositiveInteger(parsed.page_size) || readPositiveInteger(parsed.pageSize) || 25;
10295
10574
  const query = readString(parsed.query) || readString(parsed.sql);
10296
10575
  if (!query) {
@@ -12064,7 +12343,7 @@ function ChatSessionCore({
12064
12343
  return /* @__PURE__ */ jsxRuntime.jsxs(
12065
12344
  "main",
12066
12345
  {
12067
- className: `flex min-h-0 flex-1 flex-col overflow-hidden bg-gray-50 dark:bg-gray-900 ${className}`,
12346
+ className: `flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden bg-gray-50 dark:bg-gray-900 ${className}`,
12068
12347
  children: [
12069
12348
  headerSlot || /* @__PURE__ */ jsxRuntime.jsx(
12070
12349
  ChatHeader,
@@ -14571,10 +14850,14 @@ function Sidebar2({
14571
14850
  sessions: Array.isArray(group.sessions) ? group.sessions : []
14572
14851
  })) : [];
14573
14852
  }, [unpinnedSessions, t]);
14853
+ const orderedUnpinnedSessions = React.useMemo(
14854
+ () => sessionGroups.flatMap((group) => group.sessions),
14855
+ [sessionGroups]
14856
+ );
14574
14857
  const collapsedIndicators = React.useMemo(() => {
14575
14858
  const seen = /* @__PURE__ */ new Set();
14576
14859
  const result = [];
14577
- for (const s of [...pinnedSessions, ...unpinnedSessions]) {
14860
+ for (const s of [...pinnedSessions, ...orderedUnpinnedSessions]) {
14578
14861
  if (seen.has(s.id)) {
14579
14862
  continue;
14580
14863
  }
@@ -14585,7 +14868,7 @@ function Sidebar2({
14585
14868
  }
14586
14869
  }
14587
14870
  return result;
14588
- }, [pinnedSessions, unpinnedSessions]);
14871
+ }, [pinnedSessions, orderedUnpinnedSessions]);
14589
14872
  const totalSessionCount = filteredSessions.length;
14590
14873
  const overflowCount = Math.max(0, totalSessionCount - collapsedIndicators.length);
14591
14874
  const handleSessionListKeyDown = React.useCallback(
@@ -15406,7 +15689,7 @@ function BiChatLayout({
15406
15689
  const content = routeKey ? /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", initial: false, children: /* @__PURE__ */ jsxRuntime.jsx(
15407
15690
  framerMotion.motion.div,
15408
15691
  {
15409
- className: "flex flex-1 min-h-0",
15692
+ className: "flex flex-1 min-w-0 min-h-0",
15410
15693
  initial: { opacity: 0, y: 4 },
15411
15694
  animate: { opacity: 1, y: 0 },
15412
15695
  exit: { opacity: 0, y: -4 },
@@ -15414,7 +15697,7 @@ function BiChatLayout({
15414
15697
  children
15415
15698
  },
15416
15699
  routeKey
15417
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 min-h-0", children });
15700
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 min-w-0 min-h-0", children });
15418
15701
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex flex-1 w-full h-full min-h-0 overflow-hidden ${className}`, children: [
15419
15702
  /* @__PURE__ */ jsxRuntime.jsx(SkipLink, {}),
15420
15703
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block", children: renderSidebar({}) }),
@@ -15450,7 +15733,7 @@ function BiChatLayout({
15450
15733
  "sidebar-drawer"
15451
15734
  )
15452
15735
  ] }) }),
15453
- /* @__PURE__ */ jsxRuntime.jsxs("main", { id: "main-content", className: "relative flex-1 flex flex-col min-h-0 overflow-hidden", children: [
15736
+ /* @__PURE__ */ jsxRuntime.jsxs("main", { id: "main-content", className: "relative flex-1 min-w-0 flex flex-col min-h-0 overflow-hidden", children: [
15454
15737
  isMobile && !isMobileOpen && /* @__PURE__ */ jsxRuntime.jsx(
15455
15738
  "button",
15456
15739
  {
@@ -17076,7 +17359,7 @@ function useHttpDataSourceConfigFromApplet(options) {
17076
17359
  streamEndpoint,
17077
17360
  csrfToken,
17078
17361
  rpcTimeoutMs: options?.rpcTimeoutMs ?? 12e4,
17079
- streamConnectTimeoutMs: options?.streamConnectTimeoutMs ?? 3e4
17362
+ streamConnectTimeoutMs: options?.streamConnectTimeoutMs
17080
17363
  };
17081
17364
  }, [options?.rpcTimeoutMs, options?.streamConnectTimeoutMs]);
17082
17365
  }
@@ -17485,7 +17768,10 @@ function toSession(session) {
17485
17768
  function toSessionArtifact(artifact) {
17486
17769
  const rawCreatedAt = readNonEmptyString(artifact.createdAt);
17487
17770
  if (!rawCreatedAt) {
17488
- warnMalformedSessionPayload("Artifact missing createdAt; defaulting to epoch", { id: artifact.id });
17771
+ warnMalformedSessionPayload(
17772
+ "Artifact missing createdAt; defaulting to epoch",
17773
+ { id: artifact.id }
17774
+ );
17489
17775
  }
17490
17776
  const createdAt = rawCreatedAt ?? "1970-01-01T00:00:00.000Z";
17491
17777
  return {
@@ -17507,6 +17793,21 @@ function normalizeQuestionType2(rawType) {
17507
17793
  const normalized = readString2(rawType).trim().toUpperCase().replace(/[\s-]+/g, "_");
17508
17794
  return normalized === "MULTIPLE_CHOICE" ? "MULTIPLE_CHOICE" : "SINGLE_CHOICE";
17509
17795
  }
17796
+ function normalizePendingQuestionStatus(rawStatus) {
17797
+ const normalized = readString2(rawStatus).trim().toUpperCase();
17798
+ switch (normalized) {
17799
+ case "ANSWER_SUBMITTED":
17800
+ case "REJECT_SUBMITTED":
17801
+ case "ANSWER_RESUME_FAILED":
17802
+ case "REJECT_RESUME_FAILED":
17803
+ case "ANSWERED":
17804
+ case "REJECTED":
17805
+ case "CANCELLED":
17806
+ return normalized;
17807
+ default:
17808
+ return "PENDING";
17809
+ }
17810
+ }
17510
17811
  function normalizeMessageRole(rawRole) {
17511
17812
  const normalized = readString2(rawRole).trim().toLowerCase();
17512
17813
  if (normalized === "user" /* User */) {
@@ -17522,11 +17823,17 @@ function normalizeMessageRole(rawRole) {
17522
17823
  }
17523
17824
  function sanitizeAttachment(rawAttachment, turnId, index) {
17524
17825
  if (!isRecord2(rawAttachment)) {
17525
- warnMalformedSessionPayload("Dropped malformed attachment entry", { turnId, index });
17826
+ warnMalformedSessionPayload("Dropped malformed attachment entry", {
17827
+ turnId,
17828
+ index
17829
+ });
17526
17830
  return null;
17527
17831
  }
17528
17832
  const filename = readString2(rawAttachment.filename, "attachment");
17529
- const mimeType = readString2(rawAttachment.mimeType, "application/octet-stream");
17833
+ const mimeType = readString2(
17834
+ rawAttachment.mimeType,
17835
+ "application/octet-stream"
17836
+ );
17530
17837
  const id = readNonEmptyString(rawAttachment.id) || void 0;
17531
17838
  const clientKey = readNonEmptyString(rawAttachment.clientKey) || id || `${turnId}-attachment-${index}`;
17532
17839
  return {
@@ -17562,7 +17869,10 @@ function sanitizeAssistantArtifacts(rawArtifacts, turnId) {
17562
17869
  for (let i = 0; i < rawArtifacts.length; i++) {
17563
17870
  const raw = rawArtifacts[i];
17564
17871
  if (!isRecord2(raw)) {
17565
- warnMalformedSessionPayload("Dropped malformed assistant artifact", { turnId, index: i });
17872
+ warnMalformedSessionPayload("Dropped malformed assistant artifact", {
17873
+ turnId,
17874
+ index: i
17875
+ });
17566
17876
  continue;
17567
17877
  }
17568
17878
  const type = readString2(raw.type).toLowerCase();
@@ -17571,7 +17881,10 @@ function sanitizeAssistantArtifacts(rawArtifacts, turnId) {
17571
17881
  }
17572
17882
  const url = readNonEmptyString(raw.url);
17573
17883
  if (!url) {
17574
- warnMalformedSessionPayload("Dropped assistant artifact without url", { turnId, index: i });
17884
+ warnMalformedSessionPayload("Dropped assistant artifact without url", {
17885
+ turnId,
17886
+ index: i
17887
+ });
17575
17888
  continue;
17576
17889
  }
17577
17890
  artifacts.push({
@@ -17590,12 +17903,16 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17590
17903
  return void 0;
17591
17904
  }
17592
17905
  if (!isRecord2(rawAssistantTurn)) {
17593
- warnMalformedSessionPayload("Dropped malformed assistant turn payload", { turnId });
17906
+ warnMalformedSessionPayload("Dropped malformed assistant turn payload", {
17907
+ turnId
17908
+ });
17594
17909
  return void 0;
17595
17910
  }
17596
17911
  const assistantID = readNonEmptyString(rawAssistantTurn.id);
17597
17912
  if (!assistantID) {
17598
- warnMalformedSessionPayload("Dropped assistant turn without id", { turnId });
17913
+ warnMalformedSessionPayload("Dropped assistant turn without id", {
17914
+ turnId
17915
+ });
17599
17916
  return void 0;
17600
17917
  }
17601
17918
  const citations = Array.isArray(rawAssistantTurn.citations) ? rawAssistantTurn.citations.filter((item) => isRecord2(item)).map((item, index) => ({
@@ -17632,17 +17949,27 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17632
17949
  schemaVersion: readNonEmptyString(rawAssistantTurn.debug.schemaVersion) || void 0,
17633
17950
  startedAt: readNonEmptyString(rawAssistantTurn.debug.startedAt) || void 0,
17634
17951
  completedAt: readNonEmptyString(rawAssistantTurn.debug.completedAt) || void 0,
17635
- generationMs: readOptionalFiniteNumber(rawAssistantTurn.debug.generationMs),
17952
+ generationMs: readOptionalFiniteNumber(
17953
+ rawAssistantTurn.debug.generationMs
17954
+ ),
17636
17955
  traceId: readNonEmptyString(rawAssistantTurn.debug.traceId) || void 0,
17637
17956
  traceUrl: readNonEmptyString(rawAssistantTurn.debug.traceUrl) || void 0,
17638
17957
  sessionId: readNonEmptyString(rawAssistantTurn.debug.sessionId) || void 0,
17639
17958
  thinking: readNonEmptyString(rawAssistantTurn.debug.thinking) || void 0,
17640
17959
  observationReason: readNonEmptyString(rawAssistantTurn.debug.observationReason) || void 0,
17641
17960
  usage: isRecord2(rawAssistantTurn.debug.usage) ? {
17642
- promptTokens: readFiniteNumber(rawAssistantTurn.debug.usage.promptTokens),
17643
- completionTokens: readFiniteNumber(rawAssistantTurn.debug.usage.completionTokens),
17644
- totalTokens: readFiniteNumber(rawAssistantTurn.debug.usage.totalTokens),
17645
- cachedTokens: readOptionalFiniteNumber(rawAssistantTurn.debug.usage.cachedTokens),
17961
+ promptTokens: readFiniteNumber(
17962
+ rawAssistantTurn.debug.usage.promptTokens
17963
+ ),
17964
+ completionTokens: readFiniteNumber(
17965
+ rawAssistantTurn.debug.usage.completionTokens
17966
+ ),
17967
+ totalTokens: readFiniteNumber(
17968
+ rawAssistantTurn.debug.usage.totalTokens
17969
+ ),
17970
+ cachedTokens: readOptionalFiniteNumber(
17971
+ rawAssistantTurn.debug.usage.cachedTokens
17972
+ ),
17646
17973
  cost: readOptionalFiniteNumber(rawAssistantTurn.debug.usage.cost)
17647
17974
  } : void 0,
17648
17975
  tools: Array.isArray(rawAssistantTurn.debug.tools) ? rawAssistantTurn.debug.tools.filter((tool) => isRecord2(tool)).map((tool) => ({
@@ -17660,7 +17987,9 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17660
17987
  provider: readNonEmptyString(attempt.provider) || void 0,
17661
17988
  finishReason: readNonEmptyString(attempt.finishReason) || void 0,
17662
17989
  promptTokens: readOptionalFiniteNumber(attempt.promptTokens),
17663
- completionTokens: readOptionalFiniteNumber(attempt.completionTokens),
17990
+ completionTokens: readOptionalFiniteNumber(
17991
+ attempt.completionTokens
17992
+ ),
17664
17993
  totalTokens: readOptionalFiniteNumber(attempt.totalTokens),
17665
17994
  cachedTokens: readOptionalFiniteNumber(attempt.cachedTokens),
17666
17995
  cost: readOptionalFiniteNumber(attempt.cost),
@@ -17729,16 +18058,25 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17729
18058
  }
17730
18059
  function sanitizeConversationTurn(rawTurn, index, fallbackSessionID) {
17731
18060
  if (!isRecord2(rawTurn)) {
17732
- warnMalformedSessionPayload("Dropped malformed turn payload (not an object)", { index });
18061
+ warnMalformedSessionPayload(
18062
+ "Dropped malformed turn payload (not an object)",
18063
+ { index }
18064
+ );
17733
18065
  return null;
17734
18066
  }
17735
18067
  if (!isRecord2(rawTurn.userTurn)) {
17736
- warnMalformedSessionPayload("Dropped malformed turn payload (missing user turn)", { index });
18068
+ warnMalformedSessionPayload(
18069
+ "Dropped malformed turn payload (missing user turn)",
18070
+ { index }
18071
+ );
17737
18072
  return null;
17738
18073
  }
17739
18074
  const userTurnID = readNonEmptyString(rawTurn.userTurn.id);
17740
18075
  if (!userTurnID) {
17741
- warnMalformedSessionPayload("Dropped malformed turn payload (missing user turn id)", { index });
18076
+ warnMalformedSessionPayload(
18077
+ "Dropped malformed turn payload (missing user turn id)",
18078
+ { index }
18079
+ );
17742
18080
  return null;
17743
18081
  }
17744
18082
  const turnID = readString2(rawTurn.id, userTurnID);
@@ -17752,17 +18090,27 @@ function sanitizeConversationTurn(rawTurn, index, fallbackSessionID) {
17752
18090
  userTurn: {
17753
18091
  id: userTurnID,
17754
18092
  content: readString2(rawTurn.userTurn.content),
17755
- attachments: sanitizeUserAttachments(rawTurn.userTurn.attachments, turnID),
18093
+ attachments: sanitizeUserAttachments(
18094
+ rawTurn.userTurn.attachments,
18095
+ turnID
18096
+ ),
17756
18097
  author: mapSessionUser(rawTurn.userTurn.author),
17757
18098
  createdAt: readString2(rawTurn.userTurn.createdAt, createdAt)
17758
18099
  },
17759
- assistantTurn: sanitizeAssistantTurn(rawTurn.assistantTurn, createdAt, turnID),
18100
+ assistantTurn: sanitizeAssistantTurn(
18101
+ rawTurn.assistantTurn,
18102
+ createdAt,
18103
+ turnID
18104
+ ),
17760
18105
  createdAt
17761
18106
  };
17762
18107
  }
17763
18108
  function sanitizeConversationTurns(rawTurns, sessionID) {
17764
18109
  if (!Array.isArray(rawTurns)) {
17765
- warnMalformedSessionPayload("Session payload contained non-array turns field", { sessionID });
18110
+ warnMalformedSessionPayload(
18111
+ "Session payload contained non-array turns field",
18112
+ { sessionID }
18113
+ );
17766
18114
  return [];
17767
18115
  }
17768
18116
  const turns = [];
@@ -17776,11 +18124,14 @@ function sanitizeConversationTurns(rawTurns, sessionID) {
17776
18124
  }
17777
18125
  }
17778
18126
  if (dropped > 0) {
17779
- warnMalformedSessionPayload("Dropped malformed turns from session payload", {
17780
- sessionID,
17781
- dropped,
17782
- total: rawTurns.length
17783
- });
18127
+ warnMalformedSessionPayload(
18128
+ "Dropped malformed turns from session payload",
18129
+ {
18130
+ sessionID,
18131
+ dropped,
18132
+ total: rawTurns.length
18133
+ }
18134
+ );
17784
18135
  }
17785
18136
  return turns;
17786
18137
  }
@@ -17790,39 +18141,57 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
17790
18141
  }
17791
18142
  const checkpointID = readNonEmptyString(rawPendingQuestion.checkpointId);
17792
18143
  if (!checkpointID) {
17793
- warnMalformedSessionPayload("Dropped malformed pendingQuestion without checkpointId", { sessionID });
18144
+ warnMalformedSessionPayload(
18145
+ "Dropped malformed pendingQuestion without checkpointId",
18146
+ { sessionID }
18147
+ );
17794
18148
  return null;
17795
18149
  }
17796
18150
  if (!Array.isArray(rawPendingQuestion.questions)) {
17797
- warnMalformedSessionPayload("Pending question had non-array questions payload", {
17798
- sessionID,
17799
- checkpointID
17800
- });
18151
+ warnMalformedSessionPayload(
18152
+ "Pending question had non-array questions payload",
18153
+ {
18154
+ sessionID,
18155
+ checkpointID
18156
+ }
18157
+ );
17801
18158
  }
17802
18159
  const questions = Array.isArray(rawPendingQuestion.questions) ? rawPendingQuestion.questions.filter((question) => {
17803
18160
  if (!question || !isRecord2(question)) {
17804
- warnMalformedSessionPayload("Dropped malformed question from pendingQuestion", {
17805
- sessionID,
17806
- checkpointID
17807
- });
18161
+ warnMalformedSessionPayload(
18162
+ "Dropped malformed question from pendingQuestion",
18163
+ {
18164
+ sessionID,
18165
+ checkpointID
18166
+ }
18167
+ );
17808
18168
  return false;
17809
18169
  }
17810
18170
  return true;
17811
18171
  }).map((question, index) => {
17812
- const questionID = readString2(question.id, `${checkpointID}-q-${index}`);
18172
+ const questionID = readString2(
18173
+ question.id,
18174
+ `${checkpointID}-q-${index}`
18175
+ );
17813
18176
  const options = Array.isArray(question.options) ? question.options.filter((option) => {
17814
18177
  if (!option || !isRecord2(option)) {
17815
- warnMalformedSessionPayload("Dropped malformed pendingQuestion option", {
17816
- sessionID,
17817
- checkpointID,
17818
- questionID
17819
- });
18178
+ warnMalformedSessionPayload(
18179
+ "Dropped malformed pendingQuestion option",
18180
+ {
18181
+ sessionID,
18182
+ checkpointID,
18183
+ questionID
18184
+ }
18185
+ );
17820
18186
  return false;
17821
18187
  }
17822
18188
  return true;
17823
18189
  }).map((option, optionIndex) => {
17824
18190
  const label = readString2(option.label);
17825
- const id = readString2(option.id, `${questionID}-opt-${optionIndex}`);
18191
+ const id = readString2(
18192
+ option.id,
18193
+ `${questionID}-opt-${optionIndex}`
18194
+ );
17826
18195
  return {
17827
18196
  id,
17828
18197
  label,
@@ -17841,7 +18210,7 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
17841
18210
  turnId: readString2(rawPendingQuestion.turnId),
17842
18211
  agentName: readNonEmptyString(rawPendingQuestion.agentName) || void 0,
17843
18212
  questions,
17844
- status: "PENDING"
18213
+ status: normalizePendingQuestionStatus(rawPendingQuestion.status)
17845
18214
  };
17846
18215
  }
17847
18216
  function formatSizeReadable(bytes) {
@@ -17862,13 +18231,17 @@ function parseRowCount(metadata) {
17862
18231
  if (!metadata) {
17863
18232
  return void 0;
17864
18233
  }
17865
- const raw = metadata.row_count ?? metadata.rowCount;
17866
- if (typeof raw === "number" && Number.isFinite(raw)) {
18234
+ const raw = metadata.row_count ?? metadata.rowCount ?? metadata.total_rows ?? metadata.totalRows;
18235
+ if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 0) {
17867
18236
  return raw;
17868
18237
  }
17869
18238
  if (typeof raw === "string") {
17870
- const parsed = Number.parseInt(raw, 10);
17871
- if (Number.isFinite(parsed)) {
18239
+ const trimmed = raw.trim();
18240
+ if (!/^\d+$/.test(trimmed)) {
18241
+ return void 0;
18242
+ }
18243
+ const parsed = Number(trimmed);
18244
+ if (Number.isSafeInteger(parsed)) {
17872
18245
  return parsed;
17873
18246
  }
17874
18247
  }
@@ -18046,7 +18419,9 @@ function attachArtifactsToTurns(turns, artifacts) {
18046
18419
  if (artifacts.length === 0) {
18047
18420
  return turns;
18048
18421
  }
18049
- 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));
18422
+ const downloadArtifacts = artifacts.map((raw) => ({ raw, mapped: toDownloadArtifact(raw) })).filter(
18423
+ (entry) => entry.mapped !== null
18424
+ ).sort((a, b) => toMillis(a.raw.createdAt) - toMillis(b.raw.createdAt));
18050
18425
  const chartArtifacts = artifacts.filter((a) => a.type === "chart").sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
18051
18426
  const tableArtifacts = artifacts.filter((a) => a.type === "table").sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
18052
18427
  if (downloadArtifacts.length === 0 && chartArtifacts.length === 0 && tableArtifacts.length === 0) {
@@ -18135,14 +18510,19 @@ function attachArtifactsToTurns(turns, artifacts) {
18135
18510
  continue;
18136
18511
  }
18137
18512
  if (assistantTurn.renderTables === void 0) {
18138
- assistantTurn.renderTables = extractRenderTablesFromToolCalls(assistantTurn.toolCalls);
18513
+ assistantTurn.renderTables = extractRenderTablesFromToolCalls(
18514
+ assistantTurn.toolCalls
18515
+ );
18139
18516
  }
18140
18517
  const existing = assistantTurn.renderTables;
18141
18518
  const metadata = raw.metadata;
18142
18519
  if (!metadata || typeof metadata !== "object" || metadata === null) {
18143
18520
  continue;
18144
18521
  }
18145
- const tableData = parseRenderTableDataFromMetadata(metadata, raw.id);
18522
+ const tableData = parseRenderTableDataFromMetadata(
18523
+ metadata,
18524
+ raw.id
18525
+ );
18146
18526
  if (!tableData) {
18147
18527
  continue;
18148
18528
  }
@@ -19007,7 +19387,7 @@ var HttpDataSource = class {
19007
19387
  uploadEndpoint: "/api/uploads",
19008
19388
  ...config,
19009
19389
  rpcTimeoutMs: typeof config.rpcTimeoutMs === "number" ? config.rpcTimeoutMs : 12e4,
19010
- streamConnectTimeoutMs: typeof config.streamConnectTimeoutMs === "number" ? config.streamConnectTimeoutMs : 3e4
19390
+ streamConnectTimeoutMs: typeof config.streamConnectTimeoutMs === "number" ? config.streamConnectTimeoutMs : void 0
19011
19391
  };
19012
19392
  this.rpc = createAppletRPCClient({
19013
19393
  endpoint: `${this.config.baseUrl}${this.config.rpcEndpoint}`,