@iota-uz/sdk 0.4.21 → 0.4.23

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.
@@ -1649,28 +1649,6 @@ function loadDebugMode(sessionId) {
1649
1649
  }
1650
1650
  }
1651
1651
 
1652
- // ui/src/bichat/utils/reasoningEffortStorage.ts
1653
- var STORAGE_KEY = "bichat.reasoningEffort";
1654
- function saveReasoningEffort(effort) {
1655
- if (typeof window === "undefined") {
1656
- return;
1657
- }
1658
- try {
1659
- window.sessionStorage.setItem(STORAGE_KEY, effort);
1660
- } catch {
1661
- }
1662
- }
1663
- function loadReasoningEffort() {
1664
- if (typeof window === "undefined") {
1665
- return null;
1666
- }
1667
- try {
1668
- return window.sessionStorage.getItem(STORAGE_KEY);
1669
- } catch {
1670
- return null;
1671
- }
1672
- }
1673
-
1674
1652
  // ui/src/bichat/utils/debugTrace.ts
1675
1653
  function hasMeaningfulUsage(trace) {
1676
1654
  if (!trace) {
@@ -1813,16 +1791,6 @@ function readDebugLimitsFromGlobalContext() {
1813
1791
  completionReserveTokens
1814
1792
  };
1815
1793
  }
1816
- function readReasoningEffortOptionsFromGlobalContext() {
1817
- if (typeof window === "undefined") {
1818
- return void 0;
1819
- }
1820
- const opts = window.__APPLET_CONTEXT__?.extensions?.llm?.reasoningEffortOptions;
1821
- if (!Array.isArray(opts) || opts.length === 0) {
1822
- return void 0;
1823
- }
1824
- return opts.filter((o) => typeof o === "string");
1825
- }
1826
1794
 
1827
1795
  // ui/src/bichat/machine/selectors.ts
1828
1796
  function deriveDebugMode(state) {
@@ -1839,10 +1807,8 @@ function deriveSessionSnapshot(state, methods) {
1839
1807
  debugMode: deriveDebugMode(state),
1840
1808
  sessionDebugUsage: getSessionDebugUsage(state.messaging.turns),
1841
1809
  debugLimits: state.session.debugLimits,
1842
- reasoningEffort: state.session.reasoningEffort,
1843
1810
  setError: methods.setError,
1844
- retryFetchSession: methods.retryFetchSession,
1845
- setReasoningEffort: methods.setReasoningEffort
1811
+ retryFetchSession: methods.retryFetchSession
1846
1812
  };
1847
1813
  }
1848
1814
  function deriveMessagingSnapshot(state, methods) {
@@ -1914,7 +1880,7 @@ function pendingQuestionFromInterrupt(interrupt, fallbackTurnId) {
1914
1880
  options: Array.isArray(question.options) ? question.options.filter((option) => !!option && typeof option.id === "string").map((option) => ({
1915
1881
  id: option.id,
1916
1882
  label: typeof option.label === "string" ? option.label : "",
1917
- value: typeof option.label === "string" ? option.label : ""
1883
+ value: option.id
1918
1884
  })) : []
1919
1885
  })) : [];
1920
1886
  return {
@@ -2063,8 +2029,7 @@ var ChatMachine = class {
2063
2029
  if (this.lastSessionSnapshotVersion !== this.sessionSnapshotVersion) {
2064
2030
  this.cachedSessionSnapshot = deriveSessionSnapshot(this.state, {
2065
2031
  setError: this.setError,
2066
- retryFetchSession: this.retryFetchSession,
2067
- setReasoningEffort: this.setReasoningEffort
2032
+ retryFetchSession: this.retryFetchSession
2068
2033
  });
2069
2034
  this.lastSessionSnapshotVersion = this.sessionSnapshotVersion;
2070
2035
  }
@@ -2126,8 +2091,7 @@ var ChatMachine = class {
2126
2091
  error: null,
2127
2092
  errorRetryable: false,
2128
2093
  debugModeBySession: {},
2129
- debugLimits: readDebugLimitsFromGlobalContext(),
2130
- reasoningEffort: loadReasoningEffort() || void 0
2094
+ debugLimits: readDebugLimitsFromGlobalContext()
2131
2095
  },
2132
2096
  messaging: {
2133
2097
  turns: [],
@@ -2169,7 +2133,6 @@ var ChatMachine = class {
2169
2133
  this.enqueueMessage = this._enqueueMessage.bind(this);
2170
2134
  this.removeQueueItem = this._removeQueueItem.bind(this);
2171
2135
  this.updateQueueItem = this._updateQueueItem.bind(this);
2172
- this.setReasoningEffort = this._setReasoningEffort.bind(this);
2173
2136
  }
2174
2137
  // =====================================================================
2175
2138
  // Lifecycle
@@ -2290,10 +2253,6 @@ var ChatMachine = class {
2290
2253
  }
2291
2254
  });
2292
2255
  }
2293
- _setReasoningEffort(effort) {
2294
- this._updateSession({ reasoningEffort: effort });
2295
- saveReasoningEffort(effort);
2296
- }
2297
2256
  // =====================================================================
2298
2257
  // Private — session fetch
2299
2258
  // =====================================================================
@@ -2686,7 +2645,6 @@ var ChatMachine = class {
2686
2645
  attachments,
2687
2646
  debugMode,
2688
2647
  replaceFromMessageID,
2689
- reasoningEffort,
2690
2648
  tempTurnId
2691
2649
  } = params;
2692
2650
  let accumulatedContent = "";
@@ -2701,8 +2659,7 @@ var ChatMachine = class {
2701
2659
  this.abortController?.signal,
2702
2660
  {
2703
2661
  debugMode,
2704
- replaceFromMessageID,
2705
- reasoningEffort
2662
+ replaceFromMessageID
2706
2663
  }
2707
2664
  )) {
2708
2665
  if (this.abortController?.signal.aborted) {
@@ -2901,7 +2858,6 @@ var ChatMachine = class {
2901
2858
  attachments,
2902
2859
  debugMode: curDebugMode,
2903
2860
  replaceFromMessageID,
2904
- reasoningEffort: this.state.session.reasoningEffort,
2905
2861
  tempTurnId: tempTurn.id
2906
2862
  });
2907
2863
  if (stopped) {
@@ -3068,14 +3024,9 @@ var ChatMachine = class {
3068
3024
  if (!curSessionId || !curPendingQuestion) {
3069
3025
  return;
3070
3026
  }
3071
- const previousTurns = this.state.messaging.turns;
3072
3027
  this._updateMessaging({ loading: true });
3073
3028
  this._updateSession({ error: null, errorRetryable: false });
3074
3029
  const previousPendingQuestion = curPendingQuestion;
3075
- this._updateMessaging({
3076
- pendingQuestion: null,
3077
- turns: applyTurnLifecycleForPendingQuestion(previousTurns, null)
3078
- });
3079
3030
  try {
3080
3031
  const result = await this.dataSource.submitQuestionAnswers(
3081
3032
  curSessionId,
@@ -3086,60 +3037,28 @@ var ChatMachine = class {
3086
3037
  return;
3087
3038
  }
3088
3039
  if (result.success) {
3089
- if (curSessionId !== "new") {
3090
- try {
3091
- const fetchResult = await this.dataSource.fetchSession(curSessionId);
3092
- if (this.disposed) {
3093
- return;
3094
- }
3095
- if (fetchResult) {
3096
- this._updateSession({ session: fetchResult.session });
3097
- const hasMalformedRefresh = previousTurns.length > 0 && Array.isArray(fetchResult.turns) && fetchResult.turns.length === 0;
3098
- if (hasMalformedRefresh) {
3099
- console.warn("[ChatMachine] Preserving previous turns due to empty post-HITL refetch payload", {
3100
- sessionId: curSessionId,
3101
- previousTurnCount: previousTurns.length
3102
- });
3103
- this._updateSession({
3104
- error: "Failed to fully refresh session. Showing last known messages.",
3105
- errorRetryable: true
3106
- });
3107
- this._updateMessaging({
3108
- pendingQuestion: fetchResult.pendingQuestion || null,
3109
- turns: applyTurnLifecycleForPendingQuestion(
3110
- previousTurns,
3111
- fetchResult.pendingQuestion || null
3112
- )
3113
- });
3114
- } else {
3115
- this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3116
- }
3117
- } else {
3118
- this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3119
- }
3120
- } catch (fetchErr) {
3121
- if (this.disposed) {
3122
- return;
3123
- }
3124
- const normalized = normalizeRPCError(fetchErr, "Failed to load updated session");
3125
- this._updateSession({ error: normalized.userMessage, errorRetryable: true });
3040
+ if (result.data) {
3041
+ this._updateSession({ session: result.data.session });
3042
+ this._setTurnsFromFetch(result.data.turns, result.data.pendingQuestion || null);
3043
+ } else if (curSessionId !== "new") {
3044
+ const fetchResult = await this.dataSource.fetchSession(curSessionId);
3045
+ if (this.disposed) {
3046
+ return;
3047
+ }
3048
+ if (fetchResult) {
3049
+ this._updateSession({ session: fetchResult.session });
3050
+ this._setTurnsFromFetch(fetchResult.turns, fetchResult.pendingQuestion || null);
3051
+ } else {
3052
+ this._updateSession({ error: "Failed to load updated session", errorRetryable: true });
3126
3053
  }
3127
3054
  }
3128
3055
  } else {
3129
- this._updateMessaging({
3130
- pendingQuestion: previousPendingQuestion,
3131
- turns: applyTurnLifecycleForPendingQuestion(previousTurns, previousPendingQuestion)
3132
- });
3133
3056
  this._updateSession({ error: result.error || "Failed to submit answers", errorRetryable: false });
3134
3057
  }
3135
3058
  } catch (err) {
3136
3059
  if (this.disposed) {
3137
3060
  return;
3138
3061
  }
3139
- this._updateMessaging({
3140
- pendingQuestion: previousPendingQuestion,
3141
- turns: applyTurnLifecycleForPendingQuestion(previousTurns, previousPendingQuestion)
3142
- });
3143
3062
  const normalized = normalizeRPCError(err, "Failed to submit answers");
3144
3063
  this._updateSession({ error: normalized.userMessage, errorRetryable: normalized.retryable });
3145
3064
  } finally {
@@ -6573,13 +6492,13 @@ function InlineQuestionForm({ pendingQuestion }) {
6573
6492
  const currentAnswer = answers[currentQuestion?.id];
6574
6493
  const currentOtherText = otherTexts[currentQuestion?.id] || "";
6575
6494
  const handleOptionChange = React.useCallback(
6576
- (optionLabel, checked) => {
6495
+ (optionID, checked) => {
6577
6496
  if (!currentQuestion) {
6578
6497
  return;
6579
6498
  }
6580
6499
  const questionId = currentQuestion.id;
6581
6500
  const existingAnswer = answers[questionId] || { options: [] };
6582
- const isOtherOption = optionLabel === "__other__";
6501
+ const isOtherOption = optionID === "__other__";
6583
6502
  const isMultiSelect2 = currentQuestion.type === "MULTIPLE_CHOICE";
6584
6503
  if (isOtherOption) {
6585
6504
  setAnswers({
@@ -6594,14 +6513,14 @@ function InlineQuestionForm({ pendingQuestion }) {
6594
6513
  let newOptions;
6595
6514
  if (isMultiSelect2) {
6596
6515
  if (!checked) {
6597
- newOptions = existingAnswer.options.filter((o) => o !== optionLabel);
6598
- } else if (existingAnswer.options.includes(optionLabel)) {
6516
+ newOptions = existingAnswer.options.filter((o) => o !== optionID);
6517
+ } else if (existingAnswer.options.includes(optionID)) {
6599
6518
  newOptions = existingAnswer.options;
6600
6519
  } else {
6601
- newOptions = [...existingAnswer.options, optionLabel];
6520
+ newOptions = [...existingAnswer.options, optionID];
6602
6521
  }
6603
6522
  } else {
6604
- newOptions = checked ? [optionLabel] : [];
6523
+ newOptions = checked ? [optionID] : [];
6605
6524
  }
6606
6525
  setAnswers({
6607
6526
  ...answers,
@@ -6692,7 +6611,7 @@ function InlineQuestionForm({ pendingQuestion }) {
6692
6611
  const options = (currentQuestion.options || []).filter((option) => Boolean(option && typeof option.label === "string")).map((option, index) => ({
6693
6612
  id: option.id || `${currentQuestion.id}-option-${index}`,
6694
6613
  label: option.label,
6695
- value: option.value || option.label
6614
+ value: option.value || option.id || `${currentQuestion.id}-option-${index}`
6696
6615
  }));
6697
6616
  const isOtherSelected = currentAnswer?.customText !== void 0;
6698
6617
  const canProceed = isCurrentAnswerValid();
@@ -6740,7 +6659,7 @@ function InlineQuestionForm({ pendingQuestion }) {
6740
6659
  ] }),
6741
6660
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 pb-2 space-y-1.5", children: [
6742
6661
  options.map((option) => {
6743
- const isSelected = currentAnswer?.options.includes(option.label) || false;
6662
+ const isSelected = currentAnswer?.options.includes(option.id) || false;
6744
6663
  return /* @__PURE__ */ jsxRuntime.jsxs(
6745
6664
  "label",
6746
6665
  {
@@ -6768,7 +6687,7 @@ function InlineQuestionForm({ pendingQuestion }) {
6768
6687
  name: `question-${currentQuestion.id}`,
6769
6688
  value: option.value,
6770
6689
  checked: isSelected,
6771
- onChange: (e) => handleOptionChange(option.label, e.target.checked),
6690
+ onChange: (e) => handleOptionChange(option.id, e.target.checked),
6772
6691
  className: "sr-only"
6773
6692
  }
6774
6693
  ),
@@ -6975,43 +6894,6 @@ function CopyPill({ text }) {
6975
6894
  }
6976
6895
  );
6977
6896
  }
6978
- function InlineCopyButton({ text }) {
6979
- const [copied, setCopied] = React.useState(false);
6980
- const timerRef = React.useRef(null);
6981
- React.useEffect(() => () => {
6982
- if (timerRef.current !== null) {
6983
- clearTimeout(timerRef.current);
6984
- }
6985
- }, []);
6986
- const handleCopy = async (e) => {
6987
- e.stopPropagation();
6988
- try {
6989
- await navigator.clipboard.writeText(text);
6990
- setCopied(true);
6991
- if (timerRef.current !== null) {
6992
- clearTimeout(timerRef.current);
6993
- }
6994
- timerRef.current = window.setTimeout(() => {
6995
- setCopied(false);
6996
- timerRef.current = null;
6997
- }, 2e3);
6998
- } catch (err) {
6999
- console.error("Copy failed:", err);
7000
- }
7001
- };
7002
- return /* @__PURE__ */ jsxRuntime.jsx(
7003
- "button",
7004
- {
7005
- onClick: handleCopy,
7006
- "aria-label": copied ? "Copied" : "Copy",
7007
- className: [
7008
- "flex-shrink-0 p-1 rounded transition-colors duration-150",
7009
- copied ? "text-emerald-500 dark:text-emerald-400" : "text-gray-300 dark:text-gray-600 hover:text-gray-500 dark:hover:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700/40"
7010
- ].join(" "),
7011
- children: copied ? /* @__PURE__ */ jsxRuntime.jsx(react.Check, { size: 11, weight: "bold" }) : /* @__PURE__ */ jsxRuntime.jsx(react.Copy, { size: 11 })
7012
- }
7013
- );
7014
- }
7015
6897
  function MetricChip({ icon, value, label }) {
7016
6898
  return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-gray-50 dark:bg-gray-800/40 text-[11px] tabular-nums", children: [
7017
6899
  icon,
@@ -7110,7 +6992,7 @@ function ToolCard({ tool }) {
7110
6992
  }
7111
6993
  );
7112
6994
  }
7113
- function DebugPanel({ trace }) {
6995
+ function DebugPanel({ trace, debugLimits = null }) {
7114
6996
  const hasData = !!trace && hasDebugTrace(trace);
7115
6997
  const traceID = trace?.traceId?.trim() || "";
7116
6998
  const traceURL = trace?.traceUrl?.trim() || "";
@@ -7129,6 +7011,22 @@ function DebugPanel({ trace }) {
7129
7011
  }
7130
7012
  })();
7131
7013
  const tokensPerSecond = calculateCompletionTokensPerSecond(trace?.usage, trace?.generationMs);
7014
+ const effectiveMaxTokens = debugLimits?.effectiveMaxTokens ?? 0;
7015
+ const promptTokens = trace?.usage?.promptTokens ?? 0;
7016
+ const contextUsagePercent = calculateContextUsagePercent(promptTokens, effectiveMaxTokens);
7017
+ const contextUsagePercentLabel = contextUsagePercent !== null ? contextUsagePercent.toFixed(1) : null;
7018
+ const formatCompactTokens = (value) => {
7019
+ if (!Number.isFinite(value) || value <= 0) {
7020
+ return "0 tokens";
7021
+ }
7022
+ return `${new Intl.NumberFormat("en-US", {
7023
+ notation: "compact",
7024
+ maximumFractionDigits: value >= 1e5 ? 0 : 1
7025
+ }).format(value)} tokens`;
7026
+ };
7027
+ const contextPercentValue = contextUsagePercent ?? 0;
7028
+ const contextUsageToneClass = contextPercentValue > 75 ? "bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400" : contextPercentValue > 50 ? "bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400" : "bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 dark:text-emerald-400";
7029
+ const contextUsageBarColor = contextPercentValue > 75 ? "#ef4444" : contextPercentValue > 50 ? "#f59e0b" : "#10b981";
7132
7030
  const metrics = [];
7133
7031
  if (hasData && trace) {
7134
7032
  if (trace.generationMs !== void 0) {
@@ -7181,36 +7079,34 @@ function DebugPanel({ trace }) {
7181
7079
  hasData && trace && /* @__PURE__ */ jsxRuntime.jsx(CopyPill, { text: JSON.stringify(trace, null, 2) })
7182
7080
  ] }),
7183
7081
  hasData && trace ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
7184
- (traceID || trace.sessionId) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-gray-200/60 dark:border-gray-700/40 bg-gray-50/50 dark:bg-gray-800/40 px-3 py-2 space-y-1.5", children: [
7185
- traceID && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
7186
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500 w-14", children: "Trace" }),
7187
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 min-w-0 font-mono text-[11px] text-gray-700 dark:text-gray-300 truncate", title: traceID, children: traceID }),
7188
- /* @__PURE__ */ jsxRuntime.jsx(InlineCopyButton, { text: traceID })
7189
- ] }),
7190
- trace.sessionId && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
7191
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500 w-14", children: "Session" }),
7192
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 min-w-0 font-mono text-[11px] text-gray-700 dark:text-gray-300 truncate", title: trace.sessionId, children: trace.sessionId }),
7193
- /* @__PURE__ */ jsxRuntime.jsx(InlineCopyButton, { text: trace.sessionId })
7082
+ (traceID || safeTraceURL) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-gray-200/60 dark:border-gray-700/40 bg-gray-50/50 dark:bg-gray-800/40 p-3 space-y-2", children: [
7083
+ traceID && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
7084
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
7085
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Trace ID" }),
7086
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-[11px] text-gray-800 dark:text-gray-200 break-all", children: traceID })
7087
+ ] }),
7088
+ /* @__PURE__ */ jsxRuntime.jsx(CopyPill, { text: traceID })
7194
7089
  ] }),
7195
- safeTraceURL && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 pt-0.5", children: [
7196
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 w-14" }),
7197
- /* @__PURE__ */ jsxRuntime.jsxs(
7198
- "a",
7199
- {
7200
- href: safeTraceURL,
7201
- target: "_blank",
7202
- rel: "noopener noreferrer",
7203
- "aria-label": "Open in Langfuse",
7204
- className: "inline-flex items-center gap-1.5 text-[11px] font-medium text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 transition-colors duration-150",
7205
- children: [
7206
- /* @__PURE__ */ jsxRuntime.jsx(react.ArrowSquareOut, { size: 11, weight: "bold" }),
7207
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Open in Langfuse" })
7208
- ]
7209
- }
7210
- )
7211
- ] })
7090
+ safeTraceURL && /* @__PURE__ */ jsxRuntime.jsxs(
7091
+ "a",
7092
+ {
7093
+ href: safeTraceURL,
7094
+ target: "_blank",
7095
+ rel: "noopener noreferrer",
7096
+ "aria-label": "View full trace in Langfuse (opens in new tab)",
7097
+ className: "inline-flex items-center gap-1.5 text-[11px] font-medium text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300",
7098
+ children: [
7099
+ /* @__PURE__ */ jsxRuntime.jsx(react.ArrowSquareOut, { size: 12, weight: "bold" }),
7100
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Open in Langfuse" })
7101
+ ]
7102
+ }
7103
+ )
7212
7104
  ] }),
7213
- (trace.thinking || trace.observationReason) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-gray-200/60 dark:border-gray-700/40 bg-gray-50/50 dark:bg-gray-800/40 p-3 space-y-2", children: [
7105
+ (trace.thinking || trace.observationReason || trace.sessionId) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-gray-200/60 dark:border-gray-700/40 bg-gray-50/50 dark:bg-gray-800/40 p-3 space-y-2", children: [
7106
+ trace.sessionId && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[10px] uppercase tracking-wider text-gray-500 dark:text-gray-400", children: [
7107
+ "Session: ",
7108
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono normal-case break-all", children: trace.sessionId })
7109
+ ] }),
7214
7110
  trace.observationReason && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[11px] text-amber-700 dark:text-amber-300", children: [
7215
7111
  "Observation: ",
7216
7112
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: trace.observationReason })
@@ -7250,6 +7146,30 @@ function DebugPanel({ trace }) {
7250
7146
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1.5 py-0.5 rounded-full bg-gray-100 dark:bg-gray-800 text-[10px] font-mono font-medium text-gray-500 dark:text-gray-400 tabular-nums", children: trace.tools.length })
7251
7147
  ] }),
7252
7148
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: trace.tools.map((tool, idx) => /* @__PURE__ */ jsxRuntime.jsx(ToolCard, { tool }, `${tool.callId || tool.name}-${idx}`)) })
7149
+ ] }),
7150
+ contextUsagePercentLabel !== null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-gray-200/60 dark:border-gray-700/40 bg-gray-50/50 dark:bg-gray-800/40 p-3 space-y-2", children: [
7151
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
7152
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Context usage" }),
7153
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-[10px] text-gray-500 dark:text-gray-400 tabular-nums", children: [
7154
+ formatCompactTokens(promptTokens),
7155
+ " / ",
7156
+ formatCompactTokens(effectiveMaxTokens)
7157
+ ] }),
7158
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `px-1.5 py-0.5 rounded-full text-[10px] font-semibold tabular-nums ${contextUsageToneClass}`, children: [
7159
+ contextUsagePercentLabel,
7160
+ "%"
7161
+ ] })
7162
+ ] }),
7163
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 rounded-full bg-gray-200/80 dark:bg-gray-700/50 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
7164
+ "div",
7165
+ {
7166
+ className: "h-full rounded-full transition-all duration-700 ease-out",
7167
+ style: {
7168
+ width: `${Math.min(contextPercentValue, 100)}%`,
7169
+ backgroundColor: contextUsageBarColor
7170
+ }
7171
+ }
7172
+ ) })
7253
7173
  ] })
7254
7174
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500 italic", children: "Debug info unavailable" })
7255
7175
  ] });
@@ -7311,7 +7231,8 @@ function AssistantMessage({
7311
7231
  hideAvatar = false,
7312
7232
  hideActions = false,
7313
7233
  hideTimestamp = false,
7314
- showDebug = false
7234
+ showDebug = false,
7235
+ debugLimits = null
7315
7236
  }) {
7316
7237
  const { t } = useTranslation();
7317
7238
  const [explanationExpanded, setExplanationExpanded] = React.useState(false);
@@ -7502,7 +7423,7 @@ function AssistantMessage({
7502
7423
  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 }) }) })
7503
7424
  ] })
7504
7425
  ) }),
7505
- showDebug && /* @__PURE__ */ jsxRuntime.jsx(DebugPanel, { trace: turn.debug })
7426
+ showDebug && /* @__PURE__ */ jsxRuntime.jsx(DebugPanel, { trace: turn.debug, debugLimits })
7506
7427
  ] }),
7507
7428
  turn.artifacts && turn.artifacts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.artifacts, children: renderSlot(
7508
7429
  slots?.artifacts,
@@ -7694,7 +7615,7 @@ function AssistantTurnView({
7694
7615
  hideTimestamp,
7695
7616
  allowRegenerate = true
7696
7617
  }) {
7697
- const { debugMode } = useChatSession();
7618
+ const { debugMode, debugLimits } = useChatSession();
7698
7619
  const { handleCopy, handleRegenerate, pendingQuestion, sendMessage: sendMessage2, loading } = useChatMessaging();
7699
7620
  const assistantTurn = turn.assistantTurn;
7700
7621
  if (!assistantTurn) {
@@ -7729,7 +7650,8 @@ function AssistantTurnView({
7729
7650
  hideAvatar,
7730
7651
  hideActions,
7731
7652
  hideTimestamp,
7732
- showDebug: debugMode
7653
+ showDebug: debugMode,
7654
+ debugLimits
7733
7655
  }
7734
7656
  );
7735
7657
  }
@@ -8869,36 +8791,6 @@ function DebugStatsPanel({ debugSessionUsage, debugLimits }) {
8869
8791
  ] })
8870
8792
  ] });
8871
8793
  }
8872
- var EFFORT_LABEL_KEYS = {
8873
- low: "BiChat.Input.ReasoningEffortLow",
8874
- medium: "BiChat.Input.ReasoningEffortMedium",
8875
- high: "BiChat.Input.ReasoningEffortHigh",
8876
- xhigh: "BiChat.Input.ReasoningEffortXHigh"
8877
- };
8878
- function ReasoningEffortSelector({ options, value, onChange, disabled }) {
8879
- const { t } = useTranslation();
8880
- const selected = value || options[1] || options[0];
8881
- const label = t("BiChat.Input.ReasoningEffort");
8882
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-shrink-0 self-center flex items-center gap-1.5", children: [
8883
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-gray-400 dark:text-gray-500 font-medium whitespace-nowrap select-none", children: label }),
8884
- /* @__PURE__ */ jsxRuntime.jsx(
8885
- "select",
8886
- {
8887
- value: selected,
8888
- disabled,
8889
- onChange: (event) => onChange(event.target.value),
8890
- className: [
8891
- "cursor-pointer h-8 rounded-lg border border-gray-200 dark:border-gray-600",
8892
- "bg-gray-50 dark:bg-gray-700/50 px-2.5 text-[11px] font-medium leading-none",
8893
- "text-gray-700 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-primary-500/25",
8894
- "disabled:opacity-40 disabled:cursor-not-allowed"
8895
- ].join(" "),
8896
- "aria-label": label,
8897
- children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, children: t(EFFORT_LABEL_KEYS[opt] ?? opt) }, opt))
8898
- }
8899
- )
8900
- ] });
8901
- }
8902
8794
  var MAX_FILES_DEFAULT = 10;
8903
8795
  var MAX_FILE_SIZE_DEFAULT = 20 * 1024 * 1024;
8904
8796
  var MAX_HEIGHT = 192;
@@ -8925,10 +8817,7 @@ var MessageInput = React.forwardRef(
8925
8817
  maxFiles = MAX_FILES_DEFAULT,
8926
8818
  maxFileSize = MAX_FILE_SIZE_DEFAULT,
8927
8819
  containerClassName,
8928
- formClassName,
8929
- reasoningEffortOptions,
8930
- reasoningEffort,
8931
- onReasoningEffortChange
8820
+ formClassName
8932
8821
  }, ref) => {
8933
8822
  const { t } = useTranslation();
8934
8823
  const [attachments, setAttachments] = React.useState([]);
@@ -9377,25 +9266,16 @@ var MessageInput = React.forwardRef(
9377
9266
  "aria-label": t("BiChat.Input.MessageInput")
9378
9267
  }
9379
9268
  ) }),
9380
- reasoningEffortOptions && reasoningEffortOptions.length > 0 && onReasoningEffortChange && /* @__PURE__ */ jsxRuntime.jsx(
9381
- ReasoningEffortSelector,
9382
- {
9383
- options: reasoningEffortOptions,
9384
- value: reasoningEffort,
9385
- onChange: onReasoningEffortChange,
9386
- disabled: disabled || loading
9387
- }
9388
- ),
9389
9269
  isStreaming && onCancelStreaming ? /* @__PURE__ */ jsxRuntime.jsx(
9390
9270
  "button",
9391
9271
  {
9392
9272
  type: "button",
9393
9273
  onClick: onCancelStreaming,
9394
9274
  disabled: disabled || fetching,
9395
- className: "cursor-pointer flex-shrink-0 self-center p-2 rounded-lg bg-gray-900 hover:bg-gray-800 active:bg-black active:scale-95 text-white shadow-sm transition-all dark:bg-gray-100 dark:hover:bg-gray-200 dark:active:bg-white dark:text-gray-900 disabled:opacity-40 disabled:cursor-not-allowed",
9275
+ className: "cursor-pointer flex-shrink-0 self-center p-2 rounded-lg bg-red-600 hover:bg-red-700 active:bg-red-800 active:scale-95 text-white shadow-sm transition-all disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-red-600",
9396
9276
  "aria-label": t("BiChat.Common.Cancel"),
9397
9277
  title: t("BiChat.Common.Cancel"),
9398
- children: /* @__PURE__ */ jsxRuntime.jsx(react.Stop, { size: 18, weight: "fill" })
9278
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.X, { size: 18, weight: "bold" })
9399
9279
  }
9400
9280
  ) : /* @__PURE__ */ jsxRuntime.jsx(
9401
9281
  "button",
@@ -10967,9 +10847,7 @@ function ChatSessionCore({
10967
10847
  debugLimits,
10968
10848
  currentSessionId,
10969
10849
  setError,
10970
- retryFetchSession,
10971
- reasoningEffort,
10972
- setReasoningEffort
10850
+ retryFetchSession
10973
10851
  } = useChatSession();
10974
10852
  const {
10975
10853
  turns,
@@ -10996,7 +10874,6 @@ function ChatSessionCore({
10996
10874
  const isArchived = session?.status === "archived";
10997
10875
  const effectiveReadOnly = Boolean(readOnly ?? isReadOnly) || isArchived;
10998
10876
  const [restoring, setRestoring] = React.useState(false);
10999
- const [reasoningEffortOptions] = React.useState(() => readReasoningEffortOptionsFromGlobalContext());
11000
10877
  const handleRestore = React.useCallback(async () => {
11001
10878
  if (!session?.id) {
11002
10879
  return;
@@ -11223,10 +11100,7 @@ function ChatSessionCore({
11223
11100
  onUpdateQueueItem: updateQueueItem,
11224
11101
  onCancelStreaming: cancel,
11225
11102
  containerClassName: "pt-6 px-6",
11226
- formClassName: "mx-auto",
11227
- reasoningEffortOptions,
11228
- reasoningEffort,
11229
- onReasoningEffortChange: setReasoningEffort
11103
+ formClassName: "mx-auto"
11230
11104
  }
11231
11105
  ),
11232
11106
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 pb-1 text-center text-xs text-gray-500 dark:text-gray-400", children: t("BiChat.Welcome.Disclaimer") })
@@ -11282,10 +11156,7 @@ function ChatSessionCore({
11282
11156
  onUnqueue: handleUnqueue,
11283
11157
  onRemoveQueueItem: removeQueueItem,
11284
11158
  onUpdateQueueItem: updateQueueItem,
11285
- onCancelStreaming: cancel,
11286
- reasoningEffortOptions,
11287
- reasoningEffort,
11288
- onReasoningEffortChange: setReasoningEffort
11159
+ onCancelStreaming: cancel
11289
11160
  }
11290
11161
  )
11291
11162
  ] }) }),
@@ -14965,12 +14836,12 @@ function QuestionStep({
14965
14836
  const data = selectedAnswers[question.id] || { };
14966
14837
  setOtherText(data.customText || "");
14967
14838
  }, [question.id]);
14968
- const handleOptionClick = (optionLabel) => {
14839
+ const handleOptionClick = (optionID) => {
14969
14840
  if (isMultiSelect) {
14970
- const newOptions = selectedOptions.includes(optionLabel) ? selectedOptions.filter((a) => a !== optionLabel) : [...selectedOptions, optionLabel];
14841
+ const newOptions = selectedOptions.includes(optionID) ? selectedOptions.filter((a) => a !== optionID) : [...selectedOptions, optionID];
14971
14842
  onAnswer({ options: newOptions, customText: otherText || void 0 });
14972
14843
  } else {
14973
- onAnswer({ options: [optionLabel], customText: otherText || void 0 });
14844
+ onAnswer({ options: [optionID], customText: otherText || void 0 });
14974
14845
  }
14975
14846
  };
14976
14847
  const handleOtherTextChange = (text) => {
@@ -14984,11 +14855,11 @@ function QuestionStep({
14984
14855
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-2", children: question.text }) }),
14985
14856
  isMultiSelect && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-500 italic", children: t("BiChat.Question.SelectMulti") }),
14986
14857
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: (question.options || []).map((option) => {
14987
- const isSelected = selectedOptions.includes(option.label);
14858
+ const isSelected = selectedOptions.includes(option.id);
14988
14859
  return /* @__PURE__ */ jsxRuntime.jsx(
14989
14860
  "button",
14990
14861
  {
14991
- onClick: () => handleOptionClick(option.label),
14862
+ onClick: () => handleOptionClick(option.id),
14992
14863
  className: `
14993
14864
  cursor-pointer relative p-4 text-left border-2 rounded-lg transition-all
14994
14865
  ${isSelected ? "border-primary-500 bg-white dark:bg-gray-800" : "border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600"}
@@ -15056,6 +14927,7 @@ function ConfirmationStep({
15056
14927
  const answerData = answers[question.id] || { options: [] };
15057
14928
  const selectedOptions = answerData.options || [];
15058
14929
  const customText = answerData.customText;
14930
+ const optionLabelByID = new Map((question.options || []).map((option) => [option.id, option.label]));
15059
14931
  const hasAnswer = selectedOptions.length > 0 || !!customText;
15060
14932
  return /* @__PURE__ */ jsxRuntime.jsxs(
15061
14933
  "div",
@@ -15068,7 +14940,7 @@ function ConfirmationStep({
15068
14940
  "span",
15069
14941
  {
15070
14942
  className: "inline-flex items-center px-3 py-1 rounded-lg text-sm font-medium border border-primary-500 bg-primary-500/10 text-primary-600 dark:border-primary-400 dark:bg-primary-400/10 dark:text-primary-400",
15071
- children: option
14943
+ children: optionLabelByID.get(option) || option
15072
14944
  },
15073
14945
  option
15074
14946
  )),
@@ -16897,10 +16769,11 @@ function sanitizePendingQuestion(rawPendingQuestion, sessionID) {
16897
16769
  return true;
16898
16770
  }).map((option, optionIndex) => {
16899
16771
  const label = readString2(option.label);
16772
+ const id = readString2(option.id, `${questionID}-opt-${optionIndex}`);
16900
16773
  return {
16901
- id: readString2(option.id, `${questionID}-opt-${optionIndex}`),
16774
+ id,
16902
16775
  label,
16903
- value: label
16776
+ value: id
16904
16777
  };
16905
16778
  }) : [];
16906
16779
  return {
@@ -17712,9 +17585,6 @@ async function* sendMessage(deps, sessionId, content, attachments = [], signal,
17712
17585
  replaceFromMessageId: options?.replaceFromMessageID,
17713
17586
  attachments: streamAttachments
17714
17587
  };
17715
- if (options?.reasoningEffort) {
17716
- payload.reasoningEffort = options.reasoningEffort;
17717
- }
17718
17588
  const timeoutMs = deps.timeout ?? 0;
17719
17589
  if (timeoutMs > 0) {
17720
17590
  connectionTimeoutID = setTimeout(() => {
@@ -17881,12 +17751,19 @@ async function submitQuestionAnswers(callRPC, sessionId, questionId, answers) {
17881
17751
  flatAnswers[qId] = answerData.options.join(", ");
17882
17752
  }
17883
17753
  }
17884
- await callRPC("bichat.question.submit", {
17754
+ const result = await callRPC("bichat.question.submit", {
17885
17755
  sessionId,
17886
17756
  checkpointId: questionId,
17887
17757
  answers: flatAnswers
17888
17758
  });
17889
- return { success: true };
17759
+ return {
17760
+ success: true,
17761
+ data: {
17762
+ session: toSession(result.session),
17763
+ turns: normalizeTurns(sanitizeConversationTurns(result.turns, sessionId)),
17764
+ pendingQuestion: sanitizePendingQuestion(result.pendingQuestion, sessionId)
17765
+ }
17766
+ };
17890
17767
  } catch (err) {
17891
17768
  return { success: false, error: err instanceof Error ? err.message : "Unknown error" };
17892
17769
  }