@iota-uz/sdk 0.4.26 → 0.4.28

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.
package/README.md CHANGED
@@ -81,9 +81,11 @@ applet secrets delete --name <applet> --key OPENAI_API_KEY
81
81
 
82
82
  ### Release flow
83
83
 
84
- 1. Publish SDK changes from `applets/` (bump `applets/package.json` version and release).
85
- 2. Upgrade consumers (`eai/back`, applet web packages, etc.) to the published version.
86
- 3. Commit only version upgrades in consumer repos; never commit local-link overrides.
84
+ 1. Publish SDK changes from `applets/` (bump `applets/package.json` version).
85
+ 2. Create and push a tag `iota-sdk-v<version>` where `<version>` exactly matches
86
+ `applets/package.json`. This triggers `publish-npm.yml`.
87
+ 3. Upgrade consumers (`eai/back`, applet web packages, etc.) to the published version.
88
+ 4. Commit only version upgrades in consumer repos; never commit local-link overrides.
87
89
 
88
90
  ---
89
91
 
@@ -1830,7 +1830,11 @@ function readReasoningEffortOptionsFromGlobalContext() {
1830
1830
  if (!Array.isArray(opts) || opts.length === 0) {
1831
1831
  return void 0;
1832
1832
  }
1833
- return opts.filter((o) => typeof o === "string");
1833
+ const filtered = opts.filter((o) => typeof o === "string");
1834
+ if (filtered.length === 0) {
1835
+ return void 0;
1836
+ }
1837
+ return filtered;
1834
1838
  }
1835
1839
 
1836
1840
  // ui/src/bichat/machine/selectors.ts
@@ -1849,6 +1853,7 @@ function deriveSessionSnapshot(state, methods) {
1849
1853
  sessionDebugUsage: getSessionDebugUsage(state.messaging.turns),
1850
1854
  debugLimits: state.session.debugLimits,
1851
1855
  reasoningEffort: state.session.reasoningEffort,
1856
+ reasoningEffortOptions: state.session.reasoningEffortOptions,
1852
1857
  setError: methods.setError,
1853
1858
  retryFetchSession: methods.retryFetchSession,
1854
1859
  setReasoningEffort: methods.setReasoningEffort
@@ -1903,6 +1908,50 @@ function deriveInputSnapshot(state, methods) {
1903
1908
  };
1904
1909
  }
1905
1910
 
1911
+ // ui/src/bichat/utils/assistantTurnState.ts
1912
+ function isEmptyAssistantTurn(turn) {
1913
+ if (turn.content.trim().length > 0) {
1914
+ return false;
1915
+ }
1916
+ if ((turn.explanation?.trim().length ?? 0) > 0) {
1917
+ return false;
1918
+ }
1919
+ if ((turn.citations?.length ?? 0) > 0) {
1920
+ return false;
1921
+ }
1922
+ if ((turn.toolCalls?.length ?? 0) > 0) {
1923
+ return false;
1924
+ }
1925
+ if ((turn.charts?.length ?? 0) > 0) {
1926
+ return false;
1927
+ }
1928
+ if ((turn.renderTables?.length ?? 0) > 0) {
1929
+ return false;
1930
+ }
1931
+ if ((turn.artifacts?.length ?? 0) > 0) {
1932
+ return false;
1933
+ }
1934
+ if ((turn.codeOutputs?.length ?? 0) > 0) {
1935
+ return false;
1936
+ }
1937
+ if (turn.debug) {
1938
+ return false;
1939
+ }
1940
+ return true;
1941
+ }
1942
+ function isPlaceholderWaitingAssistantTurn(turn) {
1943
+ return turn.lifecycle === "waiting_for_human_input" && isEmptyAssistantTurn(turn);
1944
+ }
1945
+ function shouldRenderInlineRetry(turn, canRegenerate) {
1946
+ if (!canRegenerate) {
1947
+ return false;
1948
+ }
1949
+ if (turn.lifecycle === "waiting_for_human_input") {
1950
+ return false;
1951
+ }
1952
+ return isEmptyAssistantTurn(turn);
1953
+ }
1954
+
1906
1955
  // ui/src/bichat/machine/hitlLifecycle.ts
1907
1956
  function normalizeQuestionType(rawType) {
1908
1957
  const normalized = String(rawType || "").trim().toUpperCase().replace(/[\s-]+/g, "_");
@@ -1982,6 +2031,13 @@ function applyTurnLifecycleForPendingQuestion(turns, pendingQuestion) {
1982
2031
  }
1983
2032
  };
1984
2033
  }
2034
+ if (!shouldWaitForInput && isPlaceholderWaitingAssistantTurn(turn.assistantTurn)) {
2035
+ changed = true;
2036
+ return {
2037
+ ...turn,
2038
+ assistantTurn: void 0
2039
+ };
2040
+ }
1985
2041
  if (turn.assistantTurn.lifecycle === desiredLifecycle) {
1986
2042
  return turn;
1987
2043
  }
@@ -2042,6 +2098,7 @@ var ChatMachine = class {
2042
2098
  this.fetchCancelled = false;
2043
2099
  this.disposed = false;
2044
2100
  this.reasoningEffortOptions = null;
2101
+ this.reasoningEffortOptionSet = null;
2045
2102
  /** Memoized sessionDebugUsage — avoids unnecessary session re-renders during streaming. */
2046
2103
  this.lastSessionDebugUsage = null;
2047
2104
  /** Interval handle for passive polling when another tab has an active stream. */
@@ -2129,6 +2186,7 @@ var ChatMachine = class {
2129
2186
  this.rateLimiter = config.rateLimiter;
2130
2187
  this.onSessionCreated = config.onSessionCreated;
2131
2188
  this.reasoningEffortOptions = this.buildReasoningEffortOptions();
2189
+ this.reasoningEffortOptionSet = this.reasoningEffortOptions ? new Set(this.reasoningEffortOptions) : null;
2132
2190
  const initialReasoningEffort = this.sanitizeReasoningEffort(loadReasoningEffort() || void 0);
2133
2191
  if (!initialReasoningEffort) {
2134
2192
  clearReasoningEffort();
@@ -2142,7 +2200,8 @@ var ChatMachine = class {
2142
2200
  errorRetryable: false,
2143
2201
  debugModeBySession: {},
2144
2202
  debugLimits: readDebugLimitsFromGlobalContext(),
2145
- reasoningEffort: initialReasoningEffort
2203
+ reasoningEffort: initialReasoningEffort,
2204
+ reasoningEffortOptions: this.reasoningEffortOptions ?? void 0
2146
2205
  },
2147
2206
  messaging: {
2148
2207
  turns: [],
@@ -2191,14 +2250,14 @@ var ChatMachine = class {
2191
2250
  if (!options || options.length === 0) {
2192
2251
  return null;
2193
2252
  }
2194
- return new Set(options);
2253
+ return options;
2195
2254
  }
2196
2255
  // Keep outbound payloads constrained to server-declared options.
2197
2256
  sanitizeReasoningEffort(effort) {
2198
- if (!effort || !this.reasoningEffortOptions || this.reasoningEffortOptions.size === 0) {
2257
+ if (!effort || !this.reasoningEffortOptionSet || this.reasoningEffortOptionSet.size === 0) {
2199
2258
  return void 0;
2200
2259
  }
2201
- return this.reasoningEffortOptions.has(effort) ? effort : void 0;
2260
+ return this.reasoningEffortOptionSet.has(effort) ? effort : void 0;
2202
2261
  }
2203
2262
  // =====================================================================
2204
2263
  // Lifecycle
@@ -4429,7 +4488,7 @@ init_useTranslation();
4429
4488
  var COPY_FEEDBACK_MS = 2e3;
4430
4489
  var defaultClassNames = {
4431
4490
  root: "flex gap-3 justify-end group",
4432
- wrapper: "flex-1 flex flex-col items-end max-w-[var(--bichat-bubble-max-width)]",
4491
+ wrapper: "flex-1 min-w-0 flex flex-col items-end max-w-[var(--bichat-bubble-max-width)]",
4433
4492
  avatar: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-sm",
4434
4493
  bubble: "bg-primary-600 text-white rounded-2xl rounded-br-sm px-4 py-3 shadow-sm",
4435
4494
  content: "text-sm whitespace-pre-wrap break-words leading-relaxed",
@@ -5993,6 +6052,7 @@ function FullscreenOverlay({ title, onClose, closeLabel, children }) {
5993
6052
  )
5994
6053
  ] });
5995
6054
  }
6055
+ var FULL_WIDTH_CLASS = "w-full min-w-0 max-w-full";
5996
6056
  function getPageNumbers(current, total) {
5997
6057
  if (total <= 7) {
5998
6058
  return Array.from({ length: total }, (_, i) => i + 1);
@@ -6087,6 +6147,8 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6087
6147
  const hasHiddenColumns = dt.columns.some((c) => !c.visible);
6088
6148
  const from = dt.totalFilteredRows === 0 ? 0 : (dt.page - 1) * dt.pageSize + 1;
6089
6149
  const to = Math.min(dt.page * dt.pageSize, dt.totalFilteredRows);
6150
+ const loadedRowsCount = table.rows.length;
6151
+ const reportedRowsCount = Math.max(table.totalRows || 0, loadedRowsCount);
6090
6152
  const renderToolbar = () => /* @__PURE__ */ jsxRuntime.jsx(
6091
6153
  DataTableToolbar,
6092
6154
  {
@@ -6107,9 +6169,12 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6107
6169
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
6108
6170
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate text-sm font-semibold text-gray-900 dark:text-gray-100", children: table.title || t("BiChat.Table.QueryResults") }),
6109
6171
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
6110
- dt.totalFilteredRows === table.rows.length ? dt.totalFilteredRows === 1 ? t("BiChat.Table.OneRowLoaded") : t("BiChat.Table.RowsLoaded", { count: String(dt.totalFilteredRows) }) : t("BiChat.DataTable.FilteredRows", {
6172
+ dt.totalFilteredRows === loadedRowsCount ? loadedRowsCount === reportedRowsCount ? loadedRowsCount === 1 ? t("BiChat.Table.OneRowLoaded") : t("BiChat.Table.RowsLoaded", { count: String(loadedRowsCount) }) : t("BiChat.DataTable.FilteredRows", {
6173
+ filtered: String(loadedRowsCount),
6174
+ total: String(reportedRowsCount)
6175
+ }) : t("BiChat.DataTable.FilteredRows", {
6111
6176
  filtered: String(dt.totalFilteredRows),
6112
- total: String(table.rows.length)
6177
+ total: String(loadedRowsCount)
6113
6178
  }),
6114
6179
  table.truncated ? ` ${t("BiChat.Table.TruncatedSuffix")}` : ""
6115
6180
  ] })
@@ -6124,7 +6189,7 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6124
6189
  }
6125
6190
  )
6126
6191
  ] });
6127
- const renderTable = (scrollClass) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: scrollClass, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full border-collapse text-sm", children: [
6192
+ const renderTable = (scrollClass) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${FULL_WIDTH_CLASS} ${scrollClass}`, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full border-collapse text-sm", children: [
6128
6193
  /* @__PURE__ */ jsxRuntime.jsx(
6129
6194
  DataTableHeader,
6130
6195
  {
@@ -6265,7 +6330,7 @@ var InteractiveTableCard = React.memo(function InteractiveTableCard2({
6265
6330
  ] });
6266
6331
  const renderTruncationNotice = () => table.truncated ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "border-t border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-700 dark:border-amber-700/60 dark:bg-amber-900/20 dark:text-amber-300", children: t("BiChat.Table.TruncatedNotice") }) : null;
6267
6332
  const fillHeight = host?.isFullscreen ?? false;
6268
- const sectionClassName = host ? `w-full min-w-0 overflow-hidden${fillHeight ? " flex flex-col flex-1" : ""}` : "w-full min-w-0 rounded-xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/40 overflow-hidden";
6333
+ const sectionClassName = host ? `${FULL_WIDTH_CLASS} overflow-hidden${fillHeight ? " flex flex-col flex-1" : ""}` : `${FULL_WIDTH_CLASS} rounded-xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/40 overflow-hidden`;
6269
6334
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6270
6335
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: sectionClassName, children: [
6271
6336
  renderToolbar(),
@@ -6418,7 +6483,7 @@ var TabbedTableGroup = React.memo(function TabbedTableGroup2({
6418
6483
  const tabs = React.useMemo(
6419
6484
  () => tables.map((table, i) => ({
6420
6485
  id: table.id,
6421
- label: `${table.title || `${t("BiChat.Table.QueryResults")} ${i + 1}`} (${table.rows.length})`
6486
+ label: `${table.title || `${t("BiChat.Table.QueryResults")} ${i + 1}`} (${Math.max(table.totalRows || 0, table.rows.length)})`
6422
6487
  })),
6423
6488
  [tables, t]
6424
6489
  );
@@ -7165,21 +7230,15 @@ function calculateContextUsagePercent(promptTokens, effectiveMaxTokens) {
7165
7230
  }
7166
7231
  return promptTokens / effectiveMaxTokens * 100;
7167
7232
  }
7168
- function CopyPill({ text }) {
7233
+ function useCopyFeedback() {
7169
7234
  const [copied, setCopied] = React.useState(false);
7170
7235
  const timerRef = React.useRef(null);
7171
- React.useEffect(() => () => {
7172
- if (timerRef.current !== null) {
7173
- clearTimeout(timerRef.current);
7174
- }
7175
- }, []);
7176
- const handleCopy = async (e) => {
7177
- e.stopPropagation();
7236
+ const copy = React.useCallback(async (text) => {
7178
7237
  try {
7179
7238
  await navigator.clipboard.writeText(text);
7180
7239
  setCopied(true);
7181
7240
  if (timerRef.current !== null) {
7182
- clearTimeout(timerRef.current);
7241
+ window.clearTimeout(timerRef.current);
7183
7242
  }
7184
7243
  timerRef.current = window.setTimeout(() => {
7185
7244
  setCopied(false);
@@ -7188,6 +7247,19 @@ function CopyPill({ text }) {
7188
7247
  } catch (err) {
7189
7248
  console.error("Copy failed:", err);
7190
7249
  }
7250
+ }, []);
7251
+ React.useEffect(() => () => {
7252
+ if (timerRef.current !== null) {
7253
+ window.clearTimeout(timerRef.current);
7254
+ }
7255
+ }, []);
7256
+ return { copied, copy };
7257
+ }
7258
+ function CopyPill({ text }) {
7259
+ const { copied, copy } = useCopyFeedback();
7260
+ const handleCopy = async (e) => {
7261
+ e.stopPropagation();
7262
+ await copy(text);
7191
7263
  };
7192
7264
  return /* @__PURE__ */ jsxRuntime.jsxs(
7193
7265
  "button",
@@ -7206,28 +7278,10 @@ function CopyPill({ text }) {
7206
7278
  );
7207
7279
  }
7208
7280
  function InlineCopyButton({ text }) {
7209
- const [copied, setCopied] = React.useState(false);
7210
- const timerRef = React.useRef(null);
7211
- React.useEffect(() => () => {
7212
- if (timerRef.current !== null) {
7213
- clearTimeout(timerRef.current);
7214
- }
7215
- }, []);
7281
+ const { copied, copy } = useCopyFeedback();
7216
7282
  const handleCopy = async (e) => {
7217
7283
  e.stopPropagation();
7218
- try {
7219
- await navigator.clipboard.writeText(text);
7220
- setCopied(true);
7221
- if (timerRef.current !== null) {
7222
- clearTimeout(timerRef.current);
7223
- }
7224
- timerRef.current = window.setTimeout(() => {
7225
- setCopied(false);
7226
- timerRef.current = null;
7227
- }, 2e3);
7228
- } catch (err) {
7229
- console.error("Copy failed:", err);
7230
- }
7284
+ await copy(text);
7231
7285
  };
7232
7286
  return /* @__PURE__ */ jsxRuntime.jsx(
7233
7287
  "button",
@@ -7492,8 +7546,8 @@ var MarkdownRenderer2 = React.lazy(
7492
7546
  );
7493
7547
  var COPY_FEEDBACK_MS2 = 2e3;
7494
7548
  var defaultClassNames2 = {
7495
- root: "flex gap-3 group",
7496
- wrapper: "flex-1 min-w-0 flex flex-col gap-3 max-w-[var(--bichat-bubble-assistant-max-width,85%)]",
7549
+ root: "flex min-w-0 gap-3 group",
7550
+ wrapper: "flex-1 w-full min-w-0 flex flex-col gap-3 max-w-[var(--bichat-bubble-assistant-max-width,85%)]",
7497
7551
  avatar: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-xs",
7498
7552
  bubble: "bg-white dark:bg-gray-800 rounded-2xl rounded-bl-sm px-4 py-3 shadow-sm",
7499
7553
  codeOutputs: "",
@@ -7571,8 +7625,8 @@ function AssistantMessage({
7571
7625
  const hasDebug = showDebug && !!turn.debug;
7572
7626
  const hasAnyRenderedContent = hasContent || hasExplanation || hasCodeOutputs || hasChart || hasTables || hasArtifacts || hasDebug;
7573
7627
  const canRegenerate = !!onRegenerate && !!turnId && !isSystemMessage && isLastTurn;
7574
- const renderMode = hasPendingQuestion ? "hitl_form" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : canRegenerate ? "retry" : "empty";
7575
- const showInlineRetry = renderMode === "retry";
7628
+ const showInlineRetry = shouldRenderInlineRetry(turn, canRegenerate) && !hasAnyRenderedContent;
7629
+ const renderMode = hasPendingQuestion ? "hitl_form" : isAwaitingHumanInput ? "hitl_waiting" : hasAnyRenderedContent ? "content" : showInlineRetry ? "retry" : "empty";
7576
7630
  const handleCopyClick = React.useCallback(async () => {
7577
7631
  try {
7578
7632
  if (onCopy) {
@@ -7964,7 +8018,7 @@ function AssistantTurnView({
7964
8018
  );
7965
8019
  }
7966
8020
  var defaultClassNames3 = {
7967
- root: "space-y-4",
8021
+ root: "space-y-4 min-w-0",
7968
8022
  userTurn: "",
7969
8023
  assistantTurn: ""
7970
8024
  };
@@ -8797,9 +8851,9 @@ function MessageListSkeleton() {
8797
8851
  ] });
8798
8852
  }
8799
8853
  function StreamingBubble({ content, normalizedContent }) {
8800
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
8854
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 gap-3", children: [
8801
8855
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center text-white font-medium text-xs", children: "AI" }),
8802
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-2xl rounded-bl-sm px-4 py-3 text-gray-900 dark:text-gray-100", style: { maxWidth: "var(--bichat-bubble-assistant-max-width, 85%)" }, children: [
8856
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-2xl rounded-bl-sm px-4 py-3 text-gray-900 dark:text-gray-100", style: { maxWidth: "var(--bichat-bubble-assistant-max-width, 85%)" }, children: [
8803
8857
  /* @__PURE__ */ jsxRuntime.jsx(
8804
8858
  React.Suspense,
8805
8859
  {
@@ -8830,8 +8884,8 @@ function MessageList({ renderUserTurn, renderAssistantTurn, thinkingVerbs, readO
8830
8884
  );
8831
8885
  const showAuthorNames = Boolean(session?.isGroup);
8832
8886
  const showEphemeral = showActivityTrace || showTypingIndicator;
8833
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-h-0", children: [
8834
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full overflow-y-auto overflow-x-hidden px-4 py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto space-y-6", children: [
8887
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0 min-h-0", children: [
8888
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full overflow-y-auto overflow-x-hidden px-4 py-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full min-w-0 space-y-6", children: [
8835
8889
  fetching && turns.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(MessageListSkeleton, {}),
8836
8890
  turns.map((turn, index) => {
8837
8891
  const turnDate = new Date(turn.createdAt);
@@ -9490,6 +9544,16 @@ var MessageInput = React.forwardRef(
9490
9544
  const canSubmit = !disabled && (message.trim() || attachments.length > 0);
9491
9545
  const visibleError = error || commandError;
9492
9546
  const visibleErrorText = visibleError ? t(visibleError) : "";
9547
+ const resolvedReasoningEffort = reasoningEffortOptions && reasoningEffortOptions.length > 0 ? reasoningEffortOptions.includes(reasoningEffort ?? "") ? reasoningEffort : reasoningEffortOptions[1] || reasoningEffortOptions[0] : void 0;
9548
+ React.useEffect(() => {
9549
+ if (!onReasoningEffortChange || !reasoningEffortOptions?.length) {
9550
+ return;
9551
+ }
9552
+ if (!resolvedReasoningEffort || resolvedReasoningEffort === reasoningEffort) {
9553
+ return;
9554
+ }
9555
+ onReasoningEffortChange(resolvedReasoningEffort);
9556
+ }, [reasoningEffort, onReasoningEffortChange, reasoningEffortOptions, resolvedReasoningEffort]);
9493
9557
  const defaultContainerClassName = "shrink-0 px-4 pt-4 pb-6";
9494
9558
  return /* @__PURE__ */ jsxRuntime.jsx(
9495
9559
  "div",
@@ -9616,7 +9680,7 @@ var MessageInput = React.forwardRef(
9616
9680
  ReasoningEffortSelector,
9617
9681
  {
9618
9682
  options: reasoningEffortOptions,
9619
- value: reasoningEffort,
9683
+ value: resolvedReasoningEffort,
9620
9684
  onChange: onReasoningEffortChange,
9621
9685
  disabled: disabled || loading
9622
9686
  }
@@ -10233,6 +10297,14 @@ function readString(value) {
10233
10297
  return trimmed.length > 0 ? trimmed : null;
10234
10298
  }
10235
10299
  function readPositiveInteger(value) {
10300
+ if (typeof value === "string") {
10301
+ const trimmed = value.trim();
10302
+ if (!/^\d+$/.test(trimmed)) {
10303
+ return null;
10304
+ }
10305
+ const parsed = Number(trimmed);
10306
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
10307
+ }
10236
10308
  if (typeof value !== "number" || !Number.isFinite(value)) {
10237
10309
  return null;
10238
10310
  }
@@ -10283,7 +10355,7 @@ function parseRenderTableDataFromObject(parsed, fallbackId) {
10283
10355
  const headers = headersRaw.length === columns.length ? headersRaw : columns;
10284
10356
  const columnTypesRaw = Array.isArray(parsed.column_types) ? parsed.column_types : Array.isArray(parsed.columnTypes) ? parsed.columnTypes : [];
10285
10357
  const columnTypes = columnTypesRaw.length === columns.length ? columnTypesRaw.map((t) => readString(t) || "string") : void 0;
10286
- const totalRows = readPositiveInteger(parsed.total_rows) || readPositiveInteger(parsed.totalRows) || rows.length;
10358
+ const totalRows = readPositiveInteger(parsed.total_rows) || readPositiveInteger(parsed.totalRows) || readPositiveInteger(parsed.row_count) || readPositiveInteger(parsed.rowCount) || rows.length;
10287
10359
  const pageSize = readPositiveInteger(parsed.page_size) || readPositiveInteger(parsed.pageSize) || 25;
10288
10360
  const query = readString(parsed.query) || readString(parsed.sql);
10289
10361
  if (!query) {
@@ -11822,7 +11894,8 @@ function ChatSessionCore({
11822
11894
  setError,
11823
11895
  retryFetchSession,
11824
11896
  reasoningEffort,
11825
- setReasoningEffort
11897
+ setReasoningEffort,
11898
+ reasoningEffortOptions
11826
11899
  } = useChatSession();
11827
11900
  const {
11828
11901
  turns,
@@ -11850,7 +11923,6 @@ function ChatSessionCore({
11850
11923
  const accessReadOnly = session?.access ? !session.access.canWrite : false;
11851
11924
  const effectiveReadOnly = Boolean(readOnly ?? isReadOnly) || isArchived || accessReadOnly;
11852
11925
  const [restoring, setRestoring] = React.useState(false);
11853
- const [reasoningEffortOptions] = React.useState(() => readReasoningEffortOptionsFromGlobalContext());
11854
11926
  const handleRestore = React.useCallback(async () => {
11855
11927
  if (!session?.id) {
11856
11928
  return;
@@ -12057,7 +12129,7 @@ function ChatSessionCore({
12057
12129
  return /* @__PURE__ */ jsxRuntime.jsxs(
12058
12130
  "main",
12059
12131
  {
12060
- className: `flex min-h-0 flex-1 flex-col overflow-hidden bg-gray-50 dark:bg-gray-900 ${className}`,
12132
+ className: `flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden bg-gray-50 dark:bg-gray-900 ${className}`,
12061
12133
  children: [
12062
12134
  headerSlot || /* @__PURE__ */ jsxRuntime.jsx(
12063
12135
  ChatHeader,
@@ -14564,10 +14636,14 @@ function Sidebar2({
14564
14636
  sessions: Array.isArray(group.sessions) ? group.sessions : []
14565
14637
  })) : [];
14566
14638
  }, [unpinnedSessions, t]);
14639
+ const orderedUnpinnedSessions = React.useMemo(
14640
+ () => sessionGroups.flatMap((group) => group.sessions),
14641
+ [sessionGroups]
14642
+ );
14567
14643
  const collapsedIndicators = React.useMemo(() => {
14568
14644
  const seen = /* @__PURE__ */ new Set();
14569
14645
  const result = [];
14570
- for (const s of [...pinnedSessions, ...unpinnedSessions]) {
14646
+ for (const s of [...pinnedSessions, ...orderedUnpinnedSessions]) {
14571
14647
  if (seen.has(s.id)) {
14572
14648
  continue;
14573
14649
  }
@@ -14578,7 +14654,7 @@ function Sidebar2({
14578
14654
  }
14579
14655
  }
14580
14656
  return result;
14581
- }, [pinnedSessions, unpinnedSessions]);
14657
+ }, [pinnedSessions, orderedUnpinnedSessions]);
14582
14658
  const totalSessionCount = filteredSessions.length;
14583
14659
  const overflowCount = Math.max(0, totalSessionCount - collapsedIndicators.length);
14584
14660
  const handleSessionListKeyDown = React.useCallback(
@@ -15399,7 +15475,7 @@ function BiChatLayout({
15399
15475
  const content = routeKey ? /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", initial: false, children: /* @__PURE__ */ jsxRuntime.jsx(
15400
15476
  framerMotion.motion.div,
15401
15477
  {
15402
- className: "flex flex-1 min-h-0",
15478
+ className: "flex flex-1 min-w-0 min-h-0",
15403
15479
  initial: { opacity: 0, y: 4 },
15404
15480
  animate: { opacity: 1, y: 0 },
15405
15481
  exit: { opacity: 0, y: -4 },
@@ -15407,7 +15483,7 @@ function BiChatLayout({
15407
15483
  children
15408
15484
  },
15409
15485
  routeKey
15410
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 min-h-0", children });
15486
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 min-w-0 min-h-0", children });
15411
15487
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex flex-1 w-full h-full min-h-0 overflow-hidden ${className}`, children: [
15412
15488
  /* @__PURE__ */ jsxRuntime.jsx(SkipLink, {}),
15413
15489
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block", children: renderSidebar({}) }),
@@ -15443,7 +15519,7 @@ function BiChatLayout({
15443
15519
  "sidebar-drawer"
15444
15520
  )
15445
15521
  ] }) }),
15446
- /* @__PURE__ */ jsxRuntime.jsxs("main", { id: "main-content", className: "relative flex-1 flex flex-col min-h-0 overflow-hidden", children: [
15522
+ /* @__PURE__ */ jsxRuntime.jsxs("main", { id: "main-content", className: "relative flex-1 min-w-0 flex flex-col min-h-0 overflow-hidden", children: [
15447
15523
  isMobile && !isMobileOpen && /* @__PURE__ */ jsxRuntime.jsx(
15448
15524
  "button",
15449
15525
  {
@@ -17855,13 +17931,17 @@ function parseRowCount(metadata) {
17855
17931
  if (!metadata) {
17856
17932
  return void 0;
17857
17933
  }
17858
- const raw = metadata.row_count ?? metadata.rowCount;
17859
- if (typeof raw === "number" && Number.isFinite(raw)) {
17934
+ const raw = metadata.row_count ?? metadata.rowCount ?? metadata.total_rows ?? metadata.totalRows;
17935
+ if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 0) {
17860
17936
  return raw;
17861
17937
  }
17862
17938
  if (typeof raw === "string") {
17863
- const parsed = Number.parseInt(raw, 10);
17864
- if (Number.isFinite(parsed)) {
17939
+ const trimmed = raw.trim();
17940
+ if (!/^\d+$/.test(trimmed)) {
17941
+ return void 0;
17942
+ }
17943
+ const parsed = Number(trimmed);
17944
+ if (Number.isSafeInteger(parsed)) {
17865
17945
  return parsed;
17866
17946
  }
17867
17947
  }