@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.2 → 0.4.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA6B/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA25FlD,CAAC"}
1
+ {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA8B/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAO/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAo8FlD,CAAC"}
@@ -5,7 +5,8 @@ import * as React from 'react';
5
5
  import { flushSync } from 'react-dom';
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
  import { createNxtlinqApi, setApiHosts, synthesizeSpeechToBuffer, streamSpeechToAudioContext, useLocalStorage, useSessionStorage, useSpeechToTextFromMic, useVoiceMode, metakeepClient, getEthers, sleep, walletTextUtils, } from '@bytexbyte/nxtlinq-ai-agent-web-development';
8
- import { authorizeTextFrontendTool, hasRecordedWalletVerification, } from '@bytexbyte/nxtlinq-ai-agent-core-development';
8
+ import { authorizeTextFrontendTool, hasRecordedWalletVerification, validateWalletSession, } from '@bytexbyte/nxtlinq-ai-agent-core-development';
9
+ import { PendingTextToolRetryController } from '../pendingTextToolRetry';
9
10
  const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
10
11
  const ChatBotContext = React.createContext(undefined);
11
12
  export const useChatBot = () => {
@@ -144,6 +145,17 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
144
145
  const permissionsRef = React.useRef(permissions);
145
146
  const nxtlinqAITServiceAccessTokenRef = React.useRef(nxtlinqAITServiceAccessToken);
146
147
  const signerRef = React.useRef(signer);
148
+ const pendingTextToolRetryRef = React.useRef(new PendingTextToolRetryController());
149
+ const sendMessageRef = React.useRef(async () => { });
150
+ const retryPendingTextTool = React.useCallback(() => {
151
+ const controller = pendingTextToolRetryRef.current;
152
+ return controller.retry(async (request) => {
153
+ // This attempt consumes the old request. A still-blocked preflight will
154
+ // record it again with the next required recovery step.
155
+ controller.clear();
156
+ await sendMessageRef.current(request.content, 1, request.isPresetMessage, request.attachments);
157
+ });
158
+ }, []);
147
159
  // Helper function to combine customUsername with Adilas customUserInfo
148
160
  const getFinalCustomUsername = React.useCallback((username) => {
149
161
  if (!username)
@@ -860,7 +872,9 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
860
872
  };
861
873
  // Refresh AIT
862
874
  const refreshAIT = async (forceUpdatePermissions = false) => {
863
- if (!hitAddress) {
875
+ const currentHitAddress = hitAddressRef.current || hitAddress;
876
+ const currentToken = nxtlinqAITServiceAccessTokenRef.current || nxtlinqAITServiceAccessToken;
877
+ if (!currentHitAddress) {
864
878
  setAit(null);
865
879
  setPermissions([]);
866
880
  setWalletInfo(null);
@@ -871,9 +885,9 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
871
885
  try {
872
886
  let walletAllowsAITLookup = !requireWalletIDVVerification;
873
887
  // Get wallet info first - always try to get wallet info if we have a token
874
- if (nxtlinqAITServiceAccessToken) {
888
+ if (currentToken) {
875
889
  try {
876
- const walletResponse = await nxtlinqApi.wallet.getWallet({ address: hitAddress }, nxtlinqAITServiceAccessToken);
890
+ const walletResponse = await nxtlinqApi.wallet.getWallet({ address: currentHitAddress }, currentToken);
877
891
  if (!('error' in walletResponse)) {
878
892
  setWalletInfo(walletResponse);
879
893
  walletAllowsAITLookup = !requireWalletIDVVerification
@@ -895,18 +909,18 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
895
909
  }
896
910
  // AIT existence is not identity verification. In strict mode, stop before
897
911
  // the legacy AIT lookup can synthesize a custom wallet record.
898
- if (nxtlinqAITServiceAccessToken && !walletAllowsAITLookup) {
912
+ if (currentToken && !walletAllowsAITLookup) {
899
913
  setAit(null);
900
914
  setPermissions([]);
901
915
  return;
902
916
  }
903
917
  // Only try to fetch AIT if we have a token
904
- if (nxtlinqAITServiceAccessToken) {
918
+ if (currentToken) {
905
919
  const response = await nxtlinqApi.ait.getAITByServiceIdAndController({
906
920
  serviceId,
907
- controller: hitAddress,
921
+ controller: currentHitAddress,
908
922
  customUsername: (!requireWalletIDVVerification && customUsername) ? getFinalCustomUsername(customUsername) : undefined
909
- }, nxtlinqAITServiceAccessToken);
923
+ }, currentToken);
910
924
  if ('error' in response) {
911
925
  console.error('Failed to fetch AIT:', response.error);
912
926
  setAit(null);
@@ -940,17 +954,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
940
954
  return false;
941
955
  if (!nxtlinqAITServiceAccessToken)
942
956
  return true;
943
- try {
944
- const payload = JSON.parse(atob(nxtlinqAITServiceAccessToken.split('.')[1]));
945
- const address = payload.address;
946
- if (address !== hitAddress)
947
- return true;
948
- return false;
949
- }
950
- catch (error) {
951
- console.error('Error parsing token:', error);
952
- return true;
953
- }
957
+ return !validateWalletSession(nxtlinqAITServiceAccessToken, hitAddress).valid;
954
958
  }, [hitAddress, nxtlinqAITServiceAccessToken]);
955
959
  // Connect wallet
956
960
  const connectWallet = React.useCallback(async (autoShowSignInMessage = true) => {
@@ -1080,14 +1084,19 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1080
1084
  if (autoShowSuccessMessage) {
1081
1085
  showError(walletTextUtils.getWalletText('Please connect your wallet first.', serviceId));
1082
1086
  }
1083
- return;
1087
+ return false;
1084
1088
  }
1085
1089
  if (!signerToUse) {
1086
1090
  console.log('No signer available, returning early');
1087
1091
  if (autoShowSuccessMessage) {
1088
1092
  showError(walletTextUtils.getWalletText('Please connect your wallet first.', serviceId));
1089
1093
  }
1090
- return;
1094
+ return false;
1095
+ }
1096
+ const currentToken = nxtlinqAITServiceAccessTokenRef.current;
1097
+ if (currentToken && validateWalletSession(currentToken, addressToUse).valid) {
1098
+ await refreshAIT();
1099
+ return true;
1091
1100
  }
1092
1101
  try {
1093
1102
  const nonceResponse = await nxtlinqApi.auth.getNonce({ address: addressToUse });
@@ -1095,7 +1104,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1095
1104
  if (autoShowSuccessMessage) {
1096
1105
  showError(normalizeErrorForUser(nonceResponse.error));
1097
1106
  }
1098
- return;
1107
+ return false;
1099
1108
  }
1100
1109
  const payload = {
1101
1110
  address: addressToUse,
@@ -1112,22 +1121,25 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1112
1121
  if (autoShowSuccessMessage) {
1113
1122
  showError(normalizeErrorForUser(response.error));
1114
1123
  }
1115
- return;
1124
+ return false;
1116
1125
  }
1117
1126
  const { accessToken } = response;
1118
1127
  setNxtlinqAITServiceAccessToken(accessToken);
1128
+ nxtlinqAITServiceAccessTokenRef.current = accessToken;
1119
1129
  // Wait for state to update before refreshing AIT
1120
1130
  await new Promise(resolve => setTimeout(resolve, 100));
1121
1131
  await refreshAIT();
1122
1132
  if (autoShowSuccessMessage) {
1123
1133
  showSuccess(walletTextUtils.getWalletText('Successfully signed in with your HIT wallet. You can now use the AI agent.', serviceId));
1124
1134
  }
1135
+ return true;
1125
1136
  }
1126
1137
  catch (error) {
1127
1138
  console.error('Failed to sign in:', error);
1128
1139
  if (autoShowSuccessMessage) {
1129
1140
  showError('Failed to sign in. Please try again.');
1130
1141
  }
1142
+ return false;
1131
1143
  }
1132
1144
  };
1133
1145
  // Check permissions
@@ -1178,6 +1190,8 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1178
1190
  case 'wallet_verification_required':
1179
1191
  recovery.content = 'Please verify your wallet identity before using this tool.';
1180
1192
  recovery.button = 'verifyWallet';
1193
+ setIsPermissionFormOpen(true);
1194
+ setShowPermissionForm(true);
1181
1195
  break;
1182
1196
  case 'ait_not_found':
1183
1197
  recovery.content = 'No AIT found for your wallet. Please open settings to configure your AIT.';
@@ -1230,8 +1244,14 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1230
1244
  // Updated sendMessage function to support different AI models and attachments
1231
1245
  const sendMessage = async (content, retryCount = 0, isPresetMessage = false, attachments, clientPipelineOverride) => {
1232
1246
  const hasContent = content.trim() || (attachments && attachments.length > 0);
1233
- if (!hasContent || isLoading)
1247
+ // Recovery retries may run immediately after a completion handler calls
1248
+ // setIsLoading(false), before React has committed that state update.
1249
+ if (!hasContent || (retryCount === 0 && isLoading))
1234
1250
  return;
1251
+ if (retryCount === 0) {
1252
+ // A new user turn supersedes any older interrupted tool request.
1253
+ pendingTextToolRetryRef.current.clear();
1254
+ }
1235
1255
  setPendingAutoTts(null);
1236
1256
  const turnExternalId = typeof window !== 'undefined'
1237
1257
  ? localStorage.getItem('walletAddress') || undefined
@@ -1524,9 +1544,17 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1524
1544
  const isToolAllowed = await hasPermission(toolUse.name);
1525
1545
  // Typed preflight already emitted the only permitted recovery UI.
1526
1546
  if (!isToolAllowed) {
1547
+ pendingTextToolRetryRef.current.set({
1548
+ content,
1549
+ isPresetMessage,
1550
+ attachments,
1551
+ });
1527
1552
  setIsLoading(false);
1528
1553
  return;
1529
1554
  }
1555
+ // Authorization passed. Clear before invoking the host callback so
1556
+ // concurrent completion events cannot execute this tool twice.
1557
+ pendingTextToolRetryRef.current.clear();
1530
1558
  // Create streaming message for tool execution
1531
1559
  const streamingMessageId = `streaming-${Date.now()}`;
1532
1560
  const streamingMessage = {
@@ -1819,6 +1847,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
1819
1847
  setIsLoading(false);
1820
1848
  }
1821
1849
  };
1850
+ sendMessageRef.current = sendMessage;
1822
1851
  // Handle submit
1823
1852
  const handleSubmit = async (e, attachments) => {
1824
1853
  e.preventDefault();
@@ -2308,6 +2337,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2308
2337
  setShowPermissionForm(false);
2309
2338
  setIsPermissionFormOpen(false);
2310
2339
  await refreshAIT(true);
2340
+ await retryPendingTextTool();
2311
2341
  }
2312
2342
  catch (error) {
2313
2343
  console.error('Failed to generate AIT:', error);
@@ -2386,7 +2416,8 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2386
2416
  }
2387
2417
  setIsLoading(false);
2388
2418
  showSuccess(walletTextUtils.getWalletText('Wallet verification completed successfully! Your wallet is now verified and ready to use.', serviceId));
2389
- refreshAIT();
2419
+ await refreshAIT();
2420
+ await retryPendingTextTool();
2390
2421
  return;
2391
2422
  }
2392
2423
  showError(verifyWalletResponse.error);
@@ -2426,7 +2457,8 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2426
2457
  }
2427
2458
  setIsLoading(false);
2428
2459
  showSuccess('Wallet verification completed successfully! Your wallet is now verified and ready to use.');
2429
- refreshAIT();
2460
+ await refreshAIT();
2461
+ await retryPendingTextTool();
2430
2462
  return;
2431
2463
  }
2432
2464
  catch (error) {
@@ -2466,6 +2498,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2466
2498
  await refreshAIT();
2467
2499
  setIsLoading(false);
2468
2500
  showSuccess(walletTextUtils.getWalletText('Wallet verification completed successfully! Your wallet is now verified and ready to use.', serviceId));
2501
+ await retryPendingTextTool();
2469
2502
  return;
2470
2503
  }
2471
2504
  // Handle specific error messages
@@ -2482,6 +2515,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2482
2515
  await refreshAIT();
2483
2516
  setIsLoading(false);
2484
2517
  showSuccess(walletTextUtils.getWalletText('Wallet verification completed successfully! Your wallet is now verified and ready to use.', serviceId));
2518
+ await retryPendingTextTool();
2485
2519
  return;
2486
2520
  }
2487
2521
  catch (error) {
@@ -2650,6 +2684,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2650
2684
  // Functions
2651
2685
  connectWallet,
2652
2686
  signInWallet,
2687
+ retryPendingTextTool,
2653
2688
  sendMessage,
2654
2689
  handleSubmit,
2655
2690
  handlePresetMessage,
@@ -0,0 +1,16 @@
1
+ import type { Attachment } from '@bytexbyte/nxtlinq-ai-agent-core-development';
2
+ export type PendingTextToolRequest = {
3
+ content: string;
4
+ isPresetMessage: boolean;
5
+ attachments?: Attachment[];
6
+ };
7
+ /** Keeps one interrupted text-tool request and serializes all resume attempts. */
8
+ export declare class PendingTextToolRetryController {
9
+ private pending;
10
+ private inFlight;
11
+ set(request: PendingTextToolRequest): void;
12
+ clear(): void;
13
+ hasPending(): boolean;
14
+ retry(execute: (request: PendingTextToolRequest) => Promise<void>): Promise<boolean>;
15
+ }
16
+ //# sourceMappingURL=pendingTextToolRetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pendingTextToolRetry.d.ts","sourceRoot":"","sources":["../src/pendingTextToolRetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,CAAC;AAEF,kFAAkF;AAClF,qBAAa,8BAA8B;IACzC,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,QAAQ,CAAiC;IAEjD,GAAG,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAI1C,KAAK,IAAI,IAAI;IAIb,UAAU,IAAI,OAAO;IAIrB,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAarF"}
@@ -0,0 +1,30 @@
1
+ /** Keeps one interrupted text-tool request and serializes all resume attempts. */
2
+ export class PendingTextToolRetryController {
3
+ constructor() {
4
+ this.pending = null;
5
+ this.inFlight = null;
6
+ }
7
+ set(request) {
8
+ this.pending = request;
9
+ }
10
+ clear() {
11
+ this.pending = null;
12
+ }
13
+ hasPending() {
14
+ return this.pending !== null;
15
+ }
16
+ retry(execute) {
17
+ if (this.inFlight)
18
+ return this.inFlight;
19
+ if (!this.pending)
20
+ return Promise.resolve(false);
21
+ const request = this.pending;
22
+ this.inFlight = (async () => {
23
+ await execute(request);
24
+ return true;
25
+ })().finally(() => {
26
+ this.inFlight = null;
27
+ });
28
+ return this.inFlight;
29
+ }
30
+ }
@@ -134,8 +134,9 @@ export interface ChatBotContextType {
134
134
  setAutoSendEnabled: (enabled: boolean) => void;
135
135
  setTextToSpeechEnabled: (enabled: boolean) => void;
136
136
  connectWallet: (autoShowSignInMessage?: boolean) => Promise<string | false | undefined>;
137
- signInWallet: (autoShowSuccessMessage?: boolean) => Promise<void>;
138
- sendMessage: (content: string, retryCount?: number) => Promise<void>;
137
+ signInWallet: (autoShowSuccessMessage?: boolean) => Promise<boolean>;
138
+ retryPendingTextTool: () => Promise<boolean>;
139
+ sendMessage: (content: string, retryCount?: number, isPresetMessage?: boolean, attachments?: Attachment[]) => Promise<void>;
139
140
  handleSubmit: (e: React.FormEvent, attachments?: Attachment[]) => Promise<void>;
140
141
  handlePresetMessage: (message: PresetMessage) => void;
141
142
  savePermissions: (newPermissions?: string[]) => Promise<void>;
@@ -165,7 +166,7 @@ export interface ChatBotContextType {
165
166
  interruptVoice: () => void;
166
167
  onSave: (newPermissions?: string[]) => Promise<void>;
167
168
  onConnectWallet: () => Promise<string | false | undefined>;
168
- onSignIn: () => Promise<void>;
169
+ onSignIn: () => Promise<boolean>;
169
170
  isNeedSignInWithWallet: boolean;
170
171
  onVerifyWallet: (method: 'berifyme' | 'custom') => Promise<void>;
171
172
  serviceId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ChatBotTypes.d.ts","sourceRoot":"","sources":["../../src/types/ChatBotTypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatBotTypes.d.ts","sourceRoot":"","sources":["../../src/types/ChatBotTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAErI,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,CACV,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,KAAK,IAAI,KACP,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC;QAC7B,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,SAAS,CAAC,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC,WAAW,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAAC;IAElD,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC,YAAY,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,eAAe,CAAC,EAAE;QAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sGAAsG;IACtG,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IAEjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oBAAoB,EAAE,iBAAiB,EAAE,CAAC;IAC1C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE;QACZ,IAAI,EAAE,OAAO,CAAC;QACd,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;QAC/C,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAChD,eAAe,EAAE,OAAO,CAAC;IAEzB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,eAAe,EAAE,OAAO,EAAE,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,aAAa,EAAE,CAAC;IAG7B,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC;IAErC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IAGvB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,qBAAqB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,uBAAuB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAChD,aAAa,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,eAAe,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,CAAC;IAE7C,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACvD,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,aAAa,EAAE,CAAC,qBAAqB,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC;IACxF,YAAY,EAAE,CAAC,sBAAsB,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,oBAAoB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5H,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IACtD,eAAe,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,uBAAuB,EAAE,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,EAAE,CAAC,sBAAsB,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAE3B,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,eAAe,EAAE,MAAM,OAAO,CAAC;IAE/B,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,IAAI,CAAC;IAG3B,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC;IAC3D,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,EAAE,OAAO,CAAC;IAChC,cAAc,EAAE,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/ui/MessageList.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuT/B,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAyc/B,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/ui/MessageList.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuT/B,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EA4c/B,CAAC"}
@@ -231,7 +231,7 @@ const PiiStatusHeader = React.memo(({ message }) => {
231
231
  return (_jsxs("div", { css: piiHeaderRow, children: [_jsx(ShieldIcon, {}), _jsx("span", { children: "\u2713 Protected" })] }));
232
232
  });
233
233
  export const MessageList = () => {
234
- const { messages, isLoading, isTtsProcessing, requiresGesture, retryTtsWithGesture, connectWallet, signInWallet, hitAddress, isAutoConnecting, isNeedSignInWithWallet, enableAIT, isAITLoading, isAITEnabling, sendMessage, permissions, availableModels, serviceId, piiDisplayMode, setShowPermissionForm, setIsPermissionFormOpen, } = useChatBot();
234
+ const { messages, isLoading, isTtsProcessing, requiresGesture, retryTtsWithGesture, connectWallet, signInWallet, retryPendingTextTool, hitAddress, isAutoConnecting, isNeedSignInWithWallet, enableAIT, isAITLoading, isAITEnabling, sendMessage, permissions, availableModels, serviceId, piiDisplayMode, setShowPermissionForm, setIsPermissionFormOpen, } = useChatBot();
235
235
  const messagesEndRef = React.useRef(null);
236
236
  const scrollToBottom = () => {
237
237
  messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
@@ -247,22 +247,26 @@ export const MessageList = () => {
247
247
  return;
248
248
  }
249
249
  if (buttonType === 'connectWallet') {
250
- connectWallet(true);
250
+ const connected = await connectWallet(false);
251
+ if (connected) {
252
+ // Continue the interrupted flow immediately. This opens the wallet
253
+ // signature UI instead of leaving the user on a stale connect prompt.
254
+ const signedIn = await signInWallet(true);
255
+ if (signedIn)
256
+ await retryPendingTextTool();
257
+ }
251
258
  }
252
259
  else if (buttonType === 'signIn') {
253
- signInWallet(true);
260
+ const signedIn = await signInWallet(true);
261
+ if (signedIn)
262
+ await retryPendingTextTool();
254
263
  }
255
264
  else if (buttonType === 'enableAIT') {
256
265
  const requiredPermission = message.metadata?.requiredPermission;
257
266
  if (requiredPermission) {
258
267
  const success = await enableAIT(requiredPermission);
259
268
  if (success) {
260
- // Find the last user message
261
- const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
262
- if (lastUserMsg && lastUserMsg.content) {
263
- // Re-execute the previous user message (retryCount=1 to skip duplicate PII log)
264
- await sendMessage(lastUserMsg.content, 1);
265
- }
269
+ await retryPendingTextTool();
266
270
  }
267
271
  }
268
272
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytexbyte/nxtlinq-ai-agent-ui-react-development",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Official React Web UI for nxtlinq AI Agent — drop-in chat widget",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,6 +28,7 @@ import type {
28
28
  import {
29
29
  authorizeTextFrontendTool,
30
30
  hasRecordedWalletVerification,
31
+ validateWalletSession,
31
32
  } from '@bytexbyte/nxtlinq-ai-agent-core-development';
32
33
  import {
33
34
  AIModel,
@@ -35,6 +36,7 @@ import {
35
36
  ChatBotProps,
36
37
  PresetMessage
37
38
  } from '../types/ChatBotTypes';
39
+ import { PendingTextToolRetryController } from '../pendingTextToolRetry';
38
40
 
39
41
  const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
40
42
 
@@ -216,6 +218,22 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
216
218
  const permissionsRef = React.useRef(permissions);
217
219
  const nxtlinqAITServiceAccessTokenRef = React.useRef(nxtlinqAITServiceAccessToken);
218
220
  const signerRef = React.useRef(signer);
221
+ const pendingTextToolRetryRef = React.useRef(new PendingTextToolRetryController());
222
+ const sendMessageRef = React.useRef<ChatBotContextType['sendMessage']>(async () => {});
223
+ const retryPendingTextTool = React.useCallback(() => {
224
+ const controller = pendingTextToolRetryRef.current;
225
+ return controller.retry(async (request) => {
226
+ // This attempt consumes the old request. A still-blocked preflight will
227
+ // record it again with the next required recovery step.
228
+ controller.clear();
229
+ await sendMessageRef.current(
230
+ request.content,
231
+ 1,
232
+ request.isPresetMessage,
233
+ request.attachments,
234
+ );
235
+ });
236
+ }, []);
219
237
 
220
238
  // Helper function to combine customUsername with Adilas customUserInfo
221
239
  const getFinalCustomUsername = React.useCallback((username: string | undefined): string | undefined => {
@@ -1000,7 +1018,9 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1000
1018
 
1001
1019
  // Refresh AIT
1002
1020
  const refreshAIT = async (forceUpdatePermissions = false) => {
1003
- if (!hitAddress) {
1021
+ const currentHitAddress = hitAddressRef.current || hitAddress;
1022
+ const currentToken = nxtlinqAITServiceAccessTokenRef.current || nxtlinqAITServiceAccessToken;
1023
+ if (!currentHitAddress) {
1004
1024
  setAit(null);
1005
1025
  setPermissions([]);
1006
1026
  setWalletInfo(null);
@@ -1013,9 +1033,9 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1013
1033
  let walletAllowsAITLookup = !requireWalletIDVVerification;
1014
1034
 
1015
1035
  // Get wallet info first - always try to get wallet info if we have a token
1016
- if (nxtlinqAITServiceAccessToken) {
1036
+ if (currentToken) {
1017
1037
  try {
1018
- const walletResponse = await nxtlinqApi.wallet.getWallet({ address: hitAddress }, nxtlinqAITServiceAccessToken);
1038
+ const walletResponse = await nxtlinqApi.wallet.getWallet({ address: currentHitAddress }, currentToken);
1019
1039
  if (!('error' in walletResponse)) {
1020
1040
  setWalletInfo(walletResponse);
1021
1041
  walletAllowsAITLookup = !requireWalletIDVVerification
@@ -1036,19 +1056,19 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1036
1056
 
1037
1057
  // AIT existence is not identity verification. In strict mode, stop before
1038
1058
  // the legacy AIT lookup can synthesize a custom wallet record.
1039
- if (nxtlinqAITServiceAccessToken && !walletAllowsAITLookup) {
1059
+ if (currentToken && !walletAllowsAITLookup) {
1040
1060
  setAit(null);
1041
1061
  setPermissions([]);
1042
1062
  return;
1043
1063
  }
1044
1064
 
1045
1065
  // Only try to fetch AIT if we have a token
1046
- if (nxtlinqAITServiceAccessToken) {
1066
+ if (currentToken) {
1047
1067
  const response = await nxtlinqApi.ait.getAITByServiceIdAndController({
1048
1068
  serviceId,
1049
- controller: hitAddress,
1069
+ controller: currentHitAddress,
1050
1070
  customUsername: (!requireWalletIDVVerification && customUsername) ? getFinalCustomUsername(customUsername) : undefined
1051
- }, nxtlinqAITServiceAccessToken);
1071
+ }, currentToken);
1052
1072
 
1053
1073
  if ('error' in response) {
1054
1074
  console.error('Failed to fetch AIT:', response.error);
@@ -1080,17 +1100,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1080
1100
  const isNeedSignInWithWallet = React.useMemo(() => {
1081
1101
  if (!hitAddress) return false;
1082
1102
  if (!nxtlinqAITServiceAccessToken) return true;
1083
-
1084
- try {
1085
- const payload = JSON.parse(atob(nxtlinqAITServiceAccessToken.split('.')[1]));
1086
- const address = payload.address;
1087
- if (address !== hitAddress) return true;
1088
-
1089
- return false;
1090
- } catch (error) {
1091
- console.error('Error parsing token:', error);
1092
- return true;
1093
- }
1103
+ return !validateWalletSession(nxtlinqAITServiceAccessToken, hitAddress).valid;
1094
1104
  }, [hitAddress, nxtlinqAITServiceAccessToken]);
1095
1105
 
1096
1106
  // Connect wallet
@@ -1200,7 +1210,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1200
1210
  }
1201
1211
  }, [nxtlinqAITServiceAccessToken, refreshAIT, isNeedSignInWithWallet, requireWalletIDVVerification, customUsername, nxtlinqApi]);
1202
1212
 
1203
- const signInWallet = async (autoShowSuccessMessage = true) => {
1213
+ const signInWallet = async (autoShowSuccessMessage = true): Promise<boolean> => {
1204
1214
  // Use refs to get latest state values for consistency with hasPermission
1205
1215
  const currentHitAddress = hitAddressRef.current;
1206
1216
  const currentSigner = signerRef.current;
@@ -1233,7 +1243,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1233
1243
  if (autoShowSuccessMessage) {
1234
1244
  showError(walletTextUtils.getWalletText('Please connect your wallet first.', serviceId));
1235
1245
  }
1236
- return;
1246
+ return false;
1237
1247
  }
1238
1248
 
1239
1249
  if (!signerToUse) {
@@ -1241,7 +1251,13 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1241
1251
  if (autoShowSuccessMessage) {
1242
1252
  showError(walletTextUtils.getWalletText('Please connect your wallet first.', serviceId));
1243
1253
  }
1244
- return;
1254
+ return false;
1255
+ }
1256
+
1257
+ const currentToken = nxtlinqAITServiceAccessTokenRef.current;
1258
+ if (currentToken && validateWalletSession(currentToken, addressToUse).valid) {
1259
+ await refreshAIT();
1260
+ return true;
1245
1261
  }
1246
1262
 
1247
1263
  try {
@@ -1250,7 +1266,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1250
1266
  if (autoShowSuccessMessage) {
1251
1267
  showError(normalizeErrorForUser(nonceResponse.error));
1252
1268
  }
1253
- return;
1269
+ return false;
1254
1270
  }
1255
1271
 
1256
1272
  const payload = {
@@ -1271,10 +1287,11 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1271
1287
  if (autoShowSuccessMessage) {
1272
1288
  showError(normalizeErrorForUser(response.error));
1273
1289
  }
1274
- return;
1290
+ return false;
1275
1291
  }
1276
1292
  const { accessToken } = response;
1277
1293
  setNxtlinqAITServiceAccessToken(accessToken);
1294
+ nxtlinqAITServiceAccessTokenRef.current = accessToken;
1278
1295
 
1279
1296
  // Wait for state to update before refreshing AIT
1280
1297
  await new Promise(resolve => setTimeout(resolve, 100));
@@ -1283,11 +1300,13 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1283
1300
  if (autoShowSuccessMessage) {
1284
1301
  showSuccess(walletTextUtils.getWalletText('Successfully signed in with your HIT wallet. You can now use the AI agent.', serviceId));
1285
1302
  }
1303
+ return true;
1286
1304
  } catch (error) {
1287
1305
  console.error('Failed to sign in:', error);
1288
1306
  if (autoShowSuccessMessage) {
1289
1307
  showError('Failed to sign in. Please try again.');
1290
1308
  }
1309
+ return false;
1291
1310
  }
1292
1311
  };
1293
1312
 
@@ -1342,6 +1361,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1342
1361
  case 'wallet_verification_required':
1343
1362
  recovery.content = 'Please verify your wallet identity before using this tool.';
1344
1363
  recovery.button = 'verifyWallet';
1364
+ setIsPermissionFormOpen(true);
1365
+ setShowPermissionForm(true);
1345
1366
  break;
1346
1367
  case 'ait_not_found':
1347
1368
  recovery.content = 'No AIT found for your wallet. Please open settings to configure your AIT.';
@@ -1409,7 +1430,13 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1409
1430
  clientPipelineOverride?: Array<{ name: string; durationMs: number }>
1410
1431
  ): Promise<void> => {
1411
1432
  const hasContent = content.trim() || (attachments && attachments.length > 0);
1412
- if (!hasContent || isLoading) return;
1433
+ // Recovery retries may run immediately after a completion handler calls
1434
+ // setIsLoading(false), before React has committed that state update.
1435
+ if (!hasContent || (retryCount === 0 && isLoading)) return;
1436
+ if (retryCount === 0) {
1437
+ // A new user turn supersedes any older interrupted tool request.
1438
+ pendingTextToolRetryRef.current.clear();
1439
+ }
1413
1440
  setPendingAutoTts(null);
1414
1441
  const turnExternalId = typeof window !== 'undefined'
1415
1442
  ? localStorage.getItem('walletAddress') || undefined
@@ -1728,10 +1755,19 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1728
1755
 
1729
1756
  // Typed preflight already emitted the only permitted recovery UI.
1730
1757
  if (!isToolAllowed) {
1758
+ pendingTextToolRetryRef.current.set({
1759
+ content,
1760
+ isPresetMessage,
1761
+ attachments,
1762
+ });
1731
1763
  setIsLoading(false);
1732
1764
  return;
1733
1765
  }
1734
1766
 
1767
+ // Authorization passed. Clear before invoking the host callback so
1768
+ // concurrent completion events cannot execute this tool twice.
1769
+ pendingTextToolRetryRef.current.clear();
1770
+
1735
1771
  // Create streaming message for tool execution
1736
1772
  const streamingMessageId = `streaming-${Date.now()}`;
1737
1773
  const streamingMessage: Message = {
@@ -2041,6 +2077,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2041
2077
  setIsLoading(false);
2042
2078
  }
2043
2079
  };
2080
+ sendMessageRef.current = sendMessage;
2044
2081
 
2045
2082
  // Handle submit
2046
2083
  const handleSubmit = async (e: React.FormEvent, attachments?: Attachment[]) => {
@@ -2595,6 +2632,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2595
2632
  setShowPermissionForm(false);
2596
2633
  setIsPermissionFormOpen(false);
2597
2634
  await refreshAIT(true);
2635
+ await retryPendingTextTool();
2598
2636
  } catch (error) {
2599
2637
  console.error('Failed to generate AIT:', error);
2600
2638
  setIsDisabled(false);
@@ -2673,7 +2711,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2673
2711
  }
2674
2712
  setIsLoading(false);
2675
2713
  showSuccess(walletTextUtils.getWalletText('Wallet verification completed successfully! Your wallet is now verified and ready to use.', serviceId));
2676
- refreshAIT();
2714
+ await refreshAIT();
2715
+ await retryPendingTextTool();
2677
2716
  return;
2678
2717
  }
2679
2718
  showError(verifyWalletResponse.error);
@@ -2711,7 +2750,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2711
2750
  }
2712
2751
  setIsLoading(false);
2713
2752
  showSuccess('Wallet verification completed successfully! Your wallet is now verified and ready to use.');
2714
- refreshAIT();
2753
+ await refreshAIT();
2754
+ await retryPendingTextTool();
2715
2755
  return;
2716
2756
  } catch (error) {
2717
2757
  let msg = 'Verification failed';
@@ -2751,6 +2791,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2751
2791
  await refreshAIT();
2752
2792
  setIsLoading(false);
2753
2793
  showSuccess(walletTextUtils.getWalletText('Wallet verification completed successfully! Your wallet is now verified and ready to use.', serviceId));
2794
+ await retryPendingTextTool();
2754
2795
  return;
2755
2796
  }
2756
2797
  // Handle specific error messages
@@ -2766,6 +2807,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2766
2807
  await refreshAIT();
2767
2808
  setIsLoading(false);
2768
2809
  showSuccess(walletTextUtils.getWalletText('Wallet verification completed successfully! Your wallet is now verified and ready to use.', serviceId));
2810
+ await retryPendingTextTool();
2769
2811
  return;
2770
2812
  } catch (error) {
2771
2813
  console.error('Custom wallet verification failed:', error);
@@ -2946,6 +2988,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2946
2988
  // Functions
2947
2989
  connectWallet,
2948
2990
  signInWallet,
2991
+ retryPendingTextTool,
2949
2992
  sendMessage,
2950
2993
  handleSubmit,
2951
2994
  handlePresetMessage,
@@ -0,0 +1,39 @@
1
+ import type { Attachment } from '@bytexbyte/nxtlinq-ai-agent-core-development';
2
+
3
+ export type PendingTextToolRequest = {
4
+ content: string;
5
+ isPresetMessage: boolean;
6
+ attachments?: Attachment[];
7
+ };
8
+
9
+ /** Keeps one interrupted text-tool request and serializes all resume attempts. */
10
+ export class PendingTextToolRetryController {
11
+ private pending: PendingTextToolRequest | null = null;
12
+ private inFlight: Promise<boolean> | null = null;
13
+
14
+ set(request: PendingTextToolRequest): void {
15
+ this.pending = request;
16
+ }
17
+
18
+ clear(): void {
19
+ this.pending = null;
20
+ }
21
+
22
+ hasPending(): boolean {
23
+ return this.pending !== null;
24
+ }
25
+
26
+ retry(execute: (request: PendingTextToolRequest) => Promise<void>): Promise<boolean> {
27
+ if (this.inFlight) return this.inFlight;
28
+ if (!this.pending) return Promise.resolve(false);
29
+
30
+ const request = this.pending;
31
+ this.inFlight = (async () => {
32
+ await execute(request);
33
+ return true;
34
+ })().finally(() => {
35
+ this.inFlight = null;
36
+ });
37
+ return this.inFlight;
38
+ }
39
+ }
@@ -163,8 +163,9 @@ export interface ChatBotContextType {
163
163
 
164
164
  // Functions
165
165
  connectWallet: (autoShowSignInMessage?: boolean) => Promise<string | false | undefined>;
166
- signInWallet: (autoShowSuccessMessage?: boolean) => Promise<void>;
167
- sendMessage: (content: string, retryCount?: number) => Promise<void>;
166
+ signInWallet: (autoShowSuccessMessage?: boolean) => Promise<boolean>;
167
+ retryPendingTextTool: () => Promise<boolean>;
168
+ sendMessage: (content: string, retryCount?: number, isPresetMessage?: boolean, attachments?: Attachment[]) => Promise<void>;
168
169
  handleSubmit: (e: React.FormEvent, attachments?: Attachment[]) => Promise<void>;
169
170
  handlePresetMessage: (message: PresetMessage) => void;
170
171
  savePermissions: (newPermissions?: string[]) => Promise<void>;
@@ -194,7 +195,7 @@ export interface ChatBotContextType {
194
195
  // Additional properties for PermissionForm
195
196
  onSave: (newPermissions?: string[]) => Promise<void>;
196
197
  onConnectWallet: () => Promise<string | false | undefined>;
197
- onSignIn: () => Promise<void>;
198
+ onSignIn: () => Promise<boolean>;
198
199
  isNeedSignInWithWallet: boolean;
199
200
  onVerifyWallet: (method: 'berifyme' | 'custom') => Promise<void>;
200
201
  serviceId: string;
@@ -203,4 +204,4 @@ export interface ChatBotContextType {
203
204
  // Props
204
205
  props: ChatBotProps;
205
206
  nxtlinqApi: AITApi;
206
- }
207
+ }
@@ -319,6 +319,7 @@ export const MessageList: React.FC = () => {
319
319
  retryTtsWithGesture,
320
320
  connectWallet,
321
321
  signInWallet,
322
+ retryPendingTextTool,
322
323
  hitAddress,
323
324
  isAutoConnecting,
324
325
  isNeedSignInWithWallet,
@@ -353,20 +354,22 @@ export const MessageList: React.FC = () => {
353
354
  }
354
355
 
355
356
  if (buttonType === 'connectWallet') {
356
- connectWallet(true);
357
+ const connected = await connectWallet(false);
358
+ if (connected) {
359
+ // Continue the interrupted flow immediately. This opens the wallet
360
+ // signature UI instead of leaving the user on a stale connect prompt.
361
+ const signedIn = await signInWallet(true);
362
+ if (signedIn) await retryPendingTextTool();
363
+ }
357
364
  } else if (buttonType === 'signIn') {
358
- signInWallet(true);
365
+ const signedIn = await signInWallet(true);
366
+ if (signedIn) await retryPendingTextTool();
359
367
  } else if (buttonType === 'enableAIT') {
360
368
  const requiredPermission = message.metadata?.requiredPermission;
361
369
  if (requiredPermission) {
362
370
  const success = await enableAIT(requiredPermission);
363
371
  if (success) {
364
- // Find the last user message
365
- const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
366
- if (lastUserMsg && lastUserMsg.content) {
367
- // Re-execute the previous user message (retryCount=1 to skip duplicate PII log)
368
- await sendMessage(lastUserMsg.content, 1);
369
- }
372
+ await retryPendingTextTool();
370
373
  }
371
374
  }
372
375
  } else if (buttonType === 'verifyWallet') {