@sensiblestats/widget-react 0.79.0 → 0.80.0
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/CHANGELOG.md +11 -0
- package/dist/index.cjs +130 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +124 -27
- package/dist/index.js.map +1 -1
- package/dist/styles.css +4 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -30,6 +30,9 @@ var STRINGS = {
|
|
|
30
30
|
dismissGreeting: "Dismiss",
|
|
31
31
|
somethingWentWrong: "Something went wrong.",
|
|
32
32
|
retry: "Retry",
|
|
33
|
+
limitDailyCap: "You've asked all your questions for today. You can ask again tomorrow.",
|
|
34
|
+
limitQuotaExhausted: "The assistant can't take new questions right now. Please try again later.",
|
|
35
|
+
limitAssistantPaused: "The assistant isn't available right now. Please try again later.",
|
|
33
36
|
showLess: "Show less",
|
|
34
37
|
showMore: (n) => `Show ${n} more`,
|
|
35
38
|
allMarkets: (n) => `All markets (${n})`,
|
|
@@ -379,6 +382,9 @@ var STRINGS = {
|
|
|
379
382
|
dismissGreeting: "Kapat",
|
|
380
383
|
somethingWentWrong: "Bir \u015Feyler ters gitti.",
|
|
381
384
|
retry: "Tekrar dene",
|
|
385
|
+
limitDailyCap: "Bug\xFCnl\xFCk sorular\u0131n\u0131 tamamlad\u0131n. Yar\u0131n yeniden sorabilirsin.",
|
|
386
|
+
limitQuotaExhausted: "Asistan \u015Fu an yeni soru alam\u0131yor. L\xFCtfen daha sonra tekrar dene.",
|
|
387
|
+
limitAssistantPaused: "Asistan \u015Fu an kullan\u0131lam\u0131yor. L\xFCtfen daha sonra tekrar dene.",
|
|
382
388
|
showLess: "Daha az g\xF6ster",
|
|
383
389
|
showMore: (n) => `${n} tane daha g\xF6ster`,
|
|
384
390
|
allMarkets: (n) => `T\xFCm bahisler (${n})`,
|
|
@@ -757,6 +763,9 @@ function normalizeUi(cfg) {
|
|
|
757
763
|
dismissGreeting: strings.dismissGreeting,
|
|
758
764
|
somethingWentWrong: strings.somethingWentWrong,
|
|
759
765
|
retry: strings.retry,
|
|
766
|
+
limitDailyCap: strings.limitDailyCap,
|
|
767
|
+
limitQuotaExhausted: strings.limitQuotaExhausted,
|
|
768
|
+
limitAssistantPaused: strings.limitAssistantPaused,
|
|
760
769
|
showLess: strings.showLess,
|
|
761
770
|
showMore: strings.showMore,
|
|
762
771
|
allMarkets: strings.allMarkets,
|
|
@@ -1704,6 +1713,51 @@ import { WidgetSdkError as WidgetSdkError2 } from "@sensiblestats/widget-sdk";
|
|
|
1704
1713
|
|
|
1705
1714
|
// src/reducer.ts
|
|
1706
1715
|
import "@sensiblestats/widget-sdk";
|
|
1716
|
+
|
|
1717
|
+
// src/limit.ts
|
|
1718
|
+
import { LimitError, isLimitCode } from "@sensiblestats/widget-sdk";
|
|
1719
|
+
var LIMIT_TIMER_MAX_MS = 60 * 60 * 1e3;
|
|
1720
|
+
var ZONED = /(?:Z|[+-]\d{2}:?\d{2})$/i;
|
|
1721
|
+
function build(code, message, resetsAt, retryAfterSeconds) {
|
|
1722
|
+
return {
|
|
1723
|
+
code,
|
|
1724
|
+
paused: code === "assistant_paused",
|
|
1725
|
+
message: message?.trim() || null,
|
|
1726
|
+
resetsAt: resetsAt ?? null,
|
|
1727
|
+
retryAfterSeconds: typeof retryAfterSeconds === "number" && Number.isFinite(retryAfterSeconds) ? retryAfterSeconds : null
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
function limitFromEvent(data) {
|
|
1731
|
+
return isLimitCode(data.code) ? build(data.code, data.message, data.resetsAt, data.retryAfterSeconds) : null;
|
|
1732
|
+
}
|
|
1733
|
+
function limitFromError(error) {
|
|
1734
|
+
return error instanceof LimitError ? build(error.limitCode, error.limitMessage, error.resetsAt, error.retryAfter) : null;
|
|
1735
|
+
}
|
|
1736
|
+
function isLimitNotice(data) {
|
|
1737
|
+
return data.terminal === false && isLimitCode(data.code);
|
|
1738
|
+
}
|
|
1739
|
+
function isPaused(limit) {
|
|
1740
|
+
return limit?.paused === true;
|
|
1741
|
+
}
|
|
1742
|
+
function limitText(limit, ui) {
|
|
1743
|
+
if (limit.message) return limit.message;
|
|
1744
|
+
switch (limit.code) {
|
|
1745
|
+
case "daily_cap":
|
|
1746
|
+
return ui.limitDailyCap;
|
|
1747
|
+
case "quota_exhausted":
|
|
1748
|
+
return ui.limitQuotaExhausted;
|
|
1749
|
+
case "assistant_paused":
|
|
1750
|
+
return ui.limitAssistantPaused;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
function limitDelayMs(limit, nowMs) {
|
|
1754
|
+
const retry = limit.retryAfterSeconds;
|
|
1755
|
+
if (retry != null && Number.isFinite(retry) && retry >= 0) return Math.min(retry * 1e3, LIMIT_TIMER_MAX_MS);
|
|
1756
|
+
const at = limit.resetsAt ? Date.parse(ZONED.test(limit.resetsAt) ? limit.resetsAt : `${limit.resetsAt}Z`) : Number.NaN;
|
|
1757
|
+
return Number.isNaN(at) ? null : Math.min(Math.max(at - nowMs, 0), LIMIT_TIMER_MAX_MS);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// src/reducer.ts
|
|
1707
1761
|
var POPUP_MAX = 160;
|
|
1708
1762
|
function markAwaitingLiveUpdate(messages, held = []) {
|
|
1709
1763
|
if (!messages.some((m) => m.role === "assistant" && m.marketOdds.some((vm) => vm.live != null))) return messages;
|
|
@@ -1721,12 +1775,18 @@ function markAwaitingLiveUpdate(messages, held = []) {
|
|
|
1721
1775
|
});
|
|
1722
1776
|
}
|
|
1723
1777
|
function initialState(starters) {
|
|
1724
|
-
return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, configuredStarters: starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null };
|
|
1778
|
+
return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, configuredStarters: starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null, limit: null };
|
|
1725
1779
|
}
|
|
1726
1780
|
function activeTurn(state) {
|
|
1727
1781
|
const last = state.messages[state.messages.length - 1];
|
|
1728
1782
|
return last && last.role === "assistant" && !last.done ? last : null;
|
|
1729
1783
|
}
|
|
1784
|
+
function settleRefused(state, limit) {
|
|
1785
|
+
return { ...state, limit, error: null, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1786
|
+
}
|
|
1787
|
+
function isPlainInput(input) {
|
|
1788
|
+
return !!input && !input.actionRef && !input.actionId && !input.grounding && !input.preset;
|
|
1789
|
+
}
|
|
1730
1790
|
function mapActive(state, fn) {
|
|
1731
1791
|
const last = state.messages[state.messages.length - 1];
|
|
1732
1792
|
if (!last || last.role !== "assistant" || last.done) return state.messages;
|
|
@@ -1766,6 +1826,7 @@ function applyEvent(state, event) {
|
|
|
1766
1826
|
case "turn_complete": {
|
|
1767
1827
|
const active = activeTurn(state);
|
|
1768
1828
|
const greetingLine = event.data.clubFanDashboard?.greeting?.trim() || (active?.text.trim() ?? "");
|
|
1829
|
+
const clearsLimit = !active?.isGreeting && isPlainInput(state.lastUserInput);
|
|
1769
1830
|
const popupText = active?.isGreeting && !state.isOpen && greetingLine ? greetingLine.slice(0, POPUP_MAX) : state.popupText;
|
|
1770
1831
|
return {
|
|
1771
1832
|
...state,
|
|
@@ -1773,6 +1834,7 @@ function applyEvent(state, event) {
|
|
|
1773
1834
|
status: null,
|
|
1774
1835
|
actionsLoading: false,
|
|
1775
1836
|
popupText,
|
|
1837
|
+
limit: clearsLimit ? null : state.limit,
|
|
1776
1838
|
conversationId: event.data.conversationId ?? state.conversationId,
|
|
1777
1839
|
messages: mapActive(state, (t) => ({
|
|
1778
1840
|
...t,
|
|
@@ -1783,6 +1845,9 @@ function applyEvent(state, event) {
|
|
|
1783
1845
|
};
|
|
1784
1846
|
}
|
|
1785
1847
|
case "error": {
|
|
1848
|
+
const limit = limitFromEvent(event.data);
|
|
1849
|
+
if (limit && event.data.terminal === false) return { ...state, limit };
|
|
1850
|
+
if (limit) return settleRefused(state, limit);
|
|
1786
1851
|
const suppress = activeTurn(state)?.isGreeting === true;
|
|
1787
1852
|
return { ...state, error: suppress ? state.error : event.data, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1788
1853
|
}
|
|
@@ -1807,7 +1872,7 @@ function reducer(state, action) {
|
|
|
1807
1872
|
case "DISMISS_POPUP":
|
|
1808
1873
|
return { ...state, popupText: null };
|
|
1809
1874
|
case "RESET":
|
|
1810
|
-
return { ...initialState(state.configuredStarters), isOpen: state.isOpen };
|
|
1875
|
+
return { ...initialState(state.configuredStarters), isOpen: state.isOpen, limit: state.limit };
|
|
1811
1876
|
case "RESTORE":
|
|
1812
1877
|
return {
|
|
1813
1878
|
...state,
|
|
@@ -1821,8 +1886,13 @@ function reducer(state, action) {
|
|
|
1821
1886
|
};
|
|
1822
1887
|
case "EVENT":
|
|
1823
1888
|
return applyEvent(state, action.event);
|
|
1824
|
-
case "STREAM_ERROR":
|
|
1889
|
+
case "STREAM_ERROR": {
|
|
1890
|
+
const limit = limitFromError(action.error);
|
|
1891
|
+
if (limit) return settleRefused(state, limit);
|
|
1825
1892
|
return { ...state, error: action.error, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1893
|
+
}
|
|
1894
|
+
case "LIMIT_EXPIRED":
|
|
1895
|
+
return { ...state, limit: null };
|
|
1826
1896
|
case "STOP":
|
|
1827
1897
|
return { ...state, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
1828
1898
|
case "UPDATE_LIVE_CARD": {
|
|
@@ -1995,7 +2065,7 @@ function clearConversation(storageKey) {
|
|
|
1995
2065
|
}
|
|
1996
2066
|
|
|
1997
2067
|
// src/presets.ts
|
|
1998
|
-
var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open"];
|
|
2068
|
+
var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open", "limit_notice"];
|
|
1999
2069
|
var PRICE_TILE_PREFIX = "goal-preset-";
|
|
2000
2070
|
function isPriceTile(tile) {
|
|
2001
2071
|
const id = tile.signal?.entityId;
|
|
@@ -2093,7 +2163,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2093
2163
|
try {
|
|
2094
2164
|
for await (const event of handle) {
|
|
2095
2165
|
dispatch({ kind: "EVENT", event });
|
|
2096
|
-
if (event.type === "turn_complete" || event.type === "error") clearFallbackTimer();
|
|
2166
|
+
if (event.type === "turn_complete" || event.type === "error" && !isLimitNotice(event.data)) clearFallbackTimer();
|
|
2097
2167
|
}
|
|
2098
2168
|
} catch (err) {
|
|
2099
2169
|
if (handleRef.current === handle) clearFallbackTimer();
|
|
@@ -2106,6 +2176,7 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2106
2176
|
})();
|
|
2107
2177
|
}, [clearFallbackTimer]);
|
|
2108
2178
|
const run = useCallback2((input, displayText) => {
|
|
2179
|
+
if (isPaused(stateRef.current.limit)) return;
|
|
2109
2180
|
handleRef.current?.cancel();
|
|
2110
2181
|
clearFallbackTimer();
|
|
2111
2182
|
dispatch({ kind: "USER_SENT", input, userId: nextId(), assistantId: nextId(), displayText });
|
|
@@ -2153,6 +2224,13 @@ function useChatStream(conversation, starterTexts, greetingMessage, storageKey)
|
|
|
2153
2224
|
greetedRef.current = true;
|
|
2154
2225
|
fireGreeting();
|
|
2155
2226
|
}, [fireGreeting]);
|
|
2227
|
+
useEffect3(() => {
|
|
2228
|
+
if (!state.limit) return;
|
|
2229
|
+
const delay = limitDelayMs(state.limit, Date.now());
|
|
2230
|
+
if (delay === null) return;
|
|
2231
|
+
const timer = setTimeout(() => dispatch({ kind: "LIMIT_EXPIRED" }), delay);
|
|
2232
|
+
return () => clearTimeout(timer);
|
|
2233
|
+
}, [state.limit]);
|
|
2156
2234
|
useEffect3(() => {
|
|
2157
2235
|
if (boot.stale && storageKey) clearConversation(storageKey);
|
|
2158
2236
|
}, []);
|
|
@@ -5343,7 +5421,7 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5343
5421
|
ChatMessage,
|
|
5344
5422
|
{
|
|
5345
5423
|
message: m,
|
|
5346
|
-
disabled: state.isStreaming,
|
|
5424
|
+
disabled: state.isStreaming || isPaused(state.limit),
|
|
5347
5425
|
onAct: (a) => send(a.message, { actionId: a.actionId, actionRef: a.actionRef, displayText: a.label }),
|
|
5348
5426
|
onTap: (tile, index) => {
|
|
5349
5427
|
const displayText = tileDisplayText(tile);
|
|
@@ -5363,7 +5441,7 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
5363
5441
|
/* @__PURE__ */ jsx48("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
5364
5442
|
/* @__PURE__ */ jsx48("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
5365
5443
|
] }) : null,
|
|
5366
|
-
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ jsx48(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
5444
|
+
!hasUserMessage && !hasDashboard && !isPaused(state.limit) ? /* @__PURE__ */ jsx48(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
5367
5445
|
/* @__PURE__ */ jsx48("div", { ref: endRef, className: "ss-w-turn-spacer", "aria-hidden": "true" })
|
|
5368
5446
|
]
|
|
5369
5447
|
}
|
|
@@ -9310,7 +9388,7 @@ function markToolSeen() {
|
|
|
9310
9388
|
}
|
|
9311
9389
|
|
|
9312
9390
|
// src/components/ChatPanel.tsx
|
|
9313
|
-
import { jsx as jsx95, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
9391
|
+
import { Fragment as Fragment23, jsx as jsx95, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
9314
9392
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
9315
9393
|
function useIsModal() {
|
|
9316
9394
|
const [modal, setModal] = useState44(false);
|
|
@@ -9336,6 +9414,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9336
9414
|
return () => window.removeEventListener("keydown", onKey);
|
|
9337
9415
|
}, [close]);
|
|
9338
9416
|
const handleSend = (text) => {
|
|
9417
|
+
typedSendRef.current = true;
|
|
9339
9418
|
monitor?.setActiveTab("chat");
|
|
9340
9419
|
send(text);
|
|
9341
9420
|
};
|
|
@@ -9351,6 +9430,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9351
9430
|
const dialRef = useRef22(null);
|
|
9352
9431
|
const dialButtonRef = useRef22(null);
|
|
9353
9432
|
const inputRef = useRef22(null);
|
|
9433
|
+
const limitRef = useRef22(null);
|
|
9434
|
+
const typedSendRef = useRef22(false);
|
|
9354
9435
|
const focusAfterCloseRef = useRef22(null);
|
|
9355
9436
|
const [tool, setTool] = useState44(null);
|
|
9356
9437
|
const [toolSeen, setToolSeen] = useState44(readToolSeen);
|
|
@@ -9363,7 +9444,16 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9363
9444
|
activeTab: monitor?.activeTab ?? "chat"
|
|
9364
9445
|
});
|
|
9365
9446
|
const { fold } = dial;
|
|
9366
|
-
const
|
|
9447
|
+
const paused = isPaused(state.limit);
|
|
9448
|
+
const showDial = !!presetGrid && onChatTab && !tool && !paused;
|
|
9449
|
+
useEffect26(() => {
|
|
9450
|
+
if (paused) setTool(null);
|
|
9451
|
+
}, [paused]);
|
|
9452
|
+
useEffect26(() => {
|
|
9453
|
+
if (!paused) return;
|
|
9454
|
+
if (typedSendRef.current) limitRef.current?.focus();
|
|
9455
|
+
typedSendRef.current = false;
|
|
9456
|
+
}, [paused]);
|
|
9367
9457
|
const openTool = useCallback15((next) => {
|
|
9368
9458
|
fold();
|
|
9369
9459
|
markToolSeen();
|
|
@@ -9372,8 +9462,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9372
9462
|
}, [fold]);
|
|
9373
9463
|
const onPill = useCallback15((kind) => openTool(kind === "numbers" ? { kind: "numbers" } : { kind: "combo" }), [openTool]);
|
|
9374
9464
|
const toolsValue = useMemo4(
|
|
9375
|
-
() => presetGrid ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
9376
|
-
[presetGrid, openTool, ui.presets.changeCombo]
|
|
9465
|
+
() => presetGrid && !paused ? { openBuilder: (total, legs) => openTool({ kind: "combo", total, legs }), changeLabel: ui.presets.changeCombo } : null,
|
|
9466
|
+
[presetGrid, paused, openTool, ui.presets.changeCombo]
|
|
9377
9467
|
);
|
|
9378
9468
|
const closeTool = useCallback15(() => {
|
|
9379
9469
|
focusAfterCloseRef.current = "dial";
|
|
@@ -9441,10 +9531,10 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9441
9531
|
buttonRef: dialButtonRef
|
|
9442
9532
|
}
|
|
9443
9533
|
) : null,
|
|
9444
|
-
tool && presetGrid && onChatTab ? tool.kind === "numbers" ? /* @__PURE__ */ jsx95(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx95(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
|
|
9534
|
+
tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ jsx95(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx95(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
|
|
9445
9535
|
] }),
|
|
9446
9536
|
monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx95(TodayPanel, { discovery, ui, monitor }),
|
|
9447
|
-
monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx95(MatchesPanel, { monitor, ui, slip, onAsk: handleAsk }),
|
|
9537
|
+
monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx95(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
|
|
9448
9538
|
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx95(OddsPanel, { monitor, ui, slip }),
|
|
9449
9539
|
monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx95(
|
|
9450
9540
|
GamesPanel,
|
|
@@ -9470,20 +9560,23 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
|
|
|
9470
9560
|
ui
|
|
9471
9561
|
}
|
|
9472
9562
|
),
|
|
9473
|
-
(!monitor || monitor.activeTab !== "games" && monitor.activeTab !== "leaderboard") && /* @__PURE__ */
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9486
|
-
|
|
9563
|
+
(!monitor || monitor.activeTab !== "games" && monitor.activeTab !== "leaderboard") && /* @__PURE__ */ jsxs80(Fragment23, { children: [
|
|
9564
|
+
/* @__PURE__ */ jsx95("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
|
|
9565
|
+
paused ? null : /* @__PURE__ */ jsx95(
|
|
9566
|
+
ChatInput,
|
|
9567
|
+
{
|
|
9568
|
+
ref: inputRef,
|
|
9569
|
+
placeholder: ui.placeholder,
|
|
9570
|
+
streaming: state.isStreaming,
|
|
9571
|
+
onSend: handleSend,
|
|
9572
|
+
onStop: stop,
|
|
9573
|
+
stopLabel: ui.stopResponse,
|
|
9574
|
+
sendLabel: ui.sendMessage,
|
|
9575
|
+
disabled: !!tool,
|
|
9576
|
+
onType: fold
|
|
9577
|
+
}
|
|
9578
|
+
)
|
|
9579
|
+
] })
|
|
9487
9580
|
] });
|
|
9488
9581
|
}
|
|
9489
9582
|
|
|
@@ -10081,6 +10174,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
10081
10174
|
|
|
10082
10175
|
/* input */
|
|
10083
10176
|
.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }
|
|
10177
|
+
.ss-w-limit { padding: 10px 12px; border-top: 1px solid var(--ss-w-line); font-size: 13px; line-height: 1.4; color: var(--ss-w-ink); overflow-wrap: anywhere; }
|
|
10178
|
+
.ss-w-limit:empty { padding: 0; border-top: 0; }
|
|
10179
|
+
.ss-w-limit:focus { outline: none; }
|
|
10180
|
+
.ss-w-limit:not(:empty) + .ss-w-input { border-top: none; }
|
|
10084
10181
|
.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }
|
|
10085
10182
|
.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }
|
|
10086
10183
|
/* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it
|