@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.8 → 0.4.10

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.
@@ -0,0 +1,7 @@
1
+ export type AITMutationAuthenticationPlan = 'reuse_session' | 'sign_in' | 'connect_and_sign_in';
2
+ export declare function planAITMutationAuthentication(params: {
3
+ walletAddress: string | null | undefined;
4
+ walletToken: string | null | undefined;
5
+ hasSigner: boolean;
6
+ }): AITMutationAuthenticationPlan;
7
+ //# sourceMappingURL=aitMutationAuthentication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aitMutationAuthentication.d.ts","sourceRoot":"","sources":["../src/aitMutationAuthentication.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6BAA6B,GACrC,eAAe,GACf,SAAS,GACT,qBAAqB,CAAC;AAE1B,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,6BAA6B,CAehC"}
@@ -0,0 +1,13 @@
1
+ import { validateWalletSession } from '@bytexbyte/nxtlinq-ai-agent-core-development';
2
+ export function planAITMutationAuthentication(params) {
3
+ const walletAddress = params.walletAddress?.trim();
4
+ const walletToken = params.walletToken?.trim();
5
+ if (walletAddress
6
+ && walletToken
7
+ && validateWalletSession(walletToken, walletAddress).valid) {
8
+ return 'reuse_session';
9
+ }
10
+ return walletAddress && params.hasSigner
11
+ ? 'sign_in'
12
+ : 'connect_and_sign_in';
13
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA+B/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AA0B/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAwgGlD,CAAC"}
1
+ {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA+B/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAwB/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAo/FlD,CAAC"}
@@ -8,9 +8,10 @@ import { createNxtlinqApi, setApiHosts, synthesizeSpeechToBuffer, streamSpeechTo
8
8
  import { authorizeTextFrontendTool, hasRecordedWalletVerification, validateWalletSession, } from '@bytexbyte/nxtlinq-ai-agent-core-development';
9
9
  import { AuthorizationLoadingState } from '../authorizationLoadingState';
10
10
  import { PendingTextToolRetryController } from '../pendingTextToolRetry';
11
+ import { planAITMutationAuthentication } from '../aitMutationAuthentication';
11
12
  import { completePiiScan } from '../piiMessageState';
12
13
  import { filterSuggestions } from '../suggestionState';
13
- import { dispatchRuntimeAITCompleteReplacement, removeOneDeniedPermission, replaceCurrentMaximumDenyList, RuntimeAITMutationQueue, RuntimeAITRecomputeCoordinator, StaleRuntimeAITResponseError, runtimeAITContextKey, runtimeAITSubjectKey, runtimeAuthorizationMatchesContext, runtimeAuthorizationState, unavailableRuntimeAuthorization, useProviderRuntimeCommit, useRuntimeAITContextCommit, } from '../permissionState';
14
+ import { RuntimeAITMutationQueue, RuntimeAITRecomputeCoordinator, StaleRuntimeAITResponseError, runtimeAITContextKey, runtimeAITSubjectKey, runtimeAuthorizationMatchesContext, runtimeAuthorizationState, unavailableRuntimeAuthorization, useProviderRuntimeCommit, useRuntimeAITContextCommit, } from '../permissionState';
14
15
  const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
15
16
  const ChatBotContext = React.createContext(undefined);
16
17
  export const useChatBot = () => {
@@ -938,30 +939,23 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
938
939
  setRuntimeAuthorizationContextKey(activeContext ? runtimeAITContextKey(activeContext) : null);
939
940
  }, []);
940
941
  useRuntimeAITContextCommit(runtimeRecomputeCoordinatorRef.current, runtimeContext, invalidateCommittedRuntimeContext);
941
- const recomputeRuntimeAIT = React.useCallback(async (context) => {
942
+ const readRuntimeAIT = React.useCallback(async (context) => {
942
943
  const capturedContext = {
943
944
  controller: context.controller,
944
945
  serviceId: context.serviceId,
945
946
  ...(context.roles !== undefined ? { roles: [...context.roles] } : {}),
946
947
  ...(context.permissionGroup !== undefined ? { permissionGroup: context.permissionGroup } : {}),
947
948
  };
948
- return runtimeRecomputeCoordinatorRef.current.run(capturedContext, () => nxtlinqApi.ait.recomputeAIT(capturedContext), applyRuntimeResult, clearRuntimeAuthorization);
949
+ return runtimeRecomputeCoordinatorRef.current.run(capturedContext, () => nxtlinqApi.ait.readAIT(capturedContext), applyRuntimeResult, clearRuntimeAuthorization);
949
950
  }, [applyRuntimeResult, clearRuntimeAuthorization, nxtlinqApi]);
950
951
  const queueRuntimeAITRefresh = React.useCallback((context) => runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
951
952
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
952
- return recomputeRuntimeAIT(context);
953
- }), [recomputeRuntimeAIT]);
954
- const convergeRuntimeAITSubject = React.useCallback(async (subjectKey) => {
955
- const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
956
- if (!activeContext || runtimeAITSubjectKey(activeContext) !== subjectKey) {
957
- return;
958
- }
959
- await recomputeRuntimeAIT(activeContext);
960
- }, [recomputeRuntimeAIT]);
961
- const dispatchRuntimeDenyListReplacement = React.useCallback(async (context, nextDeniedPermissions) => dispatchRuntimeAITCompleteReplacement(runtimeRecomputeCoordinatorRef.current, context, () => nxtlinqApi.ait.updatePermissionDenyList({
953
+ return readRuntimeAIT(context);
954
+ }), [readRuntimeAIT]);
955
+ const replaceRuntimeActivePermissions = React.useCallback(async (context, activePermissions) => runtimeRecomputeCoordinatorRef.current.run(context, () => nxtlinqApi.ait.updateActivePermissions({
962
956
  ...context,
963
- deniedPermissions: nextDeniedPermissions,
964
- }), convergeRuntimeAITSubject, clearRuntimeAuthorization), [clearRuntimeAuthorization, convergeRuntimeAITSubject, nxtlinqApi]);
957
+ activePermissions,
958
+ }), applyRuntimeResult, clearRuntimeAuthorization), [applyRuntimeResult, clearRuntimeAuthorization, nxtlinqApi]);
965
959
  // Refresh the authoritative runtime AIT state.
966
960
  const refreshAIT = async (forceUpdatePermissions = false) => {
967
961
  const currentHitAddress = hitAddressRef.current || hitAddress;
@@ -2240,8 +2234,16 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2240
2234
  setIsAITEnabling(true);
2241
2235
  let currentSigner = signer;
2242
2236
  let currentHitAddress = hitAddress;
2243
- // If no wallet connected, try to auto-connect first
2244
- if (!currentSigner || !currentHitAddress) {
2237
+ const currentWalletToken = nxtlinqAITServiceAccessTokenRef.current
2238
+ || nxtlinqAITServiceAccessToken;
2239
+ const authenticationPlan = planAITMutationAuthentication({
2240
+ walletAddress: currentHitAddress,
2241
+ walletToken: currentWalletToken,
2242
+ hasSigner: Boolean(currentSigner),
2243
+ });
2244
+ // A valid wallet session is sufficient for an authenticated DB mutation.
2245
+ // A signer is only needed when the session must be established or renewed.
2246
+ if (authenticationPlan === 'connect_and_sign_in') {
2245
2247
  const autoConnectResult = await connectWallet(false); // Don't show sign-in message yet
2246
2248
  if (autoConnectResult) {
2247
2249
  // Wait for state to update - increase wait time
@@ -2255,14 +2257,6 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2255
2257
  currentSigner = signerRef.current || signer;
2256
2258
  currentHitAddress = hitAddressRef.current || hitAddress;
2257
2259
  }
2258
- try {
2259
- await signInWallet(false); // Don't show success message yet
2260
- }
2261
- catch (signInError) {
2262
- showError(walletTextUtils.getWalletText('Wallet connected but sign-in failed. Please try signing in manually.', serviceId));
2263
- setIsAITEnabling(false);
2264
- return false;
2265
- }
2266
2260
  }
2267
2261
  else {
2268
2262
  showError(walletTextUtils.getWalletText('Please connect your wallet first', serviceId));
@@ -2270,29 +2264,21 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2270
2264
  return false;
2271
2265
  }
2272
2266
  }
2273
- // Final check before proceeding
2274
- if (!currentSigner || !currentHitAddress) {
2275
- console.error('Missing signer or wallet address after connection process');
2276
- console.error('Current signer:', !!currentSigner);
2277
- console.error('Current hitAddress:', currentHitAddress);
2278
- console.error('Signer ref:', !!signerRef.current);
2279
- console.error('HitAddress ref:', hitAddressRef.current);
2267
+ if (authenticationPlan !== 'reuse_session') {
2268
+ const signedIn = await signInWallet(false);
2269
+ if (!signedIn) {
2270
+ showError(walletTextUtils.getWalletText('Wallet connected but sign-in failed. Please try signing in manually.', serviceId));
2271
+ setIsAITEnabling(false);
2272
+ return false;
2273
+ }
2274
+ currentHitAddress = hitAddressRef.current || hitAddress;
2275
+ }
2276
+ if (!currentHitAddress) {
2277
+ console.error('Missing wallet address after authentication');
2280
2278
  showError(walletTextUtils.getWalletText('Wallet connection failed. Please try connecting your wallet manually.', serviceId));
2281
2279
  setIsAITEnabling(false);
2282
2280
  return false;
2283
2281
  }
2284
- // If we don't have AIT loaded but we have a token, try to refresh it first
2285
- if (!aitRef.current && nxtlinqAITServiceAccessToken) {
2286
- try {
2287
- await refreshAIT();
2288
- // Wait a bit for AIT to be loaded
2289
- await new Promise(resolve => setTimeout(resolve, 1000));
2290
- }
2291
- catch (error) {
2292
- // Continue anyway, we'll create a new AIT if needed
2293
- console.error('Failed to refresh AIT:', error);
2294
- }
2295
- }
2296
2282
  try {
2297
2283
  const context = {
2298
2284
  controller: currentHitAddress,
@@ -2302,13 +2288,19 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2302
2288
  };
2303
2289
  const enabled = await runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
2304
2290
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2305
- const current = await recomputeRuntimeAIT(context);
2291
+ const current = await readRuntimeAIT(context);
2306
2292
  if (!current.maximumPermissions.includes(toolName)) {
2307
2293
  return false;
2308
2294
  }
2309
- const nextDeniedPermissions = removeOneDeniedPermission(current.deniedPermissions, toolName);
2295
+ if (current.effectivePermissions.includes(toolName) && current.aitId) {
2296
+ return true;
2297
+ }
2298
+ const nextActivePermissions = Array.from(new Set([
2299
+ ...current.effectivePermissions,
2300
+ toolName,
2301
+ ]));
2310
2302
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2311
- await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
2303
+ await replaceRuntimeActivePermissions(context, nextActivePermissions);
2312
2304
  return true;
2313
2305
  });
2314
2306
  if (!enabled) {
@@ -2353,15 +2345,11 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
2353
2345
  const checkedPermissions = [...(newPermissions ?? permissions)];
2354
2346
  await runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
2355
2347
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2356
- const fresh = await recomputeRuntimeAIT(context);
2357
- const nextDeniedPermissions = replaceCurrentMaximumDenyList(fresh.deniedPermissions, fresh.maximumPermissions, checkedPermissions);
2358
- runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2359
- await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
2348
+ await replaceRuntimeActivePermissions(context, checkedPermissions);
2360
2349
  });
2361
2350
  showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
2362
2351
  setShowPermissionForm(false);
2363
2352
  setIsPermissionFormOpen(false);
2364
- await refreshAIT(true);
2365
2353
  await retryPendingTextTool();
2366
2354
  }
2367
2355
  catch (error) {
@@ -44,7 +44,7 @@ export interface ChatBotProps {
44
44
  apiSecret?: string;
45
45
  serviceToken?: string;
46
46
  getAuthToken?: () => Promise<string>;
47
- environment?: 'production' | 'staging';
47
+ environment?: 'production' | 'staging' | 'local';
48
48
  onVerifyWallet?: () => Promise<{
49
49
  token: string;
50
50
  } | undefined>;
@@ -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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytexbyte/nxtlinq-ai-agent-ui-react-development",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
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",
@@ -38,8 +38,8 @@
38
38
  "react-dom": ">=18.0.0"
39
39
  },
40
40
  "dependencies": {
41
- "@bytexbyte/nxtlinq-ai-agent-core-development": "2.0.3",
42
- "@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.3",
41
+ "@bytexbyte/nxtlinq-ai-agent-core-development": "2.0.4",
42
+ "@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.4",
43
43
  "@emotion/react": "^11.14.0",
44
44
  "@emotion/styled": "^11.14.1",
45
45
  "@mui/icons-material": "^7.2.0",
@@ -0,0 +1,27 @@
1
+ import { validateWalletSession } from '@bytexbyte/nxtlinq-ai-agent-core-development';
2
+
3
+ export type AITMutationAuthenticationPlan =
4
+ | 'reuse_session'
5
+ | 'sign_in'
6
+ | 'connect_and_sign_in';
7
+
8
+ export function planAITMutationAuthentication(params: {
9
+ walletAddress: string | null | undefined;
10
+ walletToken: string | null | undefined;
11
+ hasSigner: boolean;
12
+ }): AITMutationAuthenticationPlan {
13
+ const walletAddress = params.walletAddress?.trim();
14
+ const walletToken = params.walletToken?.trim();
15
+
16
+ if (
17
+ walletAddress
18
+ && walletToken
19
+ && validateWalletSession(walletToken, walletAddress).valid
20
+ ) {
21
+ return 'reuse_session';
22
+ }
23
+
24
+ return walletAddress && params.hasSigner
25
+ ? 'sign_in'
26
+ : 'connect_and_sign_in';
27
+ }
@@ -39,12 +39,10 @@ import {
39
39
  } from '../types/ChatBotTypes';
40
40
  import { AuthorizationLoadingState } from '../authorizationLoadingState';
41
41
  import { PendingTextToolRetryController } from '../pendingTextToolRetry';
42
+ import { planAITMutationAuthentication } from '../aitMutationAuthentication';
42
43
  import { completePiiScan } from '../piiMessageState';
43
44
  import { filterSuggestions } from '../suggestionState';
44
45
  import {
45
- dispatchRuntimeAITCompleteReplacement,
46
- removeOneDeniedPermission,
47
- replaceCurrentMaximumDenyList,
48
46
  RuntimeAITMutationQueue,
49
47
  RuntimeAITRecomputeCoordinator,
50
48
  StaleRuntimeAITResponseError,
@@ -1125,7 +1123,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1125
1123
  invalidateCommittedRuntimeContext,
1126
1124
  );
1127
1125
 
1128
- const recomputeRuntimeAIT = React.useCallback(async (context: RuntimeAITContext) => {
1126
+ const readRuntimeAIT = React.useCallback(async (context: RuntimeAITContext) => {
1129
1127
  const capturedContext: RuntimeAITContext = {
1130
1128
  controller: context.controller,
1131
1129
  serviceId: context.serviceId,
@@ -1134,7 +1132,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1134
1132
  };
1135
1133
  return runtimeRecomputeCoordinatorRef.current.run(
1136
1134
  capturedContext,
1137
- () => nxtlinqApi.ait.recomputeAIT(capturedContext),
1135
+ () => nxtlinqApi.ait.readAIT(capturedContext),
1138
1136
  applyRuntimeResult,
1139
1137
  clearRuntimeAuthorization,
1140
1138
  );
@@ -1145,33 +1143,24 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
1145
1143
  runtimeAITSubjectKey(context),
1146
1144
  async () => {
1147
1145
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
1148
- return recomputeRuntimeAIT(context);
1146
+ return readRuntimeAIT(context);
1149
1147
  },
1150
1148
  ),
1151
- [recomputeRuntimeAIT],
1149
+ [readRuntimeAIT],
1152
1150
  );
1153
1151
 
1154
- const convergeRuntimeAITSubject = React.useCallback(async (subjectKey: string) => {
1155
- const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
1156
- if (!activeContext || runtimeAITSubjectKey(activeContext) !== subjectKey) {
1157
- return;
1158
- }
1159
- await recomputeRuntimeAIT(activeContext);
1160
- }, [recomputeRuntimeAIT]);
1161
-
1162
- const dispatchRuntimeDenyListReplacement = React.useCallback(async (
1152
+ const replaceRuntimeActivePermissions = React.useCallback(async (
1163
1153
  context: RuntimeAITContext,
1164
- nextDeniedPermissions: string[],
1165
- ) => dispatchRuntimeAITCompleteReplacement(
1166
- runtimeRecomputeCoordinatorRef.current,
1154
+ activePermissions: string[],
1155
+ ) => runtimeRecomputeCoordinatorRef.current.run(
1167
1156
  context,
1168
- () => nxtlinqApi.ait.updatePermissionDenyList({
1157
+ () => nxtlinqApi.ait.updateActivePermissions({
1169
1158
  ...context,
1170
- deniedPermissions: nextDeniedPermissions,
1159
+ activePermissions,
1171
1160
  }),
1172
- convergeRuntimeAITSubject,
1161
+ applyRuntimeResult,
1173
1162
  clearRuntimeAuthorization,
1174
- ), [clearRuntimeAuthorization, convergeRuntimeAITSubject, nxtlinqApi]);
1163
+ ), [applyRuntimeResult, clearRuntimeAuthorization, nxtlinqApi]);
1175
1164
 
1176
1165
  // Refresh the authoritative runtime AIT state.
1177
1166
  const refreshAIT = async (forceUpdatePermissions = false) => {
@@ -2571,9 +2560,17 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2571
2560
 
2572
2561
  let currentSigner = signer;
2573
2562
  let currentHitAddress = hitAddress;
2563
+ const currentWalletToken = nxtlinqAITServiceAccessTokenRef.current
2564
+ || nxtlinqAITServiceAccessToken;
2565
+ const authenticationPlan = planAITMutationAuthentication({
2566
+ walletAddress: currentHitAddress,
2567
+ walletToken: currentWalletToken,
2568
+ hasSigner: Boolean(currentSigner),
2569
+ });
2574
2570
 
2575
- // If no wallet connected, try to auto-connect first
2576
- if (!currentSigner || !currentHitAddress) {
2571
+ // A valid wallet session is sufficient for an authenticated DB mutation.
2572
+ // A signer is only needed when the session must be established or renewed.
2573
+ if (authenticationPlan === 'connect_and_sign_in') {
2577
2574
  const autoConnectResult = await connectWallet(false); // Don't show sign-in message yet
2578
2575
 
2579
2576
  if (autoConnectResult) {
@@ -2591,13 +2588,6 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2591
2588
  currentHitAddress = hitAddressRef.current || hitAddress;
2592
2589
  }
2593
2590
 
2594
- try {
2595
- await signInWallet(false); // Don't show success message yet
2596
- } catch (signInError) {
2597
- showError(walletTextUtils.getWalletText('Wallet connected but sign-in failed. Please try signing in manually.', serviceId));
2598
- setIsAITEnabling(false);
2599
- return false;
2600
- }
2601
2591
  } else {
2602
2592
  showError(walletTextUtils.getWalletText('Please connect your wallet first', serviceId));
2603
2593
  setIsAITEnabling(false);
@@ -2605,30 +2595,23 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2605
2595
  }
2606
2596
  }
2607
2597
 
2608
- // Final check before proceeding
2609
- if (!currentSigner || !currentHitAddress) {
2610
- console.error('Missing signer or wallet address after connection process');
2611
- console.error('Current signer:', !!currentSigner);
2612
- console.error('Current hitAddress:', currentHitAddress);
2613
- console.error('Signer ref:', !!signerRef.current);
2614
- console.error('HitAddress ref:', hitAddressRef.current);
2598
+ if (authenticationPlan !== 'reuse_session') {
2599
+ const signedIn = await signInWallet(false);
2600
+ if (!signedIn) {
2601
+ showError(walletTextUtils.getWalletText('Wallet connected but sign-in failed. Please try signing in manually.', serviceId));
2602
+ setIsAITEnabling(false);
2603
+ return false;
2604
+ }
2605
+ currentHitAddress = hitAddressRef.current || hitAddress;
2606
+ }
2607
+
2608
+ if (!currentHitAddress) {
2609
+ console.error('Missing wallet address after authentication');
2615
2610
  showError(walletTextUtils.getWalletText('Wallet connection failed. Please try connecting your wallet manually.', serviceId));
2616
2611
  setIsAITEnabling(false);
2617
2612
  return false;
2618
2613
  }
2619
2614
 
2620
- // If we don't have AIT loaded but we have a token, try to refresh it first
2621
- if (!aitRef.current && nxtlinqAITServiceAccessToken) {
2622
- try {
2623
- await refreshAIT();
2624
- // Wait a bit for AIT to be loaded
2625
- await new Promise(resolve => setTimeout(resolve, 1000));
2626
- } catch (error) {
2627
- // Continue anyway, we'll create a new AIT if needed
2628
- console.error('Failed to refresh AIT:', error);
2629
- }
2630
- }
2631
-
2632
2615
  try {
2633
2616
  const context: RuntimeAITContext = {
2634
2617
  controller: currentHitAddress,
@@ -2640,16 +2623,19 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2640
2623
  runtimeAITSubjectKey(context),
2641
2624
  async () => {
2642
2625
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2643
- const current = await recomputeRuntimeAIT(context);
2626
+ const current = await readRuntimeAIT(context);
2644
2627
  if (!current.maximumPermissions.includes(toolName)) {
2645
2628
  return false;
2646
2629
  }
2647
- const nextDeniedPermissions = removeOneDeniedPermission(
2648
- current.deniedPermissions,
2630
+ if (current.effectivePermissions.includes(toolName) && current.aitId) {
2631
+ return true;
2632
+ }
2633
+ const nextActivePermissions = Array.from(new Set([
2634
+ ...current.effectivePermissions,
2649
2635
  toolName,
2650
- );
2636
+ ]));
2651
2637
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2652
- await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
2638
+ await replaceRuntimeActivePermissions(context, nextActivePermissions);
2653
2639
  return true;
2654
2640
  },
2655
2641
  );
@@ -2695,20 +2681,12 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
2695
2681
  runtimeAITSubjectKey(context),
2696
2682
  async () => {
2697
2683
  runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2698
- const fresh = await recomputeRuntimeAIT(context);
2699
- const nextDeniedPermissions = replaceCurrentMaximumDenyList(
2700
- fresh.deniedPermissions,
2701
- fresh.maximumPermissions,
2702
- checkedPermissions,
2703
- );
2704
- runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2705
- await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
2684
+ await replaceRuntimeActivePermissions(context, checkedPermissions);
2706
2685
  },
2707
2686
  );
2708
2687
  showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
2709
2688
  setShowPermissionForm(false);
2710
2689
  setIsPermissionFormOpen(false);
2711
- await refreshAIT(true);
2712
2690
  await retryPendingTextTool();
2713
2691
  } catch (error) {
2714
2692
  if (!(error instanceof StaleRuntimeAITResponseError)) {
@@ -52,7 +52,7 @@ export interface ChatBotProps {
52
52
  apiSecret?: string;
53
53
  serviceToken?: string;
54
54
  getAuthToken?: () => Promise<string>;
55
- environment?: 'production' | 'staging'; // API environment (default: production)
55
+ environment?: 'production' | 'staging' | 'local'; // API environment (default: production)
56
56
  onVerifyWallet?: () => Promise<{
57
57
  token: string;
58
58
  } | undefined>;