@meetsmore-oss/use-ai-client 1.12.1 → 1.13.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/dist/bundled.js CHANGED
@@ -1371,6 +1371,8 @@ var defaultStrings = {
1371
1371
  API_OVERLOADED: "The AI service is currently experiencing high demand. Please try again in a moment.",
1372
1372
  /** Error when rate limited */
1373
1373
  RATE_LIMITED: "Too many requests. Please wait a moment before trying again.",
1374
+ /** Error when the connection was lost while a response was being generated */
1375
+ CONNECTION_LOST: "The connection was lost. Please send your message again.",
1374
1376
  /** Error for unknown/unexpected errors */
1375
1377
  UNKNOWN_ERROR: "An unexpected error occurred. Please try again."
1376
1378
  },
@@ -1631,6 +1633,17 @@ function mergeAssistantMessagesForDisplay(messages) {
1631
1633
  return result;
1632
1634
  }
1633
1635
 
1636
+ // src/utils/keyboard.ts
1637
+ function shouldSubmitOnEnter(e, mode) {
1638
+ if (e.key !== "Enter" || e.nativeEvent.isComposing || e.keyCode === 229) {
1639
+ return false;
1640
+ }
1641
+ if (mode === "enter") {
1642
+ return !e.shiftKey;
1643
+ }
1644
+ return e.metaKey || e.ctrlKey;
1645
+ }
1646
+
1634
1647
  // ../../node_modules/.bun/react-markdown@8.0.7+32264e8fb3466d46/node_modules/react-markdown/lib/uri-transformer.js
1635
1648
  var protocols = ["http", "https", "mailto", "tel"];
1636
1649
  function uriTransformer(uri) {
@@ -14678,7 +14691,8 @@ function UseAIChatPanel({
14678
14691
  onFeedback,
14679
14692
  pendingApprovals = [],
14680
14693
  onApproveToolCall,
14681
- onRejectToolCall
14694
+ onRejectToolCall,
14695
+ submitMode = "enter"
14682
14696
  }) {
14683
14697
  const strings = useStrings();
14684
14698
  const theme = useTheme();
@@ -14753,7 +14767,7 @@ function UseAIChatPanel({
14753
14767
  if (slashCommands.handleKeyDown(e)) {
14754
14768
  return;
14755
14769
  }
14756
- if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && !(e.keyCode === 229)) {
14770
+ if (shouldSubmitOnEnter(e, submitMode)) {
14757
14771
  e.preventDefault();
14758
14772
  handleSend();
14759
14773
  }
@@ -15773,9 +15787,10 @@ function useChatUIContext() {
15773
15787
  }
15774
15788
  return context;
15775
15789
  }
15776
- function UseAIChat({ floating = false }) {
15790
+ function UseAIChat({ floating = false, submitMode }) {
15777
15791
  const ctx = useChatUIContext();
15778
15792
  const chatPanelProps = {
15793
+ submitMode: submitMode ?? ctx.submitMode,
15779
15794
  onSendMessage: ctx.sendMessage,
15780
15795
  messages: ctx.messages,
15781
15796
  loading: ctx.loading,
@@ -23647,6 +23662,7 @@ var ErrorCode;
23647
23662
  ((ErrorCode2) => {
23648
23663
  ErrorCode2["API_OVERLOADED"] = "API_OVERLOADED";
23649
23664
  ErrorCode2["RATE_LIMITED"] = "RATE_LIMITED";
23665
+ ErrorCode2["CONNECTION_LOST"] = "CONNECTION_LOST";
23650
23666
  ErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
23651
23667
  })(ErrorCode ||= {});
23652
23668
  var TOOL_APPROVAL_REQUEST = "TOOL_APPROVAL_REQUEST";
@@ -23663,9 +23679,12 @@ var UseAIClient = class {
23663
23679
  }
23664
23680
  socket = null;
23665
23681
  eventHandlers = /* @__PURE__ */ new Map();
23666
- reconnectAttempts = 0;
23667
- maxReconnectAttempts = 5;
23682
+ // Reconnect indefinitely so clients recover after extended outages (mobile
23683
+ // app backgrounded long enough for server pingTimeout, airplane mode, etc.).
23684
+ // Socket.IO applies exponential backoff capped at reconnectionDelayMax,
23685
+ // so steady-state retry frequency is ~one attempt per 10s.
23668
23686
  reconnectDelay = 1e3;
23687
+ reconnectDelayMax = 1e4;
23669
23688
  // Session state
23670
23689
  _threadId = null;
23671
23690
  _tools = [];
@@ -23703,14 +23722,14 @@ var UseAIClient = class {
23703
23722
  this.socket = lookup2(this.serverUrl, {
23704
23723
  transports: ["polling", "websocket"],
23705
23724
  reconnection: true,
23706
- reconnectionAttempts: this.maxReconnectAttempts,
23725
+ reconnectionAttempts: Infinity,
23707
23726
  reconnectionDelay: this.reconnectDelay,
23727
+ reconnectionDelayMax: this.reconnectDelayMax,
23708
23728
  withCredentials: true
23709
23729
  });
23710
23730
  this.socket.on("connect", () => {
23711
23731
  console.log("[UseAI] Connected to server");
23712
23732
  console.log("[UseAI] Transport:", this.socket?.io?.engine?.transport?.name);
23713
- this.reconnectAttempts = 0;
23714
23733
  const engine = this.socket?.io?.engine;
23715
23734
  if (engine) {
23716
23735
  engine.on("upgrade", (transport) => {
@@ -39298,6 +39317,8 @@ function useServerEvents({
39298
39317
  const [streamingText, setStreamingText] = useState13("");
39299
39318
  const [streamingReasoning, setStreamingReasoning] = useState13("");
39300
39319
  const streamingChatIdRef = useRef10(null);
39320
+ const loadingRef = useRef10(loading);
39321
+ loadingRef.current = loading;
39301
39322
  const messageCountAtRunStartRef = useRef10(0);
39302
39323
  const hasTextFromPriorStepRef = useRef10(false);
39303
39324
  const [executingToolRaw, setExecutingTool] = useState13(null);
@@ -39393,6 +39414,17 @@ function useServerEvents({
39393
39414
  setLoading(false);
39394
39415
  }
39395
39416
  }, []);
39417
+ const handleDisconnect = useCallback11(() => {
39418
+ if (!loadingRef.current) return;
39419
+ const strs = stringsRef.current;
39420
+ const message = strs.errors[ErrorCode.CONNECTION_LOST] || strs.errors[ErrorCode.UNKNOWN_ERROR];
39421
+ saveAIResponseRef.current(message, "error");
39422
+ setStreamingText("");
39423
+ setStreamingReasoning("");
39424
+ streamingChatIdRef.current = null;
39425
+ setExecutingTool(null);
39426
+ setLoading(false);
39427
+ }, []);
39396
39428
  const executingTool = executingToolRaw ? {
39397
39429
  displayText: executingToolRaw.title ?? executingToolFallbackRef.current ?? strings.toolExecution.fallbackMessages[0]
39398
39430
  } : null;
@@ -39404,7 +39436,8 @@ function useServerEvents({
39404
39436
  executingTool,
39405
39437
  streamingChatIdRef,
39406
39438
  streamingReasoning,
39407
- handleServerEvent
39439
+ handleServerEvent,
39440
+ handleDisconnect
39408
39441
  };
39409
39442
  }
39410
39443
 
@@ -39570,7 +39603,8 @@ function UseAIProvider({
39570
39603
  theme: customTheme,
39571
39604
  strings: customStrings,
39572
39605
  visibleAgentIds,
39573
- onOpenChange
39606
+ onOpenChange,
39607
+ submitMode = "enter"
39574
39608
  }) {
39575
39609
  const fileUploadConfig = fileUploadConfigProp === false ? void 0 : fileUploadConfigProp ?? DEFAULT_FILE_UPLOAD_CONFIG;
39576
39610
  const theme = { ...defaultTheme, ...customTheme };
@@ -39629,12 +39663,17 @@ function UseAIProvider({
39629
39663
  } = useCommandManagement({ repository: commandRepository });
39630
39664
  const handleServerEventRef = useRef12(serverEvents.handleServerEvent);
39631
39665
  handleServerEventRef.current = serverEvents.handleServerEvent;
39666
+ const handleDisconnectRef = useRef12(serverEvents.handleDisconnect);
39667
+ handleDisconnectRef.current = serverEvents.handleDisconnect;
39632
39668
  useEffect11(() => {
39633
39669
  console.log("[UseAIProvider] Initializing client with serverUrl:", serverUrl);
39634
39670
  const client = new UseAIClient(serverUrl);
39635
39671
  const unsubscribeConnection = client.onConnectionStateChange((isConnected) => {
39636
39672
  console.log("[UseAIProvider] Connection state changed:", isConnected);
39637
39673
  setConnected(isConnected);
39674
+ if (!isConnected) {
39675
+ handleDisconnectRef.current();
39676
+ }
39638
39677
  });
39639
39678
  console.log("[UseAIProvider] Connecting...");
39640
39679
  client.connect();
@@ -39822,7 +39861,8 @@ function UseAIProvider({
39822
39861
  feedback: {
39823
39862
  enabled: feedback.enabled,
39824
39863
  submit: feedback.submitFeedback
39825
- }
39864
+ },
39865
+ submitMode
39826
39866
  };
39827
39867
  const isUIDisabled = CustomButton === null || CustomChat === null;
39828
39868
  const ButtonComponent = isUIDisabled ? null : CustomButton || UseAIFloatingButton;
@@ -39855,7 +39895,8 @@ function UseAIProvider({
39855
39895
  onFeedback: feedback.submitFeedback,
39856
39896
  pendingApprovals: toolSystem.pendingApprovals,
39857
39897
  onApproveToolCall: toolSystem.pendingApprovals.length > 0 ? toolSystem.approveAll : void 0,
39858
- onRejectToolCall: toolSystem.pendingApprovals.length > 0 ? toolSystem.rejectAll : void 0
39898
+ onRejectToolCall: toolSystem.pendingApprovals.length > 0 ? toolSystem.rejectAll : void 0,
39899
+ submitMode
39859
39900
  };
39860
39901
  const renderDefaultChat = () => {
39861
39902
  if (isUIDisabled) return null;