@iota-uz/sdk 0.4.28 → 0.4.30

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.
@@ -2,7 +2,7 @@ import React, { createContext, memo, useRef, useEffect, useCallback, useState, u
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import ReactApexChart from 'react-apexcharts';
4
4
  import ApexCharts from 'apexcharts';
5
- import { CaretUp, CaretDown, DotsThreeVertical, Check, Copy, X, Columns, ArrowsIn, ArrowsOut, Warning, ArrowClockwise, Paperclip, Stop, PaperPlaneRight, ChartBar, FileText, Lightbulb, CircleNotch, ArrowUUpLeft, PencilSimple, Bookmark, ArrowsClockwise, Archive, Trash, UsersThree, DotsThree, Image, MagnifyingGlass, DownloadSimple, ArrowCounterClockwise, Bug, ArrowUp, ArrowDown, Stack, ImageBroken, CaretLeft, CaretRight, Info, CheckCircle, XCircle, Spinner, WarningCircle, FilePdf, FileXls, FileCsv, FileDoc, FileCode, File as File$1, MagnifyingGlassMinus, MagnifyingGlassPlus, Download, ChatCircleDots, PencilSimpleLine, ArrowLeft, PaperPlaneTilt, ArrowRight, Timer, Lightning, Database, ArrowSquareOut, Wrench, ClockCounterClockwise, Package, Plus, Crown, UserPlus, ArrowsCounterClockwise, ChatCircle, Gear, Users, List, CaretLineLeft, CaretLineRight, Code, Table, SpinnerGap, FloppyDisk, ShareNetwork, Sidebar } from '@phosphor-icons/react';
5
+ import { CaretUp, CaretDown, DotsThreeVertical, Check, Copy, X, Columns, ArrowsIn, ArrowsOut, Warning, ArrowClockwise, Paperclip, Stop, PaperPlaneRight, ChartBar, FileText, Lightbulb, CircleNotch, ArrowUUpLeft, PencilSimple, Bookmark, ArrowsClockwise, Archive, Trash, UsersThree, DotsThree, Image, MagnifyingGlass, DownloadSimple, ArrowCounterClockwise, Bug, ArrowUp, ArrowDown, Stack, Brain, CaretUpDown, ImageBroken, CaretLeft, CaretRight, Info, CheckCircle, XCircle, Spinner, WarningCircle, FilePdf, FileXls, FileCsv, FileDoc, FileCode, File as File$1, MagnifyingGlassMinus, MagnifyingGlassPlus, Download, ChatCircleDots, PencilSimpleLine, ArrowLeft, PaperPlaneTilt, ArrowRight, Timer, Lightning, Database, ArrowSquareOut, Wrench, ClockCounterClockwise, Package, Plus, Crown, UserPlus, ArrowsCounterClockwise, ChatCircle, Gear, Users, List, CaretLineLeft, CaretLineRight, Code, Table, SpinnerGap, FloppyDisk, ShareNetwork, Sidebar } from '@phosphor-icons/react';
6
6
  import { Prism } from 'react-syntax-highlighter';
7
7
  import { vscDarkPlus, vs } from 'react-syntax-highlighter/dist/esm/styles/prism';
8
8
  import ReactMarkdown from 'react-markdown';
@@ -1945,6 +1945,12 @@ function normalizeQuestionType(rawType) {
1945
1945
  const normalized = String(rawType || "").trim().toUpperCase().replace(/[\s-]+/g, "_");
1946
1946
  return normalized === "MULTIPLE_CHOICE" ? "MULTIPLE_CHOICE" : "SINGLE_CHOICE";
1947
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
+ }
1948
1954
  function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1949
1955
  if (!interrupt) {
1950
1956
  return null;
@@ -1972,7 +1978,7 @@ function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1972
1978
  };
1973
1979
  }
1974
1980
  function resolvePendingQuestionTurnIndex(turns, pendingQuestion) {
1975
- if (!pendingQuestion || pendingQuestion.status !== "PENDING" || turns.length === 0) {
1981
+ if (!pendingQuestion || !isOpenQuestionStatus(pendingQuestion.status) || turns.length === 0) {
1976
1982
  return -1;
1977
1983
  }
1978
1984
  const pendingTurnId = pendingQuestion.turnId?.trim();
@@ -1999,7 +2005,7 @@ function applyTurnLifecycleForPendingQuestion(turns, pendingQuestion) {
1999
2005
  let changed = false;
2000
2006
  const nextTurns = turns.map((turn, index) => {
2001
2007
  const shouldWaitForInput = pendingIndex === index;
2002
- const desiredLifecycle = shouldWaitForInput ? "waiting_for_human_input" : "complete";
2008
+ const desiredLifecycle = shouldWaitForInput ? shouldPromptForHumanInput(pendingQuestion?.status) ? "waiting_for_human_input" : "complete" : "complete";
2003
2009
  if (!turn.assistantTurn) {
2004
2010
  if (!shouldWaitForInput || !pendingQuestion) {
2005
2011
  return turn;
@@ -2175,7 +2181,9 @@ var ChatMachine = class {
2175
2181
  this.onSessionCreated = config.onSessionCreated;
2176
2182
  this.reasoningEffortOptions = this.buildReasoningEffortOptions();
2177
2183
  this.reasoningEffortOptionSet = this.reasoningEffortOptions ? new Set(this.reasoningEffortOptions) : null;
2178
- const initialReasoningEffort = this.sanitizeReasoningEffort(loadReasoningEffort() || void 0);
2184
+ const initialReasoningEffort = this.sanitizeReasoningEffort(
2185
+ loadReasoningEffort() || void 0
2186
+ );
2179
2187
  if (!initialReasoningEffort) {
2180
2188
  clearReasoningEffort();
2181
2189
  }
@@ -2443,7 +2451,9 @@ var ChatMachine = class {
2443
2451
  */
2444
2452
  _setTurnsFromFetch(fetchedTurns, pendingQuestion) {
2445
2453
  if (!Array.isArray(fetchedTurns)) {
2446
- console.warn("[ChatMachine] Ignoring malformed turns payload from fetchSession");
2454
+ console.warn(
2455
+ "[ChatMachine] Ignoring malformed turns payload from fetchSession"
2456
+ );
2447
2457
  return;
2448
2458
  }
2449
2459
  const prev = this.state.messaging.turns;
@@ -2454,7 +2464,10 @@ var ChatMachine = class {
2454
2464
  patch.pendingQuestion = pendingQuestion;
2455
2465
  }
2456
2466
  if (hasPendingUserOnly && (!fetchedTurns || fetchedTurns.length === 0)) {
2457
- const lifecycleTurns = applyTurnLifecycleForPendingQuestion(prev, effectivePendingQuestion);
2467
+ const lifecycleTurns = applyTurnLifecycleForPendingQuestion(
2468
+ prev,
2469
+ effectivePendingQuestion
2470
+ );
2458
2471
  if (lifecycleTurns !== prev) {
2459
2472
  patch.turns = lifecycleTurns;
2460
2473
  }
@@ -2463,7 +2476,10 @@ var ChatMachine = class {
2463
2476
  }
2464
2477
  return;
2465
2478
  }
2466
- patch.turns = applyTurnLifecycleForPendingQuestion(fetchedTurns ?? prev, effectivePendingQuestion);
2479
+ patch.turns = applyTurnLifecycleForPendingQuestion(
2480
+ fetchedTurns ?? prev,
2481
+ effectivePendingQuestion
2482
+ );
2467
2483
  this._updateMessaging(patch);
2468
2484
  }
2469
2485
  /**
@@ -2520,10 +2536,16 @@ var ChatMachine = class {
2520
2536
  this._updateMessaging({ generationInProgress: false });
2521
2537
  this.dataSource.fetchSession(sessionId).then((result) => {
2522
2538
  if (this.state.session.currentSessionId === sessionId && result) {
2523
- this._setTurnsFromFetch(result.turns, result.pendingQuestion ?? null);
2539
+ this._setTurnsFromFetch(
2540
+ result.turns,
2541
+ result.pendingQuestion ?? null
2542
+ );
2524
2543
  }
2525
2544
  }).catch((err) => {
2526
- console.error("[ChatMachine] fetchSession after stream inactive:", err);
2545
+ console.error(
2546
+ "[ChatMachine] fetchSession after stream inactive:",
2547
+ err
2548
+ );
2527
2549
  });
2528
2550
  }
2529
2551
  }).catch((err) => {
@@ -2584,7 +2606,10 @@ var ChatMachine = class {
2584
2606
  if (this.disposed) {
2585
2607
  return;
2586
2608
  }
2587
- 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
+ );
2588
2613
  const getStreamStatus2 = this.dataSource.getStreamStatus;
2589
2614
  const status = getStreamStatus2 ? await getStreamStatus2(sessionId).catch(() => null) : null;
2590
2615
  if (!status?.active) {
@@ -2625,9 +2650,11 @@ var ChatMachine = class {
2625
2650
  if (typeof window === "undefined") {
2626
2651
  return;
2627
2652
  }
2628
- window.dispatchEvent(new CustomEvent("bichat:sessions-updated", {
2629
- detail: { reason, sessionId }
2630
- }));
2653
+ window.dispatchEvent(
2654
+ new CustomEvent("bichat:sessions-updated", {
2655
+ detail: { reason, sessionId }
2656
+ })
2657
+ );
2631
2658
  }
2632
2659
  _cancel() {
2633
2660
  if (this.abortController) {
@@ -2675,10 +2702,15 @@ var ChatMachine = class {
2675
2702
  this._setDebugModeForSession(key3, nextDebugMode);
2676
2703
  if (nextDebugMode && this.state.session.currentSessionId && this.state.session.currentSessionId !== "new") {
2677
2704
  try {
2678
- const result = await this.dataSource.fetchSession(this.state.session.currentSessionId);
2705
+ const result = await this.dataSource.fetchSession(
2706
+ this.state.session.currentSessionId
2707
+ );
2679
2708
  if (result) {
2680
2709
  this._updateSession({ session: result.session });
2681
- this._setTurnsFromFetch(result.turns, result.pendingQuestion || null);
2710
+ this._setTurnsFromFetch(
2711
+ result.turns,
2712
+ result.pendingQuestion || null
2713
+ );
2682
2714
  }
2683
2715
  } catch (err) {
2684
2716
  console.error("Failed to refresh session for debug mode:", err);
@@ -2706,7 +2738,10 @@ var ChatMachine = class {
2706
2738
  }
2707
2739
  this._updateMessaging({ codeOutputs: [] });
2708
2740
  } catch (err) {
2709
- const normalized = normalizeRPCError(err, "Failed to clear session history");
2741
+ const normalized = normalizeRPCError(
2742
+ err,
2743
+ "Failed to clear session history"
2744
+ );
2710
2745
  this._updateInput({ inputError: normalized.userMessage });
2711
2746
  } finally {
2712
2747
  this._updateMessaging({ loading: false, isStreaming: false });
@@ -2727,7 +2762,12 @@ var ChatMachine = class {
2727
2762
  }
2728
2763
  this._updateMessaging({
2729
2764
  turns: applyTurnLifecycleForPendingQuestion(
2730
- [createCompactedSystemTurn(curSessionId, "Compacting conversation history...")],
2765
+ [
2766
+ createCompactedSystemTurn(
2767
+ curSessionId,
2768
+ "Compacting conversation history..."
2769
+ )
2770
+ ],
2731
2771
  null
2732
2772
  ),
2733
2773
  pendingQuestion: null
@@ -2737,17 +2777,27 @@ var ChatMachine = class {
2737
2777
  const result = await this.dataSource.fetchSession(curSessionId);
2738
2778
  if (result) {
2739
2779
  this._updateSession({ session: result.session });
2740
- this._setTurnsFromFetch(result.turns, result.pendingQuestion || null);
2780
+ this._setTurnsFromFetch(
2781
+ result.turns,
2782
+ result.pendingQuestion || null
2783
+ );
2741
2784
  } else {
2742
2785
  this._setTurnsFromFetch([], null);
2743
2786
  }
2744
2787
  this._updateMessaging({ codeOutputs: [] });
2745
2788
  }
2746
2789
  } catch (err) {
2747
- const normalized = normalizeRPCError(err, "Failed to compact session history");
2790
+ const normalized = normalizeRPCError(
2791
+ err,
2792
+ "Failed to compact session history"
2793
+ );
2748
2794
  this._updateInput({ inputError: normalized.userMessage });
2749
2795
  } finally {
2750
- this._updateMessaging({ isCompacting: false, loading: false, isStreaming: false });
2796
+ this._updateMessaging({
2797
+ isCompacting: false,
2798
+ loading: false,
2799
+ isStreaming: false
2800
+ });
2751
2801
  }
2752
2802
  return true;
2753
2803
  }
@@ -2759,9 +2809,13 @@ var ChatMachine = class {
2759
2809
  this._updateMessaging({ turns: [...prevTurns, tempTurn] });
2760
2810
  return;
2761
2811
  }
2762
- const idx = prevTurns.findIndex((turn) => turn.userTurn.id === replaceFromMessageID);
2812
+ const idx = prevTurns.findIndex(
2813
+ (turn) => turn.userTurn.id === replaceFromMessageID
2814
+ );
2763
2815
  if (idx === -1) {
2764
- 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
+ );
2765
2819
  this._updateMessaging({ turns: [...prevTurns, tempTurn] });
2766
2820
  return;
2767
2821
  }
@@ -2845,7 +2899,10 @@ var ChatMachine = class {
2845
2899
  if (chunk.sessionId) {
2846
2900
  createdSessionId = chunk.sessionId;
2847
2901
  }
2848
- const pendingFromInterrupt = pendingQuestionFromInterrupt(chunk.interrupt, tempTurnId);
2902
+ const pendingFromInterrupt = pendingQuestionFromInterrupt(
2903
+ chunk.interrupt,
2904
+ tempTurnId
2905
+ );
2849
2906
  if (pendingFromInterrupt) {
2850
2907
  this._updateMessaging({
2851
2908
  pendingQuestion: pendingFromInterrupt,
@@ -2919,7 +2976,9 @@ var ChatMachine = class {
2919
2976
  this._updateInput({ message: content });
2920
2977
  this._clearStreamError();
2921
2978
  this._updateMessaging({
2922
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurnId)
2979
+ turns: this.state.messaging.turns.filter(
2980
+ (turn) => turn.id !== tempTurnId
2981
+ )
2923
2982
  });
2924
2983
  const sessionId = this.sendingSessionId ?? this.state.session.currentSessionId;
2925
2984
  if (sessionId && sessionId !== "new") {
@@ -2929,7 +2988,9 @@ var ChatMachine = class {
2929
2988
  return false;
2930
2989
  }
2931
2990
  this._updateMessaging({
2932
- turns: this.state.messaging.turns.filter((turn) => turn.id !== tempTurnId)
2991
+ turns: this.state.messaging.turns.filter(
2992
+ (turn) => turn.id !== tempTurnId
2993
+ )
2933
2994
  });
2934
2995
  const normalized = normalizeRPCError(err, "Failed to send message");
2935
2996
  this._updateInput({ inputError: normalized.userMessage });
@@ -2997,7 +3058,11 @@ var ChatMachine = class {
2997
3058
  const curSessionId = this.state.session.currentSessionId;
2998
3059
  const curDebugMode = deriveDebugMode(this.state);
2999
3060
  const replaceFromMessageID = options?.replaceFromMessageID;
3000
- const tempTurn = createPendingTurn(curSessionId || "new", content, attachments);
3061
+ const tempTurn = createPendingTurn(
3062
+ curSessionId || "new",
3063
+ content,
3064
+ attachments
3065
+ );
3001
3066
  this.lastSendAttempt = { content, attachments, options };
3002
3067
  const prevTurns = this.state.messaging.turns;
3003
3068
  this._insertOptimisticTurn(prevTurns, tempTurn, replaceFromMessageID);
@@ -3005,22 +3070,22 @@ var ChatMachine = class {
3005
3070
  try {
3006
3071
  const { activeSessionId, shouldNavigateAfter } = await this._resolveSendSession(curSessionId, curDebugMode);
3007
3072
  this.sendingSessionId = activeSessionId || null;
3008
- const {
3009
- createdSessionId,
3010
- sessionFetched,
3011
- stopped
3012
- } = await this._runSendStream({
3073
+ const { createdSessionId, sessionFetched, stopped } = await this._runSendStream({
3013
3074
  activeSessionId,
3014
3075
  content,
3015
3076
  attachments,
3016
3077
  debugMode: curDebugMode,
3017
3078
  replaceFromMessageID,
3018
- reasoningEffort: this.sanitizeReasoningEffort(this.state.session.reasoningEffort),
3079
+ reasoningEffort: this.sanitizeReasoningEffort(
3080
+ this.state.session.reasoningEffort
3081
+ ),
3019
3082
  tempTurnId: tempTurn.id
3020
3083
  });
3021
3084
  if (stopped) {
3022
3085
  this._updateMessaging({
3023
- 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
+ )
3024
3089
  });
3025
3090
  this._updateInput({ message: content });
3026
3091
  this._clearStreamError();
@@ -3030,7 +3095,11 @@ var ChatMachine = class {
3030
3095
  });
3031
3096
  }
3032
3097
  } else {
3033
- await this._ensureSessionSyncAfterStream(activeSessionId, createdSessionId, sessionFetched);
3098
+ await this._ensureSessionSyncAfterStream(
3099
+ activeSessionId,
3100
+ createdSessionId,
3101
+ sessionFetched
3102
+ );
3034
3103
  const targetSessionId = createdSessionId || activeSessionId;
3035
3104
  this._finalizeSuccessfulSend(targetSessionId, shouldNavigateAfter);
3036
3105
  }
@@ -3068,7 +3137,9 @@ var ChatMachine = class {
3068
3137
  }
3069
3138
  this._updateMessaging({ thinkingContent: updated });
3070
3139
  const steps = this.state.messaging.activeSteps;
3071
- 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
+ );
3072
3143
  if (!existing) {
3073
3144
  const step = {
3074
3145
  id: `thinking-${Date.now()}`,
@@ -3099,7 +3170,9 @@ var ChatMachine = class {
3099
3170
  }
3100
3171
  _handleToolEnd(tool) {
3101
3172
  const steps = [...this.state.messaging.activeSteps];
3102
- 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
+ );
3103
3176
  if (idx !== -1) {
3104
3177
  steps[idx] = {
3105
3178
  ...steps[idx],
@@ -3130,7 +3203,11 @@ var ChatMachine = class {
3130
3203
  }
3131
3204
  this._clearStreamError();
3132
3205
  this._updateInput({ inputError: null });
3133
- await this._sendMessageDirect(lastAttempt.content, lastAttempt.attachments, lastAttempt.options);
3206
+ await this._sendMessageDirect(
3207
+ lastAttempt.content,
3208
+ lastAttempt.attachments,
3209
+ lastAttempt.options
3210
+ );
3134
3211
  }
3135
3212
  // ── Regenerate / Edit ───────────────────────────────────────────────────
3136
3213
  async _handleRegenerate(turnId) {
@@ -3143,9 +3220,13 @@ var ChatMachine = class {
3143
3220
  return;
3144
3221
  }
3145
3222
  this._updateSession({ error: null, errorRetryable: false });
3146
- await this._sendMessageDirect(turn.userTurn.content, turn.userTurn.attachments, {
3147
- replaceFromMessageID: turn.userTurn.id
3148
- });
3223
+ await this._sendMessageDirect(
3224
+ turn.userTurn.content,
3225
+ turn.userTurn.attachments,
3226
+ {
3227
+ replaceFromMessageID: turn.userTurn.id
3228
+ }
3229
+ );
3149
3230
  }
3150
3231
  async _handleEdit(turnId, newContent) {
3151
3232
  const curSessionId = this.state.session.currentSessionId;
@@ -3158,7 +3239,10 @@ var ChatMachine = class {
3158
3239
  }
3159
3240
  const turn = this.state.messaging.turns.find((t) => t.id === turnId);
3160
3241
  if (!turn) {
3161
- this._updateSession({ error: "Failed to edit message", errorRetryable: false });
3242
+ this._updateSession({
3243
+ error: "Failed to edit message",
3244
+ errorRetryable: false
3245
+ });
3162
3246
  return;
3163
3247
  }
3164
3248
  this._updateSession({ error: null, errorRetryable: false });
@@ -3196,8 +3280,17 @@ var ChatMachine = class {
3196
3280
  }
3197
3281
  if (result.success) {
3198
3282
  this._updateMessaging({
3199
- pendingQuestion: null,
3200
- 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
+ )
3201
3294
  });
3202
3295
  if (result.data) {
3203
3296
  await this._resumeAcceptedRunOrPoll(curSessionId, result.data.runId);
@@ -3208,9 +3301,15 @@ var ChatMachine = class {
3208
3301
  }
3209
3302
  if (fetchResult) {
3210
3303
  this._updateSession({ session: fetchResult.session });
3211
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3304
+ this._setTurnsFromFetch(
3305
+ fetchResult.turns,
3306
+ fetchResult.pendingQuestion || null
3307
+ );
3212
3308
  } else {
3213
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3309
+ this._updateSession({
3310
+ error: "Failed to load updated session",
3311
+ errorRetryable: true
3312
+ });
3214
3313
  }
3215
3314
  }
3216
3315
  } else if (curSessionId !== "new") {
@@ -3220,20 +3319,32 @@ var ChatMachine = class {
3220
3319
  }
3221
3320
  if (fetchResult) {
3222
3321
  this._updateSession({ session: fetchResult.session });
3223
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3322
+ this._setTurnsFromFetch(
3323
+ fetchResult.turns,
3324
+ fetchResult.pendingQuestion || null
3325
+ );
3224
3326
  } else {
3225
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3327
+ this._updateSession({
3328
+ error: "Failed to load updated session",
3329
+ errorRetryable: true
3330
+ });
3226
3331
  }
3227
3332
  }
3228
3333
  } else {
3229
- 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
+ });
3230
3338
  }
3231
3339
  } catch (err) {
3232
3340
  if (this.disposed) {
3233
3341
  return;
3234
3342
  }
3235
3343
  const normalized = normalizeRPCError(err, "Failed to submit answers");
3236
- this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3344
+ this._updateSession({
3345
+ error: normalized.userMessage,
3346
+ errorRetryable: normalized.retryable
3347
+ });
3237
3348
  } finally {
3238
3349
  if (!this.disposed) {
3239
3350
  this._updateMessaging({ loading: false });
@@ -3252,12 +3363,37 @@ var ChatMachine = class {
3252
3363
  return;
3253
3364
  }
3254
3365
  if (result.success) {
3366
+ const submittedQuestion = {
3367
+ ...curPendingQuestion,
3368
+ status: "REJECT_SUBMITTED"
3369
+ };
3255
3370
  this._updateMessaging({
3256
- pendingQuestion: null,
3257
- turns: applyTurnLifecycleForPendingQuestion(this.state.messaging.turns, null)
3371
+ pendingQuestion: submittedQuestion,
3372
+ turns: applyTurnLifecycleForPendingQuestion(
3373
+ this.state.messaging.turns,
3374
+ submittedQuestion
3375
+ )
3258
3376
  });
3259
3377
  if (result.data) {
3260
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
+ }
3261
3397
  } else if (curSessionId !== "new") {
3262
3398
  const fetchResult = await this.dataSource.fetchSession(curSessionId);
3263
3399
  if (this.disposed) {
@@ -3265,18 +3401,27 @@ var ChatMachine = class {
3265
3401
  }
3266
3402
  if (fetchResult) {
3267
3403
  this._updateSession({ session: fetchResult.session });
3268
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3404
+ this._setTurnsFromFetch(
3405
+ fetchResult.turns,
3406
+ fetchResult.pendingQuestion || null
3407
+ );
3269
3408
  }
3270
3409
  }
3271
3410
  } else {
3272
- 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
+ });
3273
3415
  }
3274
3416
  } catch (err) {
3275
3417
  if (this.disposed) {
3276
3418
  return;
3277
3419
  }
3278
3420
  const normalized = normalizeRPCError(err, "Failed to reject question");
3279
- this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3421
+ this._updateSession({
3422
+ error: normalized.userMessage,
3423
+ errorRetryable: normalized.retryable
3424
+ });
3280
3425
  }
3281
3426
  }
3282
3427
  // ── Input / queue ───────────────────────────────────────────────────────
@@ -3323,7 +3468,10 @@ var ChatMachine = class {
3323
3468
  return false;
3324
3469
  }
3325
3470
  this._updateInput({
3326
- messageQueue: [...this.state.input.messageQueue, { content, attachments }]
3471
+ messageQueue: [
3472
+ ...this.state.input.messageQueue,
3473
+ { content, attachments }
3474
+ ]
3327
3475
  });
3328
3476
  return true;
3329
3477
  }
@@ -6842,7 +6990,9 @@ function DownloadCard({ artifact }) {
6842
6990
  );
6843
6991
  }
6844
6992
  init_useTranslation();
6845
- function InlineQuestionForm({ pendingQuestion }) {
6993
+ function InlineQuestionForm({
6994
+ pendingQuestion
6995
+ }) {
6846
6996
  const { handleSubmitQuestionAnswers, handleRejectPendingQuestion, loading } = useChatMessaging();
6847
6997
  const { t } = useTranslation();
6848
6998
  const [currentStep, setCurrentStep] = useState(0);
@@ -6853,6 +7003,7 @@ function InlineQuestionForm({ pendingQuestion }) {
6853
7003
  const isLastStep = currentStep === questions.length - 1;
6854
7004
  const isFirstStep = currentStep === 0;
6855
7005
  const totalSteps = questions.length;
7006
+ const isFailedRetry = pendingQuestion.status === "ANSWER_RESUME_FAILED" || pendingQuestion.status === "REJECT_RESUME_FAILED";
6856
7007
  const currentAnswer = answers[currentQuestion?.id];
6857
7008
  const currentOtherText = otherTexts[currentQuestion?.id] || "";
6858
7009
  const handleOptionChange = useCallback(
@@ -6981,7 +7132,13 @@ function InlineQuestionForm({ pendingQuestion }) {
6981
7132
  const canProceed = isCurrentAnswerValid();
6982
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: [
6983
7134
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-4 pt-4 pb-3", children: [
6984
- /* @__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
+ ) }),
6985
7142
  /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
6986
7143
  /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wide text-primary-600 dark:text-primary-400", children: t("BiChat.InlineQuestion.InputNeeded") }),
6987
7144
  totalSteps > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[11px] tabular-nums text-gray-400 dark:text-gray-500", children: [
@@ -7002,6 +7159,10 @@ function InlineQuestionForm({ pendingQuestion }) {
7002
7159
  }
7003
7160
  )
7004
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
+ ] }),
7005
7166
  totalSteps > 1 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 px-4 pb-3", children: questions.map((_, index) => {
7006
7167
  const isCompleted = index < currentStep;
7007
7168
  const isCurrent = index === currentStep;
@@ -7055,10 +7216,16 @@ function InlineQuestionForm({ pendingQuestion }) {
7055
7216
  className: "sr-only"
7056
7217
  }
7057
7218
  ),
7058
- /* @__PURE__ */ jsx("span", { className: [
7059
- "text-sm transition-colors duration-150",
7060
- isSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7061
- ].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
+ )
7062
7229
  ]
7063
7230
  },
7064
7231
  option.id
@@ -7095,10 +7262,16 @@ function InlineQuestionForm({ pendingQuestion }) {
7095
7262
  className: "sr-only"
7096
7263
  }
7097
7264
  ),
7098
- /* @__PURE__ */ jsx("span", { className: [
7099
- "text-sm transition-colors duration-150",
7100
- isOtherSelected ? "text-gray-900 dark:text-gray-100 font-medium" : "text-gray-700 dark:text-gray-300"
7101
- ].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
+ )
7102
7275
  ]
7103
7276
  }
7104
7277
  ),
@@ -7530,7 +7703,9 @@ function DebugPanel({ trace }) {
7530
7703
  // ui/src/bichat/components/AssistantMessage.tsx
7531
7704
  init_useTranslation();
7532
7705
  var MarkdownRenderer2 = lazy(
7533
- () => 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
+ }))
7534
7709
  );
7535
7710
  var COPY_FEEDBACK_MS2 = 2e3;
7536
7711
  var defaultClassNames2 = {
@@ -7588,7 +7763,9 @@ function AssistantMessage({
7588
7763
  const { t } = useTranslation();
7589
7764
  const [explanationExpanded, setExplanationExpanded] = useState(false);
7590
7765
  const [isCopied, setIsCopied] = useState(false);
7591
- const copyFeedbackTimeoutRef = useRef(null);
7766
+ const copyFeedbackTimeoutRef = useRef(
7767
+ null
7768
+ );
7592
7769
  const classes = mergeClassNames2(defaultClassNames2, classNameOverrides);
7593
7770
  const isSystemMessage = turn.role === "system";
7594
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;
@@ -7604,8 +7781,11 @@ function AssistantMessage({
7604
7781
  const hasContent = turn.content?.trim().length > 0;
7605
7782
  const hasExplanation = !!turn.explanation?.trim();
7606
7783
  const isAwaitingHumanInput = turn.lifecycle === "waiting_for_human_input";
7607
- 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);
7608
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");
7609
7789
  const hasCodeOutputs = !!turn.codeOutputs?.length;
7610
7790
  const hasChart = !!turn.charts?.length;
7611
7791
  const hasTables = !!turn.renderTables?.length;
@@ -7614,7 +7794,7 @@ function AssistantMessage({
7614
7794
  const hasAnyRenderedContent = hasContent || hasExplanation || hasCodeOutputs || hasChart || hasTables || hasArtifacts || hasDebug;
7615
7795
  const canRegenerate = !!onRegenerate && !!turnId && !isSystemMessage && isLastTurn;
7616
7796
  const showInlineRetry = shouldRenderInlineRetry(turn, canRegenerate) && !hasAnyRenderedContent;
7617
- const renderMode = hasPendingQuestion ? "hitl_form" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : showInlineRetry ? "retry" : "empty";
7797
+ const renderMode = showQuestionForm ? "hitl_form" : showResumeState ? "hitl_resuming" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : showInlineRetry ? "retry" : "empty";
7618
7798
  const handleCopyClick = useCallback(async () => {
7619
7799
  try {
7620
7800
  if (onCopy) {
@@ -7641,7 +7821,9 @@ function AssistantMessage({
7641
7821
  }
7642
7822
  }, [onRegenerate, turnId]);
7643
7823
  const timestamp = formatRelativeTime(turn.createdAt, t);
7644
- const avatarSlotProps = { text: isSystemMessage ? "SYS" : "AI" };
7824
+ const avatarSlotProps = {
7825
+ text: isSystemMessage ? "SYS" : "AI"
7826
+ };
7645
7827
  const contentSlotProps = {
7646
7828
  content: turn.content,
7647
7829
  citations: turn.citations,
@@ -7684,11 +7866,21 @@ function AssistantMessage({
7684
7866
  return slot;
7685
7867
  };
7686
7868
  return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
7687
- !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
+ ) }),
7688
7874
  /* @__PURE__ */ jsxs("div", { className: classes.wrapper, children: [
7689
- /* @__PURE__ */ jsx(AnimatePresence, { children: showInlineRetry && /* @__PURE__ */ jsx(RetryActionArea, { onRetry: () => {
7690
- void handleRegenerateClick();
7691
- } }, "inline-retry") }),
7875
+ /* @__PURE__ */ jsx(AnimatePresence, { children: showInlineRetry && /* @__PURE__ */ jsx(
7876
+ RetryActionArea,
7877
+ {
7878
+ onRetry: () => {
7879
+ void handleRegenerateClick();
7880
+ }
7881
+ },
7882
+ "inline-retry"
7883
+ ) }),
7692
7884
  turn.codeOutputs && turn.codeOutputs.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.codeOutputs, children: renderSlot(
7693
7885
  slots?.codeOutputs,
7694
7886
  codeOutputsSlotProps,
@@ -7771,7 +7963,13 @@ function AssistantMessage({
7771
7963
  ]
7772
7964
  }
7773
7965
  ),
7774
- 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
+ ) })
7775
7973
  ] })
7776
7974
  ) }),
7777
7975
  showDebug && /* @__PURE__ */ jsx(DebugPanel, { trace: turn.debug })
@@ -7779,40 +7977,79 @@ function AssistantMessage({
7779
7977
  turn.artifacts && turn.artifacts.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.artifacts, children: renderSlot(
7780
7978
  slots?.artifacts,
7781
7979
  artifactsSlotProps,
7782
- 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
+ ))
7783
7987
  ) }),
7784
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: [
7785
7989
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-primary-700 dark:text-primary-300", children: t("BiChat.InlineQuestion.InputNeeded") }),
7786
7990
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: t("BiChat.InlineQuestion.WaitingForDetails") })
7787
7991
  ] }),
7992
+ renderMode === "hitl_resuming" && /* @__PURE__ */ jsxs(
7993
+ "div",
7994
+ {
7995
+ role: "status",
7996
+ "aria-live": "polite",
7997
+ className: "animate-slide-up flex items-center gap-2 rounded-xl border border-emerald-100/80 bg-emerald-50/60 px-3 py-2 text-xs text-emerald-800 dark:border-emerald-900/60 dark:bg-emerald-950/20 dark:text-emerald-200",
7998
+ children: [
7999
+ /* @__PURE__ */ jsx(
8000
+ "span",
8001
+ {
8002
+ className: "inline-flex h-2 w-2 flex-shrink-0 rounded-full bg-emerald-500 animate-pulse",
8003
+ "aria-hidden": "true"
8004
+ }
8005
+ ),
8006
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: pendingQuestion?.status === "REJECT_SUBMITTED" ? t("BiChat.InlineQuestion.DismissalSubmitted") : t("BiChat.InlineQuestion.AnswerSubmitted") }),
8007
+ /* @__PURE__ */ jsx(
8008
+ "span",
8009
+ {
8010
+ className: "text-emerald-400/80 dark:text-emerald-500/80",
8011
+ "aria-hidden": "true",
8012
+ children: "\u2022"
8013
+ }
8014
+ ),
8015
+ /* @__PURE__ */ jsx("span", { className: "text-emerald-700/80 dark:text-emerald-300/80", children: t("BiChat.InlineQuestion.ResumeInProgress") })
8016
+ ]
8017
+ }
8018
+ ),
7788
8019
  renderMode === "hitl_form" && pendingQuestion && /* @__PURE__ */ jsx(InlineQuestionForm, { pendingQuestion }),
7789
- hasContent && !hideActions && /* @__PURE__ */ jsx("div", { className: `${classes.actions} ${isCopied ? "opacity-100" : ""}`, children: renderSlot(
7790
- slots?.actions,
7791
- actionsSlotProps,
7792
- /* @__PURE__ */ jsxs(Fragment, { children: [
7793
- !hideTimestamp && /* @__PURE__ */ jsx("span", { className: classes.timestamp, children: timestamp }),
7794
- /* @__PURE__ */ jsx(
7795
- "button",
7796
- {
7797
- onClick: handleCopyClick,
7798
- className: `cursor-pointer ${classes.actionButton} ${isCopied ? "text-green-600 dark:text-green-400" : ""}`,
7799
- "aria-label": t("BiChat.Message.CopyMessage"),
7800
- title: isCopied ? t("BiChat.Message.Copied") : t("BiChat.Message.Copy"),
7801
- children: isCopied ? /* @__PURE__ */ jsx(Check, { size: 14, weight: "bold" }) : /* @__PURE__ */ jsx(Copy, { size: 14, weight: "regular" })
7802
- }
7803
- ),
7804
- canRegenerate && /* @__PURE__ */ jsx(
7805
- "button",
7806
- {
7807
- onClick: handleRegenerateClick,
7808
- className: `cursor-pointer ${classes.actionButton}`,
7809
- "aria-label": t("BiChat.Message.Regenerate"),
7810
- title: t("BiChat.Message.Regenerate"),
7811
- children: /* @__PURE__ */ jsx(ArrowsClockwise, { size: 14, weight: "regular" })
7812
- }
8020
+ hasContent && !hideActions && /* @__PURE__ */ jsx(
8021
+ "div",
8022
+ {
8023
+ className: `${classes.actions} ${isCopied ? "opacity-100" : ""}`,
8024
+ children: renderSlot(
8025
+ slots?.actions,
8026
+ actionsSlotProps,
8027
+ /* @__PURE__ */ jsxs(Fragment, { children: [
8028
+ !hideTimestamp && /* @__PURE__ */ jsx("span", { className: classes.timestamp, children: timestamp }),
8029
+ /* @__PURE__ */ jsx(
8030
+ "button",
8031
+ {
8032
+ onClick: handleCopyClick,
8033
+ className: `cursor-pointer ${classes.actionButton} ${isCopied ? "text-green-600 dark:text-green-400" : ""}`,
8034
+ "aria-label": t("BiChat.Message.CopyMessage"),
8035
+ title: isCopied ? t("BiChat.Message.Copied") : t("BiChat.Message.Copy"),
8036
+ children: isCopied ? /* @__PURE__ */ jsx(Check, { size: 14, weight: "bold" }) : /* @__PURE__ */ jsx(Copy, { size: 14, weight: "regular" })
8037
+ }
8038
+ ),
8039
+ canRegenerate && /* @__PURE__ */ jsx(
8040
+ "button",
8041
+ {
8042
+ onClick: handleRegenerateClick,
8043
+ className: `cursor-pointer ${classes.actionButton}`,
8044
+ "aria-label": t("BiChat.Message.Regenerate"),
8045
+ title: t("BiChat.Message.Regenerate"),
8046
+ children: /* @__PURE__ */ jsx(ArrowsClockwise, { size: 14, weight: "regular" })
8047
+ }
8048
+ )
8049
+ ] })
7813
8050
  )
7814
- ] })
7815
- ) })
8051
+ }
8052
+ )
7816
8053
  ] })
7817
8054
  ] });
7818
8055
  }
@@ -9156,22 +9393,52 @@ function ReasoningEffortSelector({ options, value, onChange, disabled }) {
9156
9393
  const { t } = useTranslation();
9157
9394
  const selected = value || options[1] || options[0];
9158
9395
  const label = t("BiChat.Input.ReasoningEffort");
9159
- return /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 self-center flex items-center gap-1.5", children: [
9160
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-gray-400 dark:text-gray-500 font-medium whitespace-nowrap select-none", children: label }),
9161
- /* @__PURE__ */ jsx(
9162
- "select",
9396
+ const selectedLabel = t(EFFORT_LABEL_KEYS[selected] ?? selected);
9397
+ return /* @__PURE__ */ jsxs(Menu, { as: "div", className: "relative flex-shrink-0 self-center", children: [
9398
+ /* @__PURE__ */ jsxs(
9399
+ MenuButton,
9163
9400
  {
9164
- value: selected,
9165
9401
  disabled,
9166
- onChange: (event) => onChange(event.target.value),
9167
9402
  className: [
9168
- "cursor-pointer h-8 rounded-lg border border-gray-200 dark:border-gray-600",
9169
- "bg-gray-50 dark:bg-gray-700/50 px-2.5 text-[11px] font-medium leading-none",
9170
- "text-gray-700 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-primary-500/25",
9171
- "disabled:opacity-40 disabled:cursor-not-allowed"
9403
+ "cursor-pointer inline-flex h-8 items-center gap-1.5 rounded-xl border border-gray-200/80 dark:border-gray-600/70",
9404
+ "bg-white dark:bg-gray-800 px-2.5 text-[11px] font-medium leading-none text-gray-700 dark:text-gray-200",
9405
+ "shadow-sm transition-colors hover:border-gray-300 hover:bg-white dark:hover:border-gray-500 dark:hover:bg-gray-800",
9406
+ "focus:outline-none focus:ring-2 focus:ring-primary-500/20",
9407
+ "disabled:cursor-not-allowed disabled:opacity-40"
9172
9408
  ].join(" "),
9173
9409
  "aria-label": label,
9174
- children: options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: t(EFFORT_LABEL_KEYS[opt] ?? opt) }, opt))
9410
+ title: `${label}: ${selectedLabel}`,
9411
+ children: [
9412
+ /* @__PURE__ */ jsx(Brain, { size: 14, weight: "duotone", className: "text-primary-600 dark:text-primary-400" }),
9413
+ /* @__PURE__ */ jsx("span", { className: "max-w-[72px] truncate", children: selectedLabel }),
9414
+ /* @__PURE__ */ jsx(CaretUpDown, { size: 12, className: "text-gray-400 dark:text-gray-500" })
9415
+ ]
9416
+ }
9417
+ ),
9418
+ /* @__PURE__ */ jsx(
9419
+ MenuItems,
9420
+ {
9421
+ anchor: "top end",
9422
+ className: "isolate z-30 min-w-[148px] rounded-xl border border-gray-200 bg-white p-1 shadow-xl ring-1 ring-black/5 dark:border-gray-700 dark:bg-gray-900 dark:ring-white/10 [--anchor-gap:8px]",
9423
+ children: options.map((opt) => {
9424
+ const optionLabel = t(EFFORT_LABEL_KEYS[opt] ?? opt);
9425
+ const isSelected = opt === selected;
9426
+ return /* @__PURE__ */ jsx(MenuItem, { children: ({ focus }) => /* @__PURE__ */ jsxs(
9427
+ "button",
9428
+ {
9429
+ type: "button",
9430
+ onClick: () => onChange(opt),
9431
+ className: [
9432
+ "flex w-full items-center gap-2 rounded-lg px-2.5 py-2 text-left text-[11px] font-medium transition-colors",
9433
+ focus ? "bg-primary-50 text-primary-700 dark:bg-primary-950/40 dark:text-primary-200" : "text-gray-700 dark:text-gray-200"
9434
+ ].join(" "),
9435
+ children: [
9436
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: optionLabel }),
9437
+ isSelected && /* @__PURE__ */ jsx(Check, { size: 12, weight: "bold", className: "text-primary-600 dark:text-primary-400" })
9438
+ ]
9439
+ }
9440
+ ) }, opt);
9441
+ })
9175
9442
  }
9176
9443
  )
9177
9444
  ] });
@@ -17133,7 +17400,7 @@ function useHttpDataSourceConfigFromApplet(options) {
17133
17400
  streamEndpoint,
17134
17401
  csrfToken,
17135
17402
  rpcTimeoutMs: options?.rpcTimeoutMs ?? 12e4,
17136
- streamConnectTimeoutMs: options?.streamConnectTimeoutMs ?? 3e4
17403
+ streamConnectTimeoutMs: options?.streamConnectTimeoutMs
17137
17404
  };
17138
17405
  }, [options?.rpcTimeoutMs, options?.streamConnectTimeoutMs]);
17139
17406
  }
@@ -17542,7 +17809,10 @@ function toSession(session) {
17542
17809
  function toSessionArtifact(artifact) {
17543
17810
  const rawCreatedAt = readNonEmptyString(artifact.createdAt);
17544
17811
  if (!rawCreatedAt) {
17545
- warnMalformedSessionPayload("Artifact missing createdAt; defaulting to epoch", { id: artifact.id });
17812
+ warnMalformedSessionPayload(
17813
+ "Artifact missing createdAt; defaulting to epoch",
17814
+ { id: artifact.id }
17815
+ );
17546
17816
  }
17547
17817
  const createdAt = rawCreatedAt ?? "1970-01-01T00:00:00.000Z";
17548
17818
  return {
@@ -17564,6 +17834,21 @@ function normalizeQuestionType2(rawType) {
17564
17834
  const normalized = readString2(rawType).trim().toUpperCase().replace(/[\s-]+/g, "_");
17565
17835
  return normalized === "MULTIPLE_CHOICE" ? "MULTIPLE_CHOICE" : "SINGLE_CHOICE";
17566
17836
  }
17837
+ function normalizePendingQuestionStatus(rawStatus) {
17838
+ const normalized = readString2(rawStatus).trim().toUpperCase();
17839
+ switch (normalized) {
17840
+ case "ANSWER_SUBMITTED":
17841
+ case "REJECT_SUBMITTED":
17842
+ case "ANSWER_RESUME_FAILED":
17843
+ case "REJECT_RESUME_FAILED":
17844
+ case "ANSWERED":
17845
+ case "REJECTED":
17846
+ case "CANCELLED":
17847
+ return normalized;
17848
+ default:
17849
+ return "PENDING";
17850
+ }
17851
+ }
17567
17852
  function normalizeMessageRole(rawRole) {
17568
17853
  const normalized = readString2(rawRole).trim().toLowerCase();
17569
17854
  if (normalized === "user" /* User */) {
@@ -17579,11 +17864,17 @@ function normalizeMessageRole(rawRole) {
17579
17864
  }
17580
17865
  function sanitizeAttachment(rawAttachment, turnId, index) {
17581
17866
  if (!isRecord2(rawAttachment)) {
17582
- warnMalformedSessionPayload("Dropped malformed attachment entry", { turnId, index });
17867
+ warnMalformedSessionPayload("Dropped malformed attachment entry", {
17868
+ turnId,
17869
+ index
17870
+ });
17583
17871
  return null;
17584
17872
  }
17585
17873
  const filename = readString2(rawAttachment.filename, "attachment");
17586
- const mimeType = readString2(rawAttachment.mimeType, "application/octet-stream");
17874
+ const mimeType = readString2(
17875
+ rawAttachment.mimeType,
17876
+ "application/octet-stream"
17877
+ );
17587
17878
  const id = readNonEmptyString(rawAttachment.id) || void 0;
17588
17879
  const clientKey = readNonEmptyString(rawAttachment.clientKey) || id || `${turnId}-attachment-${index}`;
17589
17880
  return {
@@ -17619,7 +17910,10 @@ function sanitizeAssistantArtifacts(rawArtifacts, turnId) {
17619
17910
  for (let i = 0; i < rawArtifacts.length; i++) {
17620
17911
  const raw = rawArtifacts[i];
17621
17912
  if (!isRecord2(raw)) {
17622
- warnMalformedSessionPayload("Dropped malformed assistant artifact", { turnId, index: i });
17913
+ warnMalformedSessionPayload("Dropped malformed assistant artifact", {
17914
+ turnId,
17915
+ index: i
17916
+ });
17623
17917
  continue;
17624
17918
  }
17625
17919
  const type = readString2(raw.type).toLowerCase();
@@ -17628,7 +17922,10 @@ function sanitizeAssistantArtifacts(rawArtifacts, turnId) {
17628
17922
  }
17629
17923
  const url = readNonEmptyString(raw.url);
17630
17924
  if (!url) {
17631
- warnMalformedSessionPayload("Dropped assistant artifact without url", { turnId, index: i });
17925
+ warnMalformedSessionPayload("Dropped assistant artifact without url", {
17926
+ turnId,
17927
+ index: i
17928
+ });
17632
17929
  continue;
17633
17930
  }
17634
17931
  artifacts.push({
@@ -17647,12 +17944,16 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17647
17944
  return void 0;
17648
17945
  }
17649
17946
  if (!isRecord2(rawAssistantTurn)) {
17650
- warnMalformedSessionPayload("Dropped malformed assistant turn payload", { turnId });
17947
+ warnMalformedSessionPayload("Dropped malformed assistant turn payload", {
17948
+ turnId
17949
+ });
17651
17950
  return void 0;
17652
17951
  }
17653
17952
  const assistantID = readNonEmptyString(rawAssistantTurn.id);
17654
17953
  if (!assistantID) {
17655
- warnMalformedSessionPayload("Dropped assistant turn without id", { turnId });
17954
+ warnMalformedSessionPayload("Dropped assistant turn without id", {
17955
+ turnId
17956
+ });
17656
17957
  return void 0;
17657
17958
  }
17658
17959
  const citations = Array.isArray(rawAssistantTurn.citations) ? rawAssistantTurn.citations.filter((item) => isRecord2(item)).map((item, index) => ({
@@ -17689,17 +17990,27 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17689
17990
  schemaVersion: readNonEmptyString(rawAssistantTurn.debug.schemaVersion) || void 0,
17690
17991
  startedAt: readNonEmptyString(rawAssistantTurn.debug.startedAt) || void 0,
17691
17992
  completedAt: readNonEmptyString(rawAssistantTurn.debug.completedAt) || void 0,
17692
- generationMs: readOptionalFiniteNumber(rawAssistantTurn.debug.generationMs),
17993
+ generationMs: readOptionalFiniteNumber(
17994
+ rawAssistantTurn.debug.generationMs
17995
+ ),
17693
17996
  traceId: readNonEmptyString(rawAssistantTurn.debug.traceId) || void 0,
17694
17997
  traceUrl: readNonEmptyString(rawAssistantTurn.debug.traceUrl) || void 0,
17695
17998
  sessionId: readNonEmptyString(rawAssistantTurn.debug.sessionId) || void 0,
17696
17999
  thinking: readNonEmptyString(rawAssistantTurn.debug.thinking) || void 0,
17697
18000
  observationReason: readNonEmptyString(rawAssistantTurn.debug.observationReason) || void 0,
17698
18001
  usage: isRecord2(rawAssistantTurn.debug.usage) ? {
17699
- promptTokens: readFiniteNumber(rawAssistantTurn.debug.usage.promptTokens),
17700
- completionTokens: readFiniteNumber(rawAssistantTurn.debug.usage.completionTokens),
17701
- totalTokens: readFiniteNumber(rawAssistantTurn.debug.usage.totalTokens),
17702
- cachedTokens: readOptionalFiniteNumber(rawAssistantTurn.debug.usage.cachedTokens),
18002
+ promptTokens: readFiniteNumber(
18003
+ rawAssistantTurn.debug.usage.promptTokens
18004
+ ),
18005
+ completionTokens: readFiniteNumber(
18006
+ rawAssistantTurn.debug.usage.completionTokens
18007
+ ),
18008
+ totalTokens: readFiniteNumber(
18009
+ rawAssistantTurn.debug.usage.totalTokens
18010
+ ),
18011
+ cachedTokens: readOptionalFiniteNumber(
18012
+ rawAssistantTurn.debug.usage.cachedTokens
18013
+ ),
17703
18014
  cost: readOptionalFiniteNumber(rawAssistantTurn.debug.usage.cost)
17704
18015
  } : void 0,
17705
18016
  tools: Array.isArray(rawAssistantTurn.debug.tools) ? rawAssistantTurn.debug.tools.filter((tool) => isRecord2(tool)).map((tool) => ({
@@ -17717,7 +18028,9 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17717
18028
  provider: readNonEmptyString(attempt.provider) || void 0,
17718
18029
  finishReason: readNonEmptyString(attempt.finishReason) || void 0,
17719
18030
  promptTokens: readOptionalFiniteNumber(attempt.promptTokens),
17720
- completionTokens: readOptionalFiniteNumber(attempt.completionTokens),
18031
+ completionTokens: readOptionalFiniteNumber(
18032
+ attempt.completionTokens
18033
+ ),
17721
18034
  totalTokens: readOptionalFiniteNumber(attempt.totalTokens),
17722
18035
  cachedTokens: readOptionalFiniteNumber(attempt.cachedTokens),
17723
18036
  cost: readOptionalFiniteNumber(attempt.cost),
@@ -17786,16 +18099,25 @@ function sanitizeAssistantTurn(rawAssistantTurn, fallbackCreatedAt, turnId) {
17786
18099
  }
17787
18100
  function sanitizeConversationTurn(rawTurn, index, fallbackSessionID) {
17788
18101
  if (!isRecord2(rawTurn)) {
17789
- warnMalformedSessionPayload("Dropped malformed turn payload (not an object)", { index });
18102
+ warnMalformedSessionPayload(
18103
+ "Dropped malformed turn payload (not an object)",
18104
+ { index }
18105
+ );
17790
18106
  return null;
17791
18107
  }
17792
18108
  if (!isRecord2(rawTurn.userTurn)) {
17793
- warnMalformedSessionPayload("Dropped malformed turn payload (missing user turn)", { index });
18109
+ warnMalformedSessionPayload(
18110
+ "Dropped malformed turn payload (missing user turn)",
18111
+ { index }
18112
+ );
17794
18113
  return null;
17795
18114
  }
17796
18115
  const userTurnID = readNonEmptyString(rawTurn.userTurn.id);
17797
18116
  if (!userTurnID) {
17798
- warnMalformedSessionPayload("Dropped malformed turn payload (missing user turn id)", { index });
18117
+ warnMalformedSessionPayload(
18118
+ "Dropped malformed turn payload (missing user turn id)",
18119
+ { index }
18120
+ );
17799
18121
  return null;
17800
18122
  }
17801
18123
  const turnID = readString2(rawTurn.id, userTurnID);
@@ -17809,17 +18131,27 @@ function sanitizeConversationTurn(rawTurn, index, fallbackSessionID) {
17809
18131
  userTurn: {
17810
18132
  id: userTurnID,
17811
18133
  content: readString2(rawTurn.userTurn.content),
17812
- attachments: sanitizeUserAttachments(rawTurn.userTurn.attachments, turnID),
18134
+ attachments: sanitizeUserAttachments(
18135
+ rawTurn.userTurn.attachments,
18136
+ turnID
18137
+ ),
17813
18138
  author: mapSessionUser(rawTurn.userTurn.author),
17814
18139
  createdAt: readString2(rawTurn.userTurn.createdAt, createdAt)
17815
18140
  },
17816
- assistantTurn: sanitizeAssistantTurn(rawTurn.assistantTurn, createdAt, turnID),
18141
+ assistantTurn: sanitizeAssistantTurn(
18142
+ rawTurn.assistantTurn,
18143
+ createdAt,
18144
+ turnID
18145
+ ),
17817
18146
  createdAt
17818
18147
  };
17819
18148
  }
17820
18149
  function sanitizeConversationTurns(rawTurns, sessionID) {
17821
18150
  if (!Array.isArray(rawTurns)) {
17822
- warnMalformedSessionPayload("Session payload contained non-array turns field", { sessionID });
18151
+ warnMalformedSessionPayload(
18152
+ "Session payload contained non-array turns field",
18153
+ { sessionID }
18154
+ );
17823
18155
  return [];
17824
18156
  }
17825
18157
  const turns = [];
@@ -17833,11 +18165,14 @@ function sanitizeConversationTurns(rawTurns, sessionID) {
17833
18165
  }
17834
18166
  }
17835
18167
  if (dropped > 0) {
17836
- warnMalformedSessionPayload("Dropped malformed turns from session payload", {
17837
- sessionID,
17838
- dropped,
17839
- total: rawTurns.length
17840
- });
18168
+ warnMalformedSessionPayload(
18169
+ "Dropped malformed turns from session payload",
18170
+ {
18171
+ sessionID,
18172
+ dropped,
18173
+ total: rawTurns.length
18174
+ }
18175
+ );
17841
18176
  }
17842
18177
  return turns;
17843
18178
  }
@@ -17847,39 +18182,57 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
17847
18182
  }
17848
18183
  const checkpointID = readNonEmptyString(rawPendingQuestion.checkpointId);
17849
18184
  if (!checkpointID) {
17850
- warnMalformedSessionPayload("Dropped malformed pendingQuestion without checkpointId", { sessionID });
18185
+ warnMalformedSessionPayload(
18186
+ "Dropped malformed pendingQuestion without checkpointId",
18187
+ { sessionID }
18188
+ );
17851
18189
  return null;
17852
18190
  }
17853
18191
  if (!Array.isArray(rawPendingQuestion.questions)) {
17854
- warnMalformedSessionPayload("Pending question had non-array questions payload", {
17855
- sessionID,
17856
- checkpointID
17857
- });
18192
+ warnMalformedSessionPayload(
18193
+ "Pending question had non-array questions payload",
18194
+ {
18195
+ sessionID,
18196
+ checkpointID
18197
+ }
18198
+ );
17858
18199
  }
17859
18200
  const questions = Array.isArray(rawPendingQuestion.questions) ? rawPendingQuestion.questions.filter((question) => {
17860
18201
  if (!question || !isRecord2(question)) {
17861
- warnMalformedSessionPayload("Dropped malformed question from pendingQuestion", {
17862
- sessionID,
17863
- checkpointID
17864
- });
18202
+ warnMalformedSessionPayload(
18203
+ "Dropped malformed question from pendingQuestion",
18204
+ {
18205
+ sessionID,
18206
+ checkpointID
18207
+ }
18208
+ );
17865
18209
  return false;
17866
18210
  }
17867
18211
  return true;
17868
18212
  }).map((question, index) => {
17869
- const questionID = readString2(question.id, `${checkpointID}-q-${index}`);
18213
+ const questionID = readString2(
18214
+ question.id,
18215
+ `${checkpointID}-q-${index}`
18216
+ );
17870
18217
  const options = Array.isArray(question.options) ? question.options.filter((option) => {
17871
18218
  if (!option || !isRecord2(option)) {
17872
- warnMalformedSessionPayload("Dropped malformed pendingQuestion option", {
17873
- sessionID,
17874
- checkpointID,
17875
- questionID
17876
- });
18219
+ warnMalformedSessionPayload(
18220
+ "Dropped malformed pendingQuestion option",
18221
+ {
18222
+ sessionID,
18223
+ checkpointID,
18224
+ questionID
18225
+ }
18226
+ );
17877
18227
  return false;
17878
18228
  }
17879
18229
  return true;
17880
18230
  }).map((option, optionIndex) => {
17881
18231
  const label = readString2(option.label);
17882
- const id = readString2(option.id, `${questionID}-opt-${optionIndex}`);
18232
+ const id = readString2(
18233
+ option.id,
18234
+ `${questionID}-opt-${optionIndex}`
18235
+ );
17883
18236
  return {
17884
18237
  id,
17885
18238
  label,
@@ -17898,7 +18251,7 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
17898
18251
  turnId: readString2(rawPendingQuestion.turnId),
17899
18252
  agentName: readNonEmptyString(rawPendingQuestion.agentName) || void 0,
17900
18253
  questions,
17901
- status: "PENDING"
18254
+ status: normalizePendingQuestionStatus(rawPendingQuestion.status)
17902
18255
  };
17903
18256
  }
17904
18257
  function formatSizeReadable(bytes) {
@@ -18107,7 +18460,9 @@ function attachArtifactsToTurns(turns, artifacts) {
18107
18460
  if (artifacts.length === 0) {
18108
18461
  return turns;
18109
18462
  }
18110
- 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));
18463
+ const downloadArtifacts = artifacts.map((raw) => ({ raw, mapped: toDownloadArtifact(raw) })).filter(
18464
+ (entry) => entry.mapped !== null
18465
+ ).sort((a, b) => toMillis(a.raw.createdAt) - toMillis(b.raw.createdAt));
18111
18466
  const chartArtifacts = artifacts.filter((a) => a.type === "chart").sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
18112
18467
  const tableArtifacts = artifacts.filter((a) => a.type === "table").sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
18113
18468
  if (downloadArtifacts.length === 0 && chartArtifacts.length === 0 && tableArtifacts.length === 0) {
@@ -18196,14 +18551,19 @@ function attachArtifactsToTurns(turns, artifacts) {
18196
18551
  continue;
18197
18552
  }
18198
18553
  if (assistantTurn.renderTables === void 0) {
18199
- assistantTurn.renderTables = extractRenderTablesFromToolCalls(assistantTurn.toolCalls);
18554
+ assistantTurn.renderTables = extractRenderTablesFromToolCalls(
18555
+ assistantTurn.toolCalls
18556
+ );
18200
18557
  }
18201
18558
  const existing = assistantTurn.renderTables;
18202
18559
  const metadata = raw.metadata;
18203
18560
  if (!metadata || typeof metadata !== "object" || metadata === null) {
18204
18561
  continue;
18205
18562
  }
18206
- const tableData = parseRenderTableDataFromMetadata(metadata, raw.id);
18563
+ const tableData = parseRenderTableDataFromMetadata(
18564
+ metadata,
18565
+ raw.id
18566
+ );
18207
18567
  if (!tableData) {
18208
18568
  continue;
18209
18569
  }
@@ -19068,7 +19428,7 @@ var HttpDataSource = class {
19068
19428
  uploadEndpoint: "/api/uploads",
19069
19429
  ...config,
19070
19430
  rpcTimeoutMs: typeof config.rpcTimeoutMs === "number" ? config.rpcTimeoutMs : 12e4,
19071
- streamConnectTimeoutMs: typeof config.streamConnectTimeoutMs === "number" ? config.streamConnectTimeoutMs : 3e4
19431
+ streamConnectTimeoutMs: typeof config.streamConnectTimeoutMs === "number" ? config.streamConnectTimeoutMs : void 0
19072
19432
  };
19073
19433
  this.rpc = createAppletRPCClient({
19074
19434
  endpoint: `${this.config.baseUrl}${this.config.rpcEndpoint}`,