@iota-uz/sdk 0.4.25 → 0.4.26

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,16 @@ 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
+ return opts.filter((o) => typeof o === "string");
1822
+ }
1782
1823
 
1783
1824
  // ui/src/bichat/machine/selectors.ts
1784
1825
  function deriveDebugMode(state) {
@@ -1795,8 +1836,10 @@ function deriveSessionSnapshot(state, methods) {
1795
1836
  debugMode: deriveDebugMode(state),
1796
1837
  sessionDebugUsage: getSessionDebugUsage(state.messaging.turns),
1797
1838
  debugLimits: state.session.debugLimits,
1839
+ reasoningEffort: state.session.reasoningEffort,
1798
1840
  setError: methods.setError,
1799
- retryFetchSession: methods.retryFetchSession
1841
+ retryFetchSession: methods.retryFetchSession,
1842
+ setReasoningEffort: methods.setReasoningEffort
1800
1843
  };
1801
1844
  }
1802
1845
  function deriveMessagingSnapshot(state, methods) {
@@ -1986,6 +2029,7 @@ var ChatMachine = class {
1986
2029
  this.sendingSessionId = null;
1987
2030
  this.fetchCancelled = false;
1988
2031
  this.disposed = false;
2032
+ this.reasoningEffortOptions = null;
1989
2033
  /** Memoized sessionDebugUsage — avoids unnecessary session re-renders during streaming. */
1990
2034
  this.lastSessionDebugUsage = null;
1991
2035
  /** Interval handle for passive polling when another tab has an active stream. */
@@ -2017,7 +2061,8 @@ var ChatMachine = class {
2017
2061
  if (this.lastSessionSnapshotVersion !== this.sessionSnapshotVersion) {
2018
2062
  this.cachedSessionSnapshot = deriveSessionSnapshot(this.state, {
2019
2063
  setError: this.setError,
2020
- retryFetchSession: this.retryFetchSession
2064
+ retryFetchSession: this.retryFetchSession,
2065
+ setReasoningEffort: this.setReasoningEffort
2021
2066
  });
2022
2067
  this.lastSessionSnapshotVersion = this.sessionSnapshotVersion;
2023
2068
  }
@@ -2071,6 +2116,11 @@ var ChatMachine = class {
2071
2116
  this.dataSource = config.dataSource;
2072
2117
  this.rateLimiter = config.rateLimiter;
2073
2118
  this.onSessionCreated = config.onSessionCreated;
2119
+ this.reasoningEffortOptions = this.buildReasoningEffortOptions();
2120
+ const initialReasoningEffort = this.sanitizeReasoningEffort(loadReasoningEffort() || void 0);
2121
+ if (!initialReasoningEffort) {
2122
+ clearReasoningEffort();
2123
+ }
2074
2124
  this.state = {
2075
2125
  session: {
2076
2126
  currentSessionId: void 0,
@@ -2079,7 +2129,8 @@ var ChatMachine = class {
2079
2129
  error: null,
2080
2130
  errorRetryable: false,
2081
2131
  debugModeBySession: {},
2082
- debugLimits: readDebugLimitsFromGlobalContext()
2132
+ debugLimits: readDebugLimitsFromGlobalContext(),
2133
+ reasoningEffort: initialReasoningEffort
2083
2134
  },
2084
2135
  messaging: {
2085
2136
  turns: [],
@@ -2121,6 +2172,21 @@ var ChatMachine = class {
2121
2172
  this.enqueueMessage = this._enqueueMessage.bind(this);
2122
2173
  this.removeQueueItem = this._removeQueueItem.bind(this);
2123
2174
  this.updateQueueItem = this._updateQueueItem.bind(this);
2175
+ this.setReasoningEffort = this._setReasoningEffort.bind(this);
2176
+ }
2177
+ buildReasoningEffortOptions() {
2178
+ const options = readReasoningEffortOptionsFromGlobalContext();
2179
+ if (!options || options.length === 0) {
2180
+ return null;
2181
+ }
2182
+ return new Set(options);
2183
+ }
2184
+ // Keep outbound payloads constrained to server-declared options.
2185
+ sanitizeReasoningEffort(effort) {
2186
+ if (!effort || !this.reasoningEffortOptions || this.reasoningEffortOptions.size === 0) {
2187
+ return void 0;
2188
+ }
2189
+ return this.reasoningEffortOptions.has(effort) ? effort : void 0;
2124
2190
  }
2125
2191
  // =====================================================================
2126
2192
  // Lifecycle
@@ -2241,6 +2307,15 @@ var ChatMachine = class {
2241
2307
  }
2242
2308
  });
2243
2309
  }
2310
+ _setReasoningEffort(effort) {
2311
+ const next = this.sanitizeReasoningEffort(effort);
2312
+ this._updateSession({ reasoningEffort: next });
2313
+ if (next) {
2314
+ saveReasoningEffort(next);
2315
+ return;
2316
+ }
2317
+ clearReasoningEffort();
2318
+ }
2244
2319
  // =====================================================================
2245
2320
  // Private — session fetch
2246
2321
  // =====================================================================
@@ -2668,6 +2743,7 @@ var ChatMachine = class {
2668
2743
  attachments,
2669
2744
  debugMode,
2670
2745
  replaceFromMessageID,
2746
+ reasoningEffort,
2671
2747
  tempTurnId
2672
2748
  } = params;
2673
2749
  let accumulatedContent = "";
@@ -2682,7 +2758,8 @@ var ChatMachine = class {
2682
2758
  this.abortController?.signal,
2683
2759
  {
2684
2760
  debugMode,
2685
- replaceFromMessageID
2761
+ replaceFromMessageID,
2762
+ reasoningEffort
2686
2763
  }
2687
2764
  )) {
2688
2765
  if (this.abortController?.signal.aborted) {
@@ -2879,6 +2956,7 @@ var ChatMachine = class {
2879
2956
  attachments,
2880
2957
  debugMode: curDebugMode,
2881
2958
  replaceFromMessageID,
2959
+ reasoningEffort: this.sanitizeReasoningEffort(this.state.session.reasoningEffort),
2882
2960
  tempTurnId: tempTurn.id
2883
2961
  });
2884
2962
  if (stopped) {
@@ -7115,6 +7193,43 @@ function CopyPill({ text }) {
7115
7193
  }
7116
7194
  );
7117
7195
  }
7196
+ function InlineCopyButton({ text }) {
7197
+ const [copied, setCopied] = useState(false);
7198
+ const timerRef = useRef(null);
7199
+ useEffect(() => () => {
7200
+ if (timerRef.current !== null) {
7201
+ clearTimeout(timerRef.current);
7202
+ }
7203
+ }, []);
7204
+ const handleCopy = async (e) => {
7205
+ e.stopPropagation();
7206
+ try {
7207
+ await navigator.clipboard.writeText(text);
7208
+ setCopied(true);
7209
+ if (timerRef.current !== null) {
7210
+ clearTimeout(timerRef.current);
7211
+ }
7212
+ timerRef.current = window.setTimeout(() => {
7213
+ setCopied(false);
7214
+ timerRef.current = null;
7215
+ }, 2e3);
7216
+ } catch (err) {
7217
+ console.error("Copy failed:", err);
7218
+ }
7219
+ };
7220
+ return /* @__PURE__ */ jsx(
7221
+ "button",
7222
+ {
7223
+ onClick: handleCopy,
7224
+ "aria-label": copied ? "Copied" : "Copy",
7225
+ className: [
7226
+ "flex-shrink-0 p-1 rounded transition-colors duration-150",
7227
+ 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"
7228
+ ].join(" "),
7229
+ children: copied ? /* @__PURE__ */ jsx(Check, { size: 11, weight: "bold" }) : /* @__PURE__ */ jsx(Copy, { size: 11 })
7230
+ }
7231
+ );
7232
+ }
7118
7233
  function MetricChip({ icon, value, label }) {
7119
7234
  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
7235
  icon,
@@ -7213,7 +7328,7 @@ function ToolCard({ tool }) {
7213
7328
  }
7214
7329
  );
7215
7330
  }
7216
- function DebugPanel({ trace, debugLimits = null }) {
7331
+ function DebugPanel({ trace }) {
7217
7332
  const hasData = !!trace && hasDebugTrace(trace);
7218
7333
  const traceID = trace?.traceId?.trim() || "";
7219
7334
  const traceURL = trace?.traceUrl?.trim() || "";
@@ -7232,22 +7347,6 @@ function DebugPanel({ trace, debugLimits = null }) {
7232
7347
  }
7233
7348
  })();
7234
7349
  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
7350
  const metrics = [];
7252
7351
  if (hasData && trace) {
7253
7352
  if (trace.generationMs !== void 0) {
@@ -7300,34 +7399,36 @@ function DebugPanel({ trace, debugLimits = null }) {
7300
7399
  hasData && trace && /* @__PURE__ */ jsx(CopyPill, { text: JSON.stringify(trace, null, 2) })
7301
7400
  ] }),
7302
7401
  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 })
7402
+ (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: [
7403
+ traceID && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
7404
+ /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500 w-14", children: "Trace" }),
7405
+ /* @__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 }),
7406
+ /* @__PURE__ */ jsx(InlineCopyButton, { text: traceID })
7310
7407
  ] }),
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 })
7408
+ trace.sessionId && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
7409
+ /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500 w-14", children: "Session" }),
7410
+ /* @__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 }),
7411
+ /* @__PURE__ */ jsx(InlineCopyButton, { text: trace.sessionId })
7330
7412
  ] }),
7413
+ safeTraceURL && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0 pt-0.5", children: [
7414
+ /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 w-14" }),
7415
+ /* @__PURE__ */ jsxs(
7416
+ "a",
7417
+ {
7418
+ href: safeTraceURL,
7419
+ target: "_blank",
7420
+ rel: "noopener noreferrer",
7421
+ "aria-label": "Open in Langfuse",
7422
+ 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",
7423
+ children: [
7424
+ /* @__PURE__ */ jsx(ArrowSquareOut, { size: 11, weight: "bold" }),
7425
+ /* @__PURE__ */ jsx("span", { children: "Open in Langfuse" })
7426
+ ]
7427
+ }
7428
+ )
7429
+ ] })
7430
+ ] }),
7431
+ (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
7432
  trace.observationReason && /* @__PURE__ */ jsxs("div", { className: "text-[11px] text-amber-700 dark:text-amber-300", children: [
7332
7433
  "Observation: ",
7333
7434
  /* @__PURE__ */ jsx("span", { className: "font-mono", children: trace.observationReason })
@@ -7367,30 +7468,6 @@ function DebugPanel({ trace, debugLimits = null }) {
7367
7468
  /* @__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
7469
  ] }),
7369
7470
  /* @__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
7471
  ] })
7395
7472
  ] }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500 italic", children: "Debug info unavailable" })
7396
7473
  ] });
@@ -7452,8 +7529,7 @@ function AssistantMessage({
7452
7529
  hideAvatar = false,
7453
7530
  hideActions = false,
7454
7531
  hideTimestamp = false,
7455
- showDebug = false,
7456
- debugLimits = null
7532
+ showDebug = false
7457
7533
  }) {
7458
7534
  const { t } = useTranslation();
7459
7535
  const [explanationExpanded, setExplanationExpanded] = useState(false);
@@ -7644,7 +7720,7 @@ function AssistantMessage({
7644
7720
  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
7721
  ] })
7646
7722
  ) }),
7647
- showDebug && /* @__PURE__ */ jsx(DebugPanel, { trace: turn.debug, debugLimits })
7723
+ showDebug && /* @__PURE__ */ jsx(DebugPanel, { trace: turn.debug })
7648
7724
  ] }),
7649
7725
  turn.artifacts && turn.artifacts.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.artifacts, children: renderSlot(
7650
7726
  slots?.artifacts,
@@ -7836,7 +7912,7 @@ function AssistantTurnView({
7836
7912
  hideTimestamp,
7837
7913
  allowRegenerate = true
7838
7914
  }) {
7839
- const { debugMode, debugLimits } = useChatSession();
7915
+ const { debugMode } = useChatSession();
7840
7916
  const { handleCopy, handleRegenerate, pendingQuestion, sendMessage: sendMessage2, loading } = useChatMessaging();
7841
7917
  const assistantTurn = turn.assistantTurn;
7842
7918
  if (!assistantTurn) {
@@ -7871,8 +7947,7 @@ function AssistantTurnView({
7871
7947
  hideAvatar,
7872
7948
  hideActions,
7873
7949
  hideTimestamp,
7874
- showDebug: debugMode,
7875
- debugLimits
7950
+ showDebug: debugMode
7876
7951
  }
7877
7952
  );
7878
7953
  }
@@ -9017,6 +9092,36 @@ function DebugStatsPanel({ debugSessionUsage, debugLimits }) {
9017
9092
  ] })
9018
9093
  ] });
9019
9094
  }
9095
+ var EFFORT_LABEL_KEYS = {
9096
+ low: "BiChat.Input.ReasoningEffortLow",
9097
+ medium: "BiChat.Input.ReasoningEffortMedium",
9098
+ high: "BiChat.Input.ReasoningEffortHigh",
9099
+ xhigh: "BiChat.Input.ReasoningEffortXHigh"
9100
+ };
9101
+ function ReasoningEffortSelector({ options, value, onChange, disabled }) {
9102
+ const { t } = useTranslation();
9103
+ const selected = value || options[1] || options[0];
9104
+ const label = t("BiChat.Input.ReasoningEffort");
9105
+ return /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 self-center flex items-center gap-1.5", children: [
9106
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-gray-400 dark:text-gray-500 font-medium whitespace-nowrap select-none", children: label }),
9107
+ /* @__PURE__ */ jsx(
9108
+ "select",
9109
+ {
9110
+ value: selected,
9111
+ disabled,
9112
+ onChange: (event) => onChange(event.target.value),
9113
+ className: [
9114
+ "cursor-pointer h-8 rounded-lg border border-gray-200 dark:border-gray-600",
9115
+ "bg-gray-50 dark:bg-gray-700/50 px-2.5 text-[11px] font-medium leading-none",
9116
+ "text-gray-700 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-primary-500/25",
9117
+ "disabled:opacity-40 disabled:cursor-not-allowed"
9118
+ ].join(" "),
9119
+ "aria-label": label,
9120
+ children: options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: t(EFFORT_LABEL_KEYS[opt] ?? opt) }, opt))
9121
+ }
9122
+ )
9123
+ ] });
9124
+ }
9020
9125
  var MAX_FILES_DEFAULT = 10;
9021
9126
  var MAX_FILE_SIZE_DEFAULT = 20 * 1024 * 1024;
9022
9127
  var MAX_HEIGHT = 192;
@@ -9043,7 +9148,10 @@ var MessageInput = forwardRef(
9043
9148
  maxFiles = MAX_FILES_DEFAULT,
9044
9149
  maxFileSize = MAX_FILE_SIZE_DEFAULT,
9045
9150
  containerClassName,
9046
- formClassName
9151
+ formClassName,
9152
+ reasoningEffortOptions,
9153
+ reasoningEffort,
9154
+ onReasoningEffortChange
9047
9155
  }, ref) => {
9048
9156
  const { t } = useTranslation();
9049
9157
  const [attachments, setAttachments] = useState([]);
@@ -9492,16 +9600,25 @@ var MessageInput = forwardRef(
9492
9600
  "aria-label": t("BiChat.Input.MessageInput")
9493
9601
  }
9494
9602
  ) }),
9603
+ reasoningEffortOptions && reasoningEffortOptions.length > 0 && onReasoningEffortChange && /* @__PURE__ */ jsx(
9604
+ ReasoningEffortSelector,
9605
+ {
9606
+ options: reasoningEffortOptions,
9607
+ value: reasoningEffort,
9608
+ onChange: onReasoningEffortChange,
9609
+ disabled: disabled || loading
9610
+ }
9611
+ ),
9495
9612
  isStreaming && onCancelStreaming ? /* @__PURE__ */ jsx(
9496
9613
  "button",
9497
9614
  {
9498
9615
  type: "button",
9499
9616
  onClick: onCancelStreaming,
9500
9617
  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",
9618
+ 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
9619
  "aria-label": t("BiChat.Common.Cancel"),
9503
9620
  title: t("BiChat.Common.Cancel"),
9504
- children: /* @__PURE__ */ jsx(X, { size: 18, weight: "bold" })
9621
+ children: /* @__PURE__ */ jsx(Stop, { size: 18, weight: "fill" })
9505
9622
  }
9506
9623
  ) : /* @__PURE__ */ jsx(
9507
9624
  "button",
@@ -11691,7 +11808,9 @@ function ChatSessionCore({
11691
11808
  debugLimits,
11692
11809
  currentSessionId,
11693
11810
  setError,
11694
- retryFetchSession
11811
+ retryFetchSession,
11812
+ reasoningEffort,
11813
+ setReasoningEffort
11695
11814
  } = useChatSession();
11696
11815
  const {
11697
11816
  turns,
@@ -11719,6 +11838,7 @@ function ChatSessionCore({
11719
11838
  const accessReadOnly = session?.access ? !session.access.canWrite : false;
11720
11839
  const effectiveReadOnly = Boolean(readOnly ?? isReadOnly) || isArchived || accessReadOnly;
11721
11840
  const [restoring, setRestoring] = useState(false);
11841
+ const [reasoningEffortOptions] = useState(() => readReasoningEffortOptionsFromGlobalContext());
11722
11842
  const handleRestore = useCallback(async () => {
11723
11843
  if (!session?.id) {
11724
11844
  return;
@@ -11986,7 +12106,10 @@ function ChatSessionCore({
11986
12106
  onUpdateQueueItem: updateQueueItem,
11987
12107
  onCancelStreaming: cancel,
11988
12108
  containerClassName: "pt-6 px-6",
11989
- formClassName: "mx-auto"
12109
+ formClassName: "mx-auto",
12110
+ reasoningEffortOptions,
12111
+ reasoningEffort,
12112
+ onReasoningEffortChange: setReasoningEffort
11990
12113
  }
11991
12114
  ),
11992
12115
  /* @__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 +12165,10 @@ function ChatSessionCore({
12042
12165
  onUnqueue: handleUnqueue,
12043
12166
  onRemoveQueueItem: removeQueueItem,
12044
12167
  onUpdateQueueItem: updateQueueItem,
12045
- onCancelStreaming: cancel
12168
+ onCancelStreaming: cancel,
12169
+ reasoningEffortOptions,
12170
+ reasoningEffort,
12171
+ onReasoningEffortChange: setReasoningEffort
12046
12172
  }
12047
12173
  )
12048
12174
  ] }) }),
@@ -18574,6 +18700,9 @@ async function* sendMessage(deps, sessionId, content, attachments = [], signal,
18574
18700
  replaceFromMessageId: options?.replaceFromMessageID,
18575
18701
  attachments: streamAttachments
18576
18702
  };
18703
+ if (options?.reasoningEffort) {
18704
+ payload.reasoningEffort = options.reasoningEffort;
18705
+ }
18577
18706
  const timeoutMs = deps.streamConnectTimeoutMs ?? 0;
18578
18707
  if (timeoutMs > 0) {
18579
18708
  connectionTimeoutID = setTimeout(() => {