@iota-uz/sdk 0.4.25 → 0.4.27

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, 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, 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';
@@ -1637,6 +1637,37 @@ function loadDebugMode(sessionId) {
1637
1637
  }
1638
1638
  }
1639
1639
 
1640
+ // ui/src/bichat/utils/reasoningEffortStorage.ts
1641
+ var STORAGE_KEY = "bichat.reasoningEffort";
1642
+ function saveReasoningEffort(effort) {
1643
+ if (typeof window === "undefined") {
1644
+ return;
1645
+ }
1646
+ try {
1647
+ window.sessionStorage.setItem(STORAGE_KEY, effort);
1648
+ } catch {
1649
+ }
1650
+ }
1651
+ function loadReasoningEffort() {
1652
+ if (typeof window === "undefined") {
1653
+ return null;
1654
+ }
1655
+ try {
1656
+ return window.sessionStorage.getItem(STORAGE_KEY);
1657
+ } catch {
1658
+ return null;
1659
+ }
1660
+ }
1661
+ function clearReasoningEffort() {
1662
+ if (typeof window === "undefined") {
1663
+ return;
1664
+ }
1665
+ try {
1666
+ window.sessionStorage.removeItem(STORAGE_KEY);
1667
+ } catch {
1668
+ }
1669
+ }
1670
+
1640
1671
  // ui/src/bichat/utils/debugTrace.ts
1641
1672
  function hasMeaningfulUsage(trace) {
1642
1673
  if (!trace) {
@@ -1779,6 +1810,20 @@ function readDebugLimitsFromGlobalContext() {
1779
1810
  completionReserveTokens
1780
1811
  };
1781
1812
  }
1813
+ function readReasoningEffortOptionsFromGlobalContext() {
1814
+ if (typeof window === "undefined") {
1815
+ return void 0;
1816
+ }
1817
+ const opts = window.__APPLET_CONTEXT__?.extensions?.llm?.reasoningEffortOptions;
1818
+ if (!Array.isArray(opts) || opts.length === 0) {
1819
+ return void 0;
1820
+ }
1821
+ const filtered = opts.filter((o) => typeof o === "string");
1822
+ if (filtered.length === 0) {
1823
+ return void 0;
1824
+ }
1825
+ return filtered;
1826
+ }
1782
1827
 
1783
1828
  // ui/src/bichat/machine/selectors.ts
1784
1829
  function deriveDebugMode(state) {
@@ -1795,8 +1840,11 @@ function deriveSessionSnapshot(state, methods) {
1795
1840
  debugMode: deriveDebugMode(state),
1796
1841
  sessionDebugUsage: getSessionDebugUsage(state.messaging.turns),
1797
1842
  debugLimits: state.session.debugLimits,
1843
+ reasoningEffort: state.session.reasoningEffort,
1844
+ reasoningEffortOptions: state.session.reasoningEffortOptions,
1798
1845
  setError: methods.setError,
1799
- retryFetchSession: methods.retryFetchSession
1846
+ retryFetchSession: methods.retryFetchSession,
1847
+ setReasoningEffort: methods.setReasoningEffort
1800
1848
  };
1801
1849
  }
1802
1850
  function deriveMessagingSnapshot(state, methods) {
@@ -1986,6 +2034,8 @@ var ChatMachine = class {
1986
2034
  this.sendingSessionId = null;
1987
2035
  this.fetchCancelled = false;
1988
2036
  this.disposed = false;
2037
+ this.reasoningEffortOptions = null;
2038
+ this.reasoningEffortOptionSet = null;
1989
2039
  /** Memoized sessionDebugUsage — avoids unnecessary session re-renders during streaming. */
1990
2040
  this.lastSessionDebugUsage = null;
1991
2041
  /** Interval handle for passive polling when another tab has an active stream. */
@@ -2017,7 +2067,8 @@ var ChatMachine = class {
2017
2067
  if (this.lastSessionSnapshotVersion !== this.sessionSnapshotVersion) {
2018
2068
  this.cachedSessionSnapshot = deriveSessionSnapshot(this.state, {
2019
2069
  setError: this.setError,
2020
- retryFetchSession: this.retryFetchSession
2070
+ retryFetchSession: this.retryFetchSession,
2071
+ setReasoningEffort: this.setReasoningEffort
2021
2072
  });
2022
2073
  this.lastSessionSnapshotVersion = this.sessionSnapshotVersion;
2023
2074
  }
@@ -2071,6 +2122,12 @@ var ChatMachine = class {
2071
2122
  this.dataSource = config.dataSource;
2072
2123
  this.rateLimiter = config.rateLimiter;
2073
2124
  this.onSessionCreated = config.onSessionCreated;
2125
+ this.reasoningEffortOptions = this.buildReasoningEffortOptions();
2126
+ this.reasoningEffortOptionSet = this.reasoningEffortOptions ? new Set(this.reasoningEffortOptions) : null;
2127
+ const initialReasoningEffort = this.sanitizeReasoningEffort(loadReasoningEffort() || void 0);
2128
+ if (!initialReasoningEffort) {
2129
+ clearReasoningEffort();
2130
+ }
2074
2131
  this.state = {
2075
2132
  session: {
2076
2133
  currentSessionId: void 0,
@@ -2079,7 +2136,9 @@ var ChatMachine = class {
2079
2136
  error: null,
2080
2137
  errorRetryable: false,
2081
2138
  debugModeBySession: {},
2082
- debugLimits: readDebugLimitsFromGlobalContext()
2139
+ debugLimits: readDebugLimitsFromGlobalContext(),
2140
+ reasoningEffort: initialReasoningEffort,
2141
+ reasoningEffortOptions: this.reasoningEffortOptions ?? void 0
2083
2142
  },
2084
2143
  messaging: {
2085
2144
  turns: [],
@@ -2121,6 +2180,21 @@ var ChatMachine = class {
2121
2180
  this.enqueueMessage = this._enqueueMessage.bind(this);
2122
2181
  this.removeQueueItem = this._removeQueueItem.bind(this);
2123
2182
  this.updateQueueItem = this._updateQueueItem.bind(this);
2183
+ this.setReasoningEffort = this._setReasoningEffort.bind(this);
2184
+ }
2185
+ buildReasoningEffortOptions() {
2186
+ const options = readReasoningEffortOptionsFromGlobalContext();
2187
+ if (!options || options.length === 0) {
2188
+ return null;
2189
+ }
2190
+ return options;
2191
+ }
2192
+ // Keep outbound payloads constrained to server-declared options.
2193
+ sanitizeReasoningEffort(effort) {
2194
+ if (!effort || !this.reasoningEffortOptionSet || this.reasoningEffortOptionSet.size === 0) {
2195
+ return void 0;
2196
+ }
2197
+ return this.reasoningEffortOptionSet.has(effort) ? effort : void 0;
2124
2198
  }
2125
2199
  // =====================================================================
2126
2200
  // Lifecycle
@@ -2241,6 +2315,15 @@ var ChatMachine = class {
2241
2315
  }
2242
2316
  });
2243
2317
  }
2318
+ _setReasoningEffort(effort) {
2319
+ const next = this.sanitizeReasoningEffort(effort);
2320
+ this._updateSession({ reasoningEffort: next });
2321
+ if (next) {
2322
+ saveReasoningEffort(next);
2323
+ return;
2324
+ }
2325
+ clearReasoningEffort();
2326
+ }
2244
2327
  // =====================================================================
2245
2328
  // Private — session fetch
2246
2329
  // =====================================================================
@@ -2668,6 +2751,7 @@ var ChatMachine = class {
2668
2751
  attachments,
2669
2752
  debugMode,
2670
2753
  replaceFromMessageID,
2754
+ reasoningEffort,
2671
2755
  tempTurnId
2672
2756
  } = params;
2673
2757
  let accumulatedContent = "";
@@ -2682,7 +2766,8 @@ var ChatMachine = class {
2682
2766
  this.abortController?.signal,
2683
2767
  {
2684
2768
  debugMode,
2685
- replaceFromMessageID
2769
+ replaceFromMessageID,
2770
+ reasoningEffort
2686
2771
  }
2687
2772
  )) {
2688
2773
  if (this.abortController?.signal.aborted) {
@@ -2879,6 +2964,7 @@ var ChatMachine = class {
2879
2964
  attachments,
2880
2965
  debugMode: curDebugMode,
2881
2966
  replaceFromMessageID,
2967
+ reasoningEffort: this.sanitizeReasoningEffort(this.state.session.reasoningEffort),
2882
2968
  tempTurnId: tempTurn.id
2883
2969
  });
2884
2970
  if (stopped) {
@@ -7075,21 +7161,15 @@ function calculateContextUsagePercent(promptTokens, effectiveMaxTokens) {
7075
7161
  }
7076
7162
  return promptTokens / effectiveMaxTokens * 100;
7077
7163
  }
7078
- function CopyPill({ text }) {
7164
+ function useCopyFeedback() {
7079
7165
  const [copied, setCopied] = useState(false);
7080
7166
  const timerRef = useRef(null);
7081
- useEffect(() => () => {
7082
- if (timerRef.current !== null) {
7083
- clearTimeout(timerRef.current);
7084
- }
7085
- }, []);
7086
- const handleCopy = async (e) => {
7087
- e.stopPropagation();
7167
+ const copy = useCallback(async (text) => {
7088
7168
  try {
7089
7169
  await navigator.clipboard.writeText(text);
7090
7170
  setCopied(true);
7091
7171
  if (timerRef.current !== null) {
7092
- clearTimeout(timerRef.current);
7172
+ window.clearTimeout(timerRef.current);
7093
7173
  }
7094
7174
  timerRef.current = window.setTimeout(() => {
7095
7175
  setCopied(false);
@@ -7098,6 +7178,19 @@ function CopyPill({ text }) {
7098
7178
  } catch (err) {
7099
7179
  console.error("Copy failed:", err);
7100
7180
  }
7181
+ }, []);
7182
+ useEffect(() => () => {
7183
+ if (timerRef.current !== null) {
7184
+ window.clearTimeout(timerRef.current);
7185
+ }
7186
+ }, []);
7187
+ return { copied, copy };
7188
+ }
7189
+ function CopyPill({ text }) {
7190
+ const { copied, copy } = useCopyFeedback();
7191
+ const handleCopy = async (e) => {
7192
+ e.stopPropagation();
7193
+ await copy(text);
7101
7194
  };
7102
7195
  return /* @__PURE__ */ jsxs(
7103
7196
  "button",
@@ -7115,6 +7208,25 @@ function CopyPill({ text }) {
7115
7208
  }
7116
7209
  );
7117
7210
  }
7211
+ function InlineCopyButton({ text }) {
7212
+ const { copied, copy } = useCopyFeedback();
7213
+ const handleCopy = async (e) => {
7214
+ e.stopPropagation();
7215
+ await copy(text);
7216
+ };
7217
+ return /* @__PURE__ */ jsx(
7218
+ "button",
7219
+ {
7220
+ onClick: handleCopy,
7221
+ "aria-label": copied ? "Copied" : "Copy",
7222
+ className: [
7223
+ "flex-shrink-0 p-1 rounded transition-colors duration-150",
7224
+ 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"
7225
+ ].join(" "),
7226
+ children: copied ? /* @__PURE__ */ jsx(Check, { size: 11, weight: "bold" }) : /* @__PURE__ */ jsx(Copy, { size: 11 })
7227
+ }
7228
+ );
7229
+ }
7118
7230
  function MetricChip({ icon, value, label }) {
7119
7231
  return /* @__PURE__ */ 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: [
7120
7232
  icon,
@@ -7213,7 +7325,7 @@ function ToolCard({ tool }) {
7213
7325
  }
7214
7326
  );
7215
7327
  }
7216
- function DebugPanel({ trace, debugLimits = null }) {
7328
+ function DebugPanel({ trace }) {
7217
7329
  const hasData = !!trace && hasDebugTrace(trace);
7218
7330
  const traceID = trace?.traceId?.trim() || "";
7219
7331
  const traceURL = trace?.traceUrl?.trim() || "";
@@ -7232,22 +7344,6 @@ function DebugPanel({ trace, debugLimits = null }) {
7232
7344
  }
7233
7345
  })();
7234
7346
  const tokensPerSecond = calculateCompletionTokensPerSecond(trace?.usage, trace?.generationMs);
7235
- const effectiveMaxTokens = debugLimits?.effectiveMaxTokens ?? 0;
7236
- const promptTokens = trace?.usage?.promptTokens ?? 0;
7237
- const contextUsagePercent = calculateContextUsagePercent(promptTokens, effectiveMaxTokens);
7238
- const contextUsagePercentLabel = contextUsagePercent !== null ? contextUsagePercent.toFixed(1) : null;
7239
- const formatCompactTokens = (value) => {
7240
- if (!Number.isFinite(value) || value <= 0) {
7241
- return "0 tokens";
7242
- }
7243
- return `${new Intl.NumberFormat("en-US", {
7244
- notation: "compact",
7245
- maximumFractionDigits: value >= 1e5 ? 0 : 1
7246
- }).format(value)} tokens`;
7247
- };
7248
- const contextPercentValue = contextUsagePercent ?? 0;
7249
- 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";
7250
- const contextUsageBarColor = contextPercentValue > 75 ? "#ef4444" : contextPercentValue > 50 ? "#f59e0b" : "#10b981";
7251
7347
  const metrics = [];
7252
7348
  if (hasData && trace) {
7253
7349
  if (trace.generationMs !== void 0) {
@@ -7300,34 +7396,36 @@ function DebugPanel({ trace, debugLimits = null }) {
7300
7396
  hasData && trace && /* @__PURE__ */ jsx(CopyPill, { text: JSON.stringify(trace, null, 2) })
7301
7397
  ] }),
7302
7398
  hasData && trace ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
7303
- (traceID || safeTraceURL) && /* @__PURE__ */ 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: [
7304
- traceID && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
7305
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
7306
- /* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Trace ID" }),
7307
- /* @__PURE__ */ jsx("div", { className: "font-mono text-[11px] text-gray-800 dark:text-gray-200 break-all", children: traceID })
7308
- ] }),
7309
- /* @__PURE__ */ jsx(CopyPill, { text: traceID })
7399
+ (traceID || trace.sessionId) && /* @__PURE__ */ 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: [
7400
+ traceID && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
7401
+ /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500 w-14", children: "Trace" }),
7402
+ /* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0 font-mono text-[11px] text-gray-700 dark:text-gray-300 truncate", title: traceID, children: traceID }),
7403
+ /* @__PURE__ */ jsx(InlineCopyButton, { text: traceID })
7310
7404
  ] }),
7311
- safeTraceURL && /* @__PURE__ */ jsxs(
7312
- "a",
7313
- {
7314
- href: safeTraceURL,
7315
- target: "_blank",
7316
- rel: "noopener noreferrer",
7317
- "aria-label": "View full trace in Langfuse (opens in new tab)",
7318
- 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",
7319
- children: [
7320
- /* @__PURE__ */ jsx(ArrowSquareOut, { size: 12, weight: "bold" }),
7321
- /* @__PURE__ */ jsx("span", { children: "Open in Langfuse" })
7322
- ]
7323
- }
7324
- )
7325
- ] }),
7326
- (trace.thinking || trace.observationReason || trace.sessionId) && /* @__PURE__ */ 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: [
7327
- trace.sessionId && /* @__PURE__ */ jsxs("div", { className: "text-[10px] uppercase tracking-wider text-gray-500 dark:text-gray-400", children: [
7328
- "Session: ",
7329
- /* @__PURE__ */ jsx("span", { className: "font-mono normal-case break-all", children: trace.sessionId })
7405
+ trace.sessionId && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
7406
+ /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500 w-14", children: "Session" }),
7407
+ /* @__PURE__ */ 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 }),
7408
+ /* @__PURE__ */ jsx(InlineCopyButton, { text: trace.sessionId })
7330
7409
  ] }),
7410
+ safeTraceURL && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0 pt-0.5", children: [
7411
+ /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 w-14" }),
7412
+ /* @__PURE__ */ jsxs(
7413
+ "a",
7414
+ {
7415
+ href: safeTraceURL,
7416
+ target: "_blank",
7417
+ rel: "noopener noreferrer",
7418
+ "aria-label": "Open in Langfuse",
7419
+ 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",
7420
+ children: [
7421
+ /* @__PURE__ */ jsx(ArrowSquareOut, { size: 11, weight: "bold" }),
7422
+ /* @__PURE__ */ jsx("span", { children: "Open in Langfuse" })
7423
+ ]
7424
+ }
7425
+ )
7426
+ ] })
7427
+ ] }),
7428
+ (trace.thinking || trace.observationReason) && /* @__PURE__ */ 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: [
7331
7429
  trace.observationReason && /* @__PURE__ */ jsxs("div", { className: "text-[11px] text-amber-700 dark:text-amber-300", children: [
7332
7430
  "Observation: ",
7333
7431
  /* @__PURE__ */ jsx("span", { className: "font-mono", children: trace.observationReason })
@@ -7367,30 +7465,6 @@ function DebugPanel({ trace, debugLimits = null }) {
7367
7465
  /* @__PURE__ */ 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 })
7368
7466
  ] }),
7369
7467
  /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: trace.tools.map((tool, idx) => /* @__PURE__ */ jsx(ToolCard, { tool }, `${tool.callId || tool.name}-${idx}`)) })
7370
- ] }),
7371
- contextUsagePercentLabel !== null && /* @__PURE__ */ 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: [
7372
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
7373
- /* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Context usage" }),
7374
- /* @__PURE__ */ jsxs("span", { className: "font-mono text-[10px] text-gray-500 dark:text-gray-400 tabular-nums", children: [
7375
- formatCompactTokens(promptTokens),
7376
- " / ",
7377
- formatCompactTokens(effectiveMaxTokens)
7378
- ] }),
7379
- /* @__PURE__ */ jsxs("span", { className: `px-1.5 py-0.5 rounded-full text-[10px] font-semibold tabular-nums ${contextUsageToneClass}`, children: [
7380
- contextUsagePercentLabel,
7381
- "%"
7382
- ] })
7383
- ] }),
7384
- /* @__PURE__ */ jsx("div", { className: "h-1.5 rounded-full bg-gray-200/80 dark:bg-gray-700/50 overflow-hidden", children: /* @__PURE__ */ jsx(
7385
- "div",
7386
- {
7387
- className: "h-full rounded-full transition-all duration-700 ease-out",
7388
- style: {
7389
- width: `${Math.min(contextPercentValue, 100)}%`,
7390
- backgroundColor: contextUsageBarColor
7391
- }
7392
- }
7393
- ) })
7394
7468
  ] })
7395
7469
  ] }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500 italic", children: "Debug info unavailable" })
7396
7470
  ] });
@@ -7452,8 +7526,7 @@ function AssistantMessage({
7452
7526
  hideAvatar = false,
7453
7527
  hideActions = false,
7454
7528
  hideTimestamp = false,
7455
- showDebug = false,
7456
- debugLimits = null
7529
+ showDebug = false
7457
7530
  }) {
7458
7531
  const { t } = useTranslation();
7459
7532
  const [explanationExpanded, setExplanationExpanded] = useState(false);
@@ -7644,7 +7717,7 @@ function AssistantMessage({
7644
7717
  explanationExpanded && /* @__PURE__ */ jsx("div", { className: "pt-3 text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { children: t("BiChat.Common.Loading") }), children: /* @__PURE__ */ jsx(MarkdownRenderer2, { content: turn.explanation }) }) })
7645
7718
  ] })
7646
7719
  ) }),
7647
- showDebug && /* @__PURE__ */ jsx(DebugPanel, { trace: turn.debug, debugLimits })
7720
+ showDebug && /* @__PURE__ */ jsx(DebugPanel, { trace: turn.debug })
7648
7721
  ] }),
7649
7722
  turn.artifacts && turn.artifacts.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.artifacts, children: renderSlot(
7650
7723
  slots?.artifacts,
@@ -7836,7 +7909,7 @@ function AssistantTurnView({
7836
7909
  hideTimestamp,
7837
7910
  allowRegenerate = true
7838
7911
  }) {
7839
- const { debugMode, debugLimits } = useChatSession();
7912
+ const { debugMode } = useChatSession();
7840
7913
  const { handleCopy, handleRegenerate, pendingQuestion, sendMessage: sendMessage2, loading } = useChatMessaging();
7841
7914
  const assistantTurn = turn.assistantTurn;
7842
7915
  if (!assistantTurn) {
@@ -7871,8 +7944,7 @@ function AssistantTurnView({
7871
7944
  hideAvatar,
7872
7945
  hideActions,
7873
7946
  hideTimestamp,
7874
- showDebug: debugMode,
7875
- debugLimits
7947
+ showDebug: debugMode
7876
7948
  }
7877
7949
  );
7878
7950
  }
@@ -9017,6 +9089,36 @@ function DebugStatsPanel({ debugSessionUsage, debugLimits }) {
9017
9089
  ] })
9018
9090
  ] });
9019
9091
  }
9092
+ var EFFORT_LABEL_KEYS = {
9093
+ low: "BiChat.Input.ReasoningEffortLow",
9094
+ medium: "BiChat.Input.ReasoningEffortMedium",
9095
+ high: "BiChat.Input.ReasoningEffortHigh",
9096
+ xhigh: "BiChat.Input.ReasoningEffortXHigh"
9097
+ };
9098
+ function ReasoningEffortSelector({ options, value, onChange, disabled }) {
9099
+ const { t } = useTranslation();
9100
+ const selected = value || options[1] || options[0];
9101
+ const label = t("BiChat.Input.ReasoningEffort");
9102
+ return /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 self-center flex items-center gap-1.5", children: [
9103
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-gray-400 dark:text-gray-500 font-medium whitespace-nowrap select-none", children: label }),
9104
+ /* @__PURE__ */ jsx(
9105
+ "select",
9106
+ {
9107
+ value: selected,
9108
+ disabled,
9109
+ onChange: (event) => onChange(event.target.value),
9110
+ className: [
9111
+ "cursor-pointer h-8 rounded-lg border border-gray-200 dark:border-gray-600",
9112
+ "bg-gray-50 dark:bg-gray-700/50 px-2.5 text-[11px] font-medium leading-none",
9113
+ "text-gray-700 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-primary-500/25",
9114
+ "disabled:opacity-40 disabled:cursor-not-allowed"
9115
+ ].join(" "),
9116
+ "aria-label": label,
9117
+ children: options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: t(EFFORT_LABEL_KEYS[opt] ?? opt) }, opt))
9118
+ }
9119
+ )
9120
+ ] });
9121
+ }
9020
9122
  var MAX_FILES_DEFAULT = 10;
9021
9123
  var MAX_FILE_SIZE_DEFAULT = 20 * 1024 * 1024;
9022
9124
  var MAX_HEIGHT = 192;
@@ -9043,7 +9145,10 @@ var MessageInput = forwardRef(
9043
9145
  maxFiles = MAX_FILES_DEFAULT,
9044
9146
  maxFileSize = MAX_FILE_SIZE_DEFAULT,
9045
9147
  containerClassName,
9046
- formClassName
9148
+ formClassName,
9149
+ reasoningEffortOptions,
9150
+ reasoningEffort,
9151
+ onReasoningEffortChange
9047
9152
  }, ref) => {
9048
9153
  const { t } = useTranslation();
9049
9154
  const [attachments, setAttachments] = useState([]);
@@ -9370,6 +9475,16 @@ var MessageInput = forwardRef(
9370
9475
  const canSubmit = !disabled && (message.trim() || attachments.length > 0);
9371
9476
  const visibleError = error || commandError;
9372
9477
  const visibleErrorText = visibleError ? t(visibleError) : "";
9478
+ const resolvedReasoningEffort = reasoningEffortOptions && reasoningEffortOptions.length > 0 ? reasoningEffortOptions.includes(reasoningEffort ?? "") ? reasoningEffort : reasoningEffortOptions[1] || reasoningEffortOptions[0] : void 0;
9479
+ useEffect(() => {
9480
+ if (!onReasoningEffortChange || !reasoningEffortOptions?.length) {
9481
+ return;
9482
+ }
9483
+ if (!resolvedReasoningEffort || resolvedReasoningEffort === reasoningEffort) {
9484
+ return;
9485
+ }
9486
+ onReasoningEffortChange(resolvedReasoningEffort);
9487
+ }, [reasoningEffort, onReasoningEffortChange, reasoningEffortOptions, resolvedReasoningEffort]);
9373
9488
  const defaultContainerClassName = "shrink-0 px-4 pt-4 pb-6";
9374
9489
  return /* @__PURE__ */ jsx(
9375
9490
  "div",
@@ -9492,16 +9607,25 @@ var MessageInput = forwardRef(
9492
9607
  "aria-label": t("BiChat.Input.MessageInput")
9493
9608
  }
9494
9609
  ) }),
9610
+ reasoningEffortOptions && reasoningEffortOptions.length > 0 && onReasoningEffortChange && /* @__PURE__ */ jsx(
9611
+ ReasoningEffortSelector,
9612
+ {
9613
+ options: reasoningEffortOptions,
9614
+ value: resolvedReasoningEffort,
9615
+ onChange: onReasoningEffortChange,
9616
+ disabled: disabled || loading
9617
+ }
9618
+ ),
9495
9619
  isStreaming && onCancelStreaming ? /* @__PURE__ */ jsx(
9496
9620
  "button",
9497
9621
  {
9498
9622
  type: "button",
9499
9623
  onClick: onCancelStreaming,
9500
9624
  disabled: disabled || fetching,
9501
- 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",
9625
+ 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",
9502
9626
  "aria-label": t("BiChat.Common.Cancel"),
9503
9627
  title: t("BiChat.Common.Cancel"),
9504
- children: /* @__PURE__ */ jsx(X, { size: 18, weight: "bold" })
9628
+ children: /* @__PURE__ */ jsx(Stop, { size: 18, weight: "fill" })
9505
9629
  }
9506
9630
  ) : /* @__PURE__ */ jsx(
9507
9631
  "button",
@@ -11691,7 +11815,10 @@ function ChatSessionCore({
11691
11815
  debugLimits,
11692
11816
  currentSessionId,
11693
11817
  setError,
11694
- retryFetchSession
11818
+ retryFetchSession,
11819
+ reasoningEffort,
11820
+ setReasoningEffort,
11821
+ reasoningEffortOptions
11695
11822
  } = useChatSession();
11696
11823
  const {
11697
11824
  turns,
@@ -11986,7 +12113,10 @@ function ChatSessionCore({
11986
12113
  onUpdateQueueItem: updateQueueItem,
11987
12114
  onCancelStreaming: cancel,
11988
12115
  containerClassName: "pt-6 px-6",
11989
- formClassName: "mx-auto"
12116
+ formClassName: "mx-auto",
12117
+ reasoningEffortOptions,
12118
+ reasoningEffort,
12119
+ onReasoningEffortChange: setReasoningEffort
11990
12120
  }
11991
12121
  ),
11992
12122
  /* @__PURE__ */ jsx("p", { className: "mt-4 pb-1 text-center text-xs text-gray-500 dark:text-gray-400", children: t("BiChat.Welcome.Disclaimer") })
@@ -12042,7 +12172,10 @@ function ChatSessionCore({
12042
12172
  onUnqueue: handleUnqueue,
12043
12173
  onRemoveQueueItem: removeQueueItem,
12044
12174
  onUpdateQueueItem: updateQueueItem,
12045
- onCancelStreaming: cancel
12175
+ onCancelStreaming: cancel,
12176
+ reasoningEffortOptions,
12177
+ reasoningEffort,
12178
+ onReasoningEffortChange: setReasoningEffort
12046
12179
  }
12047
12180
  )
12048
12181
  ] }) }),
@@ -18574,6 +18707,9 @@ async function* sendMessage(deps, sessionId, content, attachments = [], signal,
18574
18707
  replaceFromMessageId: options?.replaceFromMessageID,
18575
18708
  attachments: streamAttachments
18576
18709
  };
18710
+ if (options?.reasoningEffort) {
18711
+ payload.reasoningEffort = options.reasoningEffort;
18712
+ }
18577
18713
  const timeoutMs = deps.streamConnectTimeoutMs ?? 0;
18578
18714
  if (timeoutMs > 0) {
18579
18715
  connectionTimeoutID = setTimeout(() => {