@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.12 → 0.4.14
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/context/ChatBotContext.d.ts.map +1 -1
- package/dist/context/ChatBotContext.js +75 -31
- package/dist/types/ChatBotTypes.d.ts +2 -0
- package/dist/types/ChatBotTypes.d.ts.map +1 -1
- package/dist/ui/PermissionForm.d.ts.map +1 -1
- package/dist/ui/PermissionForm.js +25 -25
- package/package.json +2 -2
- package/src/context/ChatBotContext.tsx +96 -33
- package/src/types/ChatBotTypes.ts +2 -0
- package/src/ui/PermissionForm.tsx +25 -23
|
@@ -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;
|
|
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;AAqC/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAkjGlD,CAAC"}
|
|
@@ -103,6 +103,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
103
103
|
const [showPermissionForm, setShowPermissionForm] = React.useState(false);
|
|
104
104
|
const [isPermissionFormOpen, setIsPermissionFormOpen] = React.useState(false);
|
|
105
105
|
const [isAITLoading, setIsAITLoading] = React.useState(false);
|
|
106
|
+
const [permissionSaveState, setPermissionSaveState] = React.useState(null);
|
|
106
107
|
const [isDisabled, setIsDisabled] = React.useState(true);
|
|
107
108
|
const [signer, setSigner] = React.useState(null);
|
|
108
109
|
const [walletInfo, setWalletInfo] = React.useState(null);
|
|
@@ -174,6 +175,8 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
174
175
|
}, []);
|
|
175
176
|
const runtimeRecomputeCoordinatorRef = React.useRef(new RuntimeAITRecomputeCoordinator());
|
|
176
177
|
const runtimeMutationQueueRef = React.useRef(new RuntimeAITMutationQueue());
|
|
178
|
+
const permissionSaveOperationRef = React.useRef(null);
|
|
179
|
+
const permissionSaveOperationIdRef = React.useRef(0);
|
|
177
180
|
useProviderRuntimeCommit(hitAddressRef, hitAddress, environment, setApiHosts);
|
|
178
181
|
// Helper function to combine customUsername with Adilas customUserInfo
|
|
179
182
|
const getFinalCustomUsername = React.useCallback((username) => {
|
|
@@ -972,6 +975,14 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
972
975
|
setIsAITLoading(false);
|
|
973
976
|
return;
|
|
974
977
|
}
|
|
978
|
+
// updateActivePermissions publishes the authoritative result itself. A modal reopened while
|
|
979
|
+
// that mutation is still running must keep rendering its submitted draft instead of queuing
|
|
980
|
+
// a redundant GET that replaces the form with a loading state.
|
|
981
|
+
const activePermissionSave = permissionSaveOperationRef.current;
|
|
982
|
+
if (runtimeContext
|
|
983
|
+
&& activePermissionSave?.subjectKey === runtimeAITSubjectKey(runtimeContext)) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
975
986
|
authorizationLoadingStateRef.current.setAITLoading(true);
|
|
976
987
|
setIsAITLoading(true);
|
|
977
988
|
try {
|
|
@@ -2342,41 +2353,68 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2342
2353
|
// Save permissions
|
|
2343
2354
|
const savePermissions = async (newPermissions) => {
|
|
2344
2355
|
setIsDisabled(true);
|
|
2345
|
-
|
|
2346
|
-
if (!hitAddress) {
|
|
2347
|
-
throw new Error('Please connect your wallet first');
|
|
2348
|
-
}
|
|
2349
|
-
const context = {
|
|
2350
|
-
controller: hitAddress,
|
|
2351
|
-
serviceId,
|
|
2352
|
-
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2353
|
-
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2354
|
-
};
|
|
2355
|
-
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2356
|
-
await runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
|
|
2357
|
-
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2358
|
-
await replaceRuntimeActivePermissions(context, checkedPermissions);
|
|
2359
|
-
});
|
|
2360
|
-
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2361
|
-
setShowPermissionForm(false);
|
|
2362
|
-
setIsPermissionFormOpen(false);
|
|
2363
|
-
await retryPendingTextTool();
|
|
2364
|
-
}
|
|
2365
|
-
catch (error) {
|
|
2366
|
-
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2367
|
-
console.error('Failed to update AIT deny-list:', error);
|
|
2368
|
-
}
|
|
2356
|
+
if (!hitAddress) {
|
|
2369
2357
|
setIsDisabled(false);
|
|
2370
|
-
|
|
2371
|
-
|
|
2358
|
+
showError('Please connect your wallet first');
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2361
|
+
const context = {
|
|
2362
|
+
controller: hitAddress,
|
|
2363
|
+
serviceId,
|
|
2364
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2365
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2366
|
+
};
|
|
2367
|
+
const subjectKey = runtimeAITSubjectKey(context);
|
|
2368
|
+
const activeOperation = permissionSaveOperationRef.current;
|
|
2369
|
+
if (activeOperation?.subjectKey === subjectKey) {
|
|
2370
|
+
return activeOperation.promise;
|
|
2371
|
+
}
|
|
2372
|
+
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2373
|
+
const operationId = ++permissionSaveOperationIdRef.current;
|
|
2374
|
+
setPermissionSaveState({
|
|
2375
|
+
operationId,
|
|
2376
|
+
subjectKey,
|
|
2377
|
+
permissions: checkedPermissions,
|
|
2378
|
+
status: 'saving',
|
|
2379
|
+
});
|
|
2380
|
+
const operation = (async () => {
|
|
2381
|
+
try {
|
|
2382
|
+
await runtimeMutationQueueRef.current.run(subjectKey, async () => {
|
|
2383
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2384
|
+
await replaceRuntimeActivePermissions(context, checkedPermissions);
|
|
2385
|
+
});
|
|
2386
|
+
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2387
|
+
setShowPermissionForm(false);
|
|
2388
|
+
setIsPermissionFormOpen(false);
|
|
2389
|
+
setPermissionSaveState((current) => current?.operationId === operationId ? null : current);
|
|
2390
|
+
await retryPendingTextTool();
|
|
2372
2391
|
}
|
|
2373
|
-
|
|
2374
|
-
|
|
2392
|
+
catch (error) {
|
|
2393
|
+
setPermissionSaveState((current) => current?.operationId === operationId
|
|
2394
|
+
? { ...current, status: 'failed' }
|
|
2395
|
+
: current);
|
|
2396
|
+
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2397
|
+
console.error('Failed to update AIT deny-list:', error);
|
|
2398
|
+
}
|
|
2399
|
+
setIsDisabled(false);
|
|
2400
|
+
if (error instanceof StaleRuntimeAITResponseError) {
|
|
2401
|
+
return;
|
|
2402
|
+
}
|
|
2403
|
+
else if (error instanceof Error) {
|
|
2404
|
+
showError(error.message);
|
|
2405
|
+
}
|
|
2406
|
+
else {
|
|
2407
|
+
showError('Failed to save permissions. Please try again.');
|
|
2408
|
+
}
|
|
2375
2409
|
}
|
|
2376
|
-
|
|
2377
|
-
|
|
2410
|
+
finally {
|
|
2411
|
+
if (permissionSaveOperationRef.current?.operationId === operationId) {
|
|
2412
|
+
permissionSaveOperationRef.current = null;
|
|
2413
|
+
}
|
|
2378
2414
|
}
|
|
2379
|
-
}
|
|
2415
|
+
})();
|
|
2416
|
+
permissionSaveOperationRef.current = { operationId, subjectKey, promise: operation };
|
|
2417
|
+
return operation;
|
|
2380
2418
|
};
|
|
2381
2419
|
// Handle verify wallet click
|
|
2382
2420
|
const handleVerifyWalletClick = async (method) => {
|
|
@@ -2653,6 +2691,10 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2653
2691
|
updateExternalId();
|
|
2654
2692
|
}, [hitAddress, nxtlinqApi, authFields, pseudoId]);
|
|
2655
2693
|
const runtimeAuthorizationMatchesRenderedContext = runtimeAuthorizationMatchesContext(runtimeAuthorizationContextKey, runtimeContext);
|
|
2694
|
+
const renderedPermissionSaveState = runtimeContext
|
|
2695
|
+
&& permissionSaveState?.subjectKey === runtimeAITSubjectKey(runtimeContext)
|
|
2696
|
+
? permissionSaveState
|
|
2697
|
+
: null;
|
|
2656
2698
|
const contextValue = {
|
|
2657
2699
|
// State
|
|
2658
2700
|
messages,
|
|
@@ -2673,6 +2715,8 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2673
2715
|
showPermissionForm,
|
|
2674
2716
|
isPermissionFormOpen,
|
|
2675
2717
|
isAITLoading,
|
|
2718
|
+
permissionSaveDraft: renderedPermissionSaveState?.permissions ?? null,
|
|
2719
|
+
isPermissionSaving: renderedPermissionSaveState?.status === 'saving',
|
|
2676
2720
|
isDisabled,
|
|
2677
2721
|
walletInfo,
|
|
2678
2722
|
isWalletLoading,
|
|
@@ -89,6 +89,8 @@ export interface ChatBotContextType {
|
|
|
89
89
|
showPermissionForm: boolean;
|
|
90
90
|
isPermissionFormOpen: boolean;
|
|
91
91
|
isAITLoading: boolean;
|
|
92
|
+
permissionSaveDraft: string[] | null;
|
|
93
|
+
isPermissionSaving: boolean;
|
|
92
94
|
isAITEnabling: boolean;
|
|
93
95
|
isDisabled: boolean;
|
|
94
96
|
walletInfo: any;
|
|
@@ -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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionForm.d.ts","sourceRoot":"","sources":["../../src/ui/PermissionForm.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"PermissionForm.d.ts","sourceRoot":"","sources":["../../src/ui/PermissionForm.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA6lBxD,CAAC"}
|
|
@@ -7,18 +7,24 @@ import { walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
|
7
7
|
import { hasRecordedWalletVerification } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
8
8
|
import { actionButton } from './styles/isolatedStyles';
|
|
9
9
|
export const PermissionForm = ({ onClose }) => {
|
|
10
|
-
const { hitAddress, permissions, availablePermissions, runtimePermissionsUnavailable, setIsDisabled, onSave, onConnectWallet, onSignIn, isNeedSignInWithWallet, walletInfo, onVerifyWallet, serviceId, isAITLoading, isWalletLoading = false, refreshAIT, props } = useChatBot();
|
|
11
|
-
const [
|
|
12
|
-
const [tempPermissions, setTempPermissions] = React.useState(permissions);
|
|
10
|
+
const { hitAddress, permissions, availablePermissions, runtimePermissionsUnavailable, setIsDisabled, onSave, onConnectWallet, onSignIn, isNeedSignInWithWallet, walletInfo, onVerifyWallet, serviceId, isAITLoading, permissionSaveDraft, isPermissionSaving, isWalletLoading = false, refreshAIT, props } = useChatBot();
|
|
11
|
+
const [tempPermissions, setTempPermissions] = React.useState(permissionSaveDraft ?? permissions);
|
|
13
12
|
const [hasUserInteracted, setHasUserInteracted] = React.useState(false);
|
|
13
|
+
const isPermissionFormBusy = isAITLoading || isPermissionSaving;
|
|
14
|
+
const hasPermissionSnapshot = permissionSaveDraft !== null
|
|
15
|
+
|| availablePermissions.length > 0
|
|
16
|
+
|| permissions.length > 0;
|
|
14
17
|
// Check if ALL permission is selected
|
|
15
18
|
const isAllSelected = tempPermissions.includes('ALL');
|
|
16
19
|
// Update temp permissions when permissions change, but only if user hasn't interacted
|
|
17
20
|
React.useEffect(() => {
|
|
18
|
-
if (
|
|
21
|
+
if (permissionSaveDraft) {
|
|
22
|
+
setTempPermissions(permissionSaveDraft);
|
|
23
|
+
}
|
|
24
|
+
else if (!hasUserInteracted) {
|
|
19
25
|
setTempPermissions(permissions);
|
|
20
26
|
}
|
|
21
|
-
}, [permissions, hasUserInteracted]);
|
|
27
|
+
}, [permissions, permissionSaveDraft, hasUserInteracted]);
|
|
22
28
|
// When ALL is selected, automatically select all other permissions
|
|
23
29
|
// This handles cases where ALL is set from initial permissions or when availablePermissions loads
|
|
24
30
|
React.useEffect(() => {
|
|
@@ -57,14 +63,8 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
57
63
|
const shouldShowVerificationPrompt = requireWalletIDVVerification
|
|
58
64
|
&& (!walletInfo?.id || !hasRecordedWalletVerification(walletInfo));
|
|
59
65
|
const handleSave = async () => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
await onSave(tempPermissions);
|
|
63
|
-
setHasUserInteracted(false);
|
|
64
|
-
}
|
|
65
|
-
finally {
|
|
66
|
-
setIsSaving(false);
|
|
67
|
-
}
|
|
66
|
+
await onSave(tempPermissions);
|
|
67
|
+
setHasUserInteracted(false);
|
|
68
68
|
};
|
|
69
69
|
const handleCancel = () => {
|
|
70
70
|
// Reset temp permissions to original permissions
|
|
@@ -317,7 +317,7 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
317
317
|
font-size: 16px !important;
|
|
318
318
|
color: #666 !important;
|
|
319
319
|
flex-shrink: 0 !important;
|
|
320
|
-
`, children: "Permissions" }), isAITLoading ? (_jsx("div", { css: css `
|
|
320
|
+
`, children: "Permissions" }), isAITLoading && !hasPermissionSnapshot ? (_jsx("div", { css: css `
|
|
321
321
|
background-color: #f8f9fa !important;
|
|
322
322
|
padding: 16px !important;
|
|
323
323
|
border-radius: 8px !important;
|
|
@@ -353,17 +353,17 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
353
353
|
display: flex !important;
|
|
354
354
|
align-items: center !important;
|
|
355
355
|
gap: 12px !important;
|
|
356
|
-
cursor: ${
|
|
356
|
+
cursor: ${isPermissionFormBusy || isOtherPermissionDisabled ? 'not-allowed' : 'pointer'} !important;
|
|
357
357
|
padding: 8px !important;
|
|
358
358
|
border-radius: 6px !important;
|
|
359
359
|
transition: background-color 0.2s !important;
|
|
360
|
-
opacity: ${
|
|
360
|
+
opacity: ${isPermissionFormBusy || isOtherPermissionDisabled ? 0.6 : 1} !important;
|
|
361
361
|
|
|
362
362
|
&:hover {
|
|
363
|
-
background-color: ${!
|
|
363
|
+
background-color: ${!isPermissionFormBusy && !isOtherPermissionDisabled ? '#e9ecef' : 'transparent'} !important;
|
|
364
364
|
}
|
|
365
365
|
`, children: [_jsx("input", { type: "checkbox", checked: isChecked, onChange: () => {
|
|
366
|
-
if (!
|
|
366
|
+
if (!isPermissionFormBusy) {
|
|
367
367
|
if (isAllPermission) {
|
|
368
368
|
// Handle ALL permission toggle
|
|
369
369
|
if (isAllSelected) {
|
|
@@ -392,11 +392,11 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
392
392
|
setHasUserInteracted(true);
|
|
393
393
|
setIsDisabled(false);
|
|
394
394
|
}
|
|
395
|
-
}, disabled:
|
|
395
|
+
}, disabled: isPermissionFormBusy || runtimePermissionsUnavailable || isOtherPermissionDisabled, css: css `
|
|
396
396
|
margin: 0 !important;
|
|
397
397
|
width: 18px !important;
|
|
398
398
|
height: 18px !important;
|
|
399
|
-
cursor: ${
|
|
399
|
+
cursor: ${isPermissionFormBusy || isOtherPermissionDisabled ? 'not-allowed' : 'pointer'} !important;
|
|
400
400
|
` }), _jsx("span", { css: css `
|
|
401
401
|
font-size: 14px !important;
|
|
402
402
|
color: ${isOtherPermissionDisabled ? '#999' : '#333'} !important;
|
|
@@ -425,13 +425,13 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
425
425
|
background-color: #e9ecef !important;
|
|
426
426
|
border-color: #ced4da !important;
|
|
427
427
|
}
|
|
428
|
-
`, children: "Cancel" }), _jsx("button", { onClick: handleSave, disabled: !hasPermissionChanges() ||
|
|
428
|
+
`, children: "Cancel" }), _jsx("button", { onClick: handleSave, disabled: !hasPermissionChanges() || isPermissionFormBusy || runtimePermissionsUnavailable, css: css `
|
|
429
429
|
padding: 10px 20px !important;
|
|
430
|
-
background-color: ${!hasPermissionChanges() ||
|
|
431
|
-
color: ${!hasPermissionChanges() ||
|
|
430
|
+
background-color: ${!hasPermissionChanges() || isPermissionFormBusy ? '#e9ecef' : '#007bff'} !important;
|
|
431
|
+
color: ${!hasPermissionChanges() || isPermissionFormBusy ? '#6c757d' : 'white'} !important;
|
|
432
432
|
border: none !important;
|
|
433
433
|
border-radius: 8px !important;
|
|
434
|
-
cursor: ${!hasPermissionChanges() ||
|
|
434
|
+
cursor: ${!hasPermissionChanges() || isPermissionFormBusy ? 'not-allowed' : 'pointer'} !important;
|
|
435
435
|
font-size: 14px !important;
|
|
436
436
|
font-weight: 500 !important;
|
|
437
437
|
transition: all 0.2s !important;
|
|
@@ -444,5 +444,5 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
444
444
|
&:hover:not(:disabled) {
|
|
445
445
|
background-color: #0056b3 !important;
|
|
446
446
|
}
|
|
447
|
-
`, children:
|
|
447
|
+
`, children: isPermissionSaving ? 'Saving...' : isAITLoading ? 'Refreshing...' : 'Save' })] })] }))] }));
|
|
448
448
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytexbyte/nxtlinq-ai-agent-ui-react-development",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
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",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@bytexbyte/nxtlinq-ai-agent-core-development": "2.0.5",
|
|
42
|
-
"@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.
|
|
42
|
+
"@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.7",
|
|
43
43
|
"@emotion/react": "^11.14.0",
|
|
44
44
|
"@emotion/styled": "^11.14.1",
|
|
45
45
|
"@mui/icons-material": "^7.2.0",
|
|
@@ -58,6 +58,19 @@ import {
|
|
|
58
58
|
|
|
59
59
|
const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
|
|
60
60
|
|
|
61
|
+
interface PermissionSaveState {
|
|
62
|
+
operationId: number;
|
|
63
|
+
subjectKey: string;
|
|
64
|
+
permissions: string[];
|
|
65
|
+
status: 'saving' | 'failed';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface PermissionSaveOperation {
|
|
69
|
+
operationId: number;
|
|
70
|
+
subjectKey: string;
|
|
71
|
+
promise: Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
|
|
61
74
|
const ChatBotContext = React.createContext<ChatBotContextType | undefined>(undefined);
|
|
62
75
|
|
|
63
76
|
export const useChatBot = () => {
|
|
@@ -186,6 +199,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
186
199
|
const [showPermissionForm, setShowPermissionForm] = React.useState(false);
|
|
187
200
|
const [isPermissionFormOpen, setIsPermissionFormOpen] = React.useState(false);
|
|
188
201
|
const [isAITLoading, setIsAITLoading] = React.useState(false);
|
|
202
|
+
const [permissionSaveState, setPermissionSaveState] = React.useState<PermissionSaveState | null>(null);
|
|
189
203
|
const [isDisabled, setIsDisabled] = React.useState(true);
|
|
190
204
|
const [signer, setSigner] = React.useState<ethers.JsonRpcSigner | null>(null);
|
|
191
205
|
const [walletInfo, setWalletInfo] = React.useState<any>(null);
|
|
@@ -272,6 +286,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
272
286
|
}, []);
|
|
273
287
|
const runtimeRecomputeCoordinatorRef = React.useRef(new RuntimeAITRecomputeCoordinator());
|
|
274
288
|
const runtimeMutationQueueRef = React.useRef(new RuntimeAITMutationQueue());
|
|
289
|
+
const permissionSaveOperationRef = React.useRef<PermissionSaveOperation | null>(null);
|
|
290
|
+
const permissionSaveOperationIdRef = React.useRef(0);
|
|
275
291
|
useProviderRuntimeCommit(
|
|
276
292
|
hitAddressRef,
|
|
277
293
|
hitAddress,
|
|
@@ -1179,6 +1195,17 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
1179
1195
|
return;
|
|
1180
1196
|
}
|
|
1181
1197
|
|
|
1198
|
+
// updateActivePermissions publishes the authoritative result itself. A modal reopened while
|
|
1199
|
+
// that mutation is still running must keep rendering its submitted draft instead of queuing
|
|
1200
|
+
// a redundant GET that replaces the form with a loading state.
|
|
1201
|
+
const activePermissionSave = permissionSaveOperationRef.current;
|
|
1202
|
+
if (
|
|
1203
|
+
runtimeContext
|
|
1204
|
+
&& activePermissionSave?.subjectKey === runtimeAITSubjectKey(runtimeContext)
|
|
1205
|
+
) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1182
1209
|
authorizationLoadingStateRef.current.setAITLoading(true);
|
|
1183
1210
|
setIsAITLoading(true);
|
|
1184
1211
|
try {
|
|
@@ -2677,41 +2704,71 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2677
2704
|
// Save permissions
|
|
2678
2705
|
const savePermissions = async (newPermissions?: string[]) => {
|
|
2679
2706
|
setIsDisabled(true);
|
|
2680
|
-
|
|
2681
|
-
if (!hitAddress) {
|
|
2682
|
-
throw new Error('Please connect your wallet first');
|
|
2683
|
-
}
|
|
2684
|
-
const context: RuntimeAITContext = {
|
|
2685
|
-
controller: hitAddress,
|
|
2686
|
-
serviceId,
|
|
2687
|
-
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2688
|
-
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2689
|
-
};
|
|
2690
|
-
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2691
|
-
await runtimeMutationQueueRef.current.run(
|
|
2692
|
-
runtimeAITSubjectKey(context),
|
|
2693
|
-
async () => {
|
|
2694
|
-
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2695
|
-
await replaceRuntimeActivePermissions(context, checkedPermissions);
|
|
2696
|
-
},
|
|
2697
|
-
);
|
|
2698
|
-
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2699
|
-
setShowPermissionForm(false);
|
|
2700
|
-
setIsPermissionFormOpen(false);
|
|
2701
|
-
await retryPendingTextTool();
|
|
2702
|
-
} catch (error) {
|
|
2703
|
-
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2704
|
-
console.error('Failed to update AIT deny-list:', error);
|
|
2705
|
-
}
|
|
2707
|
+
if (!hitAddress) {
|
|
2706
2708
|
setIsDisabled(false);
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
} else if (error instanceof Error) {
|
|
2710
|
-
showError(error.message);
|
|
2711
|
-
} else {
|
|
2712
|
-
showError('Failed to save permissions. Please try again.');
|
|
2713
|
-
}
|
|
2709
|
+
showError('Please connect your wallet first');
|
|
2710
|
+
return;
|
|
2714
2711
|
}
|
|
2712
|
+
|
|
2713
|
+
const context: RuntimeAITContext = {
|
|
2714
|
+
controller: hitAddress,
|
|
2715
|
+
serviceId,
|
|
2716
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2717
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2718
|
+
};
|
|
2719
|
+
const subjectKey = runtimeAITSubjectKey(context);
|
|
2720
|
+
const activeOperation = permissionSaveOperationRef.current;
|
|
2721
|
+
if (activeOperation?.subjectKey === subjectKey) {
|
|
2722
|
+
return activeOperation.promise;
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2726
|
+
const operationId = ++permissionSaveOperationIdRef.current;
|
|
2727
|
+
setPermissionSaveState({
|
|
2728
|
+
operationId,
|
|
2729
|
+
subjectKey,
|
|
2730
|
+
permissions: checkedPermissions,
|
|
2731
|
+
status: 'saving',
|
|
2732
|
+
});
|
|
2733
|
+
|
|
2734
|
+
const operation = (async () => {
|
|
2735
|
+
try {
|
|
2736
|
+
await runtimeMutationQueueRef.current.run(
|
|
2737
|
+
subjectKey,
|
|
2738
|
+
async () => {
|
|
2739
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2740
|
+
await replaceRuntimeActivePermissions(context, checkedPermissions);
|
|
2741
|
+
},
|
|
2742
|
+
);
|
|
2743
|
+
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2744
|
+
setShowPermissionForm(false);
|
|
2745
|
+
setIsPermissionFormOpen(false);
|
|
2746
|
+
setPermissionSaveState((current) => current?.operationId === operationId ? null : current);
|
|
2747
|
+
await retryPendingTextTool();
|
|
2748
|
+
} catch (error) {
|
|
2749
|
+
setPermissionSaveState((current) => current?.operationId === operationId
|
|
2750
|
+
? { ...current, status: 'failed' }
|
|
2751
|
+
: current);
|
|
2752
|
+
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2753
|
+
console.error('Failed to update AIT deny-list:', error);
|
|
2754
|
+
}
|
|
2755
|
+
setIsDisabled(false);
|
|
2756
|
+
if (error instanceof StaleRuntimeAITResponseError) {
|
|
2757
|
+
return;
|
|
2758
|
+
} else if (error instanceof Error) {
|
|
2759
|
+
showError(error.message);
|
|
2760
|
+
} else {
|
|
2761
|
+
showError('Failed to save permissions. Please try again.');
|
|
2762
|
+
}
|
|
2763
|
+
} finally {
|
|
2764
|
+
if (permissionSaveOperationRef.current?.operationId === operationId) {
|
|
2765
|
+
permissionSaveOperationRef.current = null;
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
})();
|
|
2769
|
+
|
|
2770
|
+
permissionSaveOperationRef.current = { operationId, subjectKey, promise: operation };
|
|
2771
|
+
return operation;
|
|
2715
2772
|
};
|
|
2716
2773
|
|
|
2717
2774
|
// Handle verify wallet click
|
|
@@ -2998,6 +3055,10 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2998
3055
|
|
|
2999
3056
|
const runtimeAuthorizationMatchesRenderedContext =
|
|
3000
3057
|
runtimeAuthorizationMatchesContext(runtimeAuthorizationContextKey, runtimeContext);
|
|
3058
|
+
const renderedPermissionSaveState = runtimeContext
|
|
3059
|
+
&& permissionSaveState?.subjectKey === runtimeAITSubjectKey(runtimeContext)
|
|
3060
|
+
? permissionSaveState
|
|
3061
|
+
: null;
|
|
3001
3062
|
const contextValue: ChatBotContextType = {
|
|
3002
3063
|
// State
|
|
3003
3064
|
messages,
|
|
@@ -3018,6 +3079,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3018
3079
|
showPermissionForm,
|
|
3019
3080
|
isPermissionFormOpen,
|
|
3020
3081
|
isAITLoading,
|
|
3082
|
+
permissionSaveDraft: renderedPermissionSaveState?.permissions ?? null,
|
|
3083
|
+
isPermissionSaving: renderedPermissionSaveState?.status === 'saving',
|
|
3021
3084
|
isDisabled,
|
|
3022
3085
|
walletInfo,
|
|
3023
3086
|
isWalletLoading,
|
|
@@ -107,6 +107,8 @@ export interface ChatBotContextType {
|
|
|
107
107
|
showPermissionForm: boolean;
|
|
108
108
|
isPermissionFormOpen: boolean;
|
|
109
109
|
isAITLoading: boolean;
|
|
110
|
+
permissionSaveDraft: string[] | null;
|
|
111
|
+
isPermissionSaving: boolean;
|
|
110
112
|
isAITEnabling: boolean;
|
|
111
113
|
isDisabled: boolean;
|
|
112
114
|
walletInfo: any;
|
|
@@ -25,24 +25,31 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
25
25
|
onVerifyWallet,
|
|
26
26
|
serviceId,
|
|
27
27
|
isAITLoading,
|
|
28
|
+
permissionSaveDraft,
|
|
29
|
+
isPermissionSaving,
|
|
28
30
|
isWalletLoading = false,
|
|
29
31
|
refreshAIT,
|
|
30
32
|
props
|
|
31
33
|
} = useChatBot();
|
|
32
34
|
|
|
33
|
-
const [
|
|
34
|
-
const [tempPermissions, setTempPermissions] = React.useState<string[]>(permissions);
|
|
35
|
+
const [tempPermissions, setTempPermissions] = React.useState<string[]>(permissionSaveDraft ?? permissions);
|
|
35
36
|
const [hasUserInteracted, setHasUserInteracted] = React.useState(false);
|
|
37
|
+
const isPermissionFormBusy = isAITLoading || isPermissionSaving;
|
|
38
|
+
const hasPermissionSnapshot = permissionSaveDraft !== null
|
|
39
|
+
|| availablePermissions.length > 0
|
|
40
|
+
|| permissions.length > 0;
|
|
36
41
|
|
|
37
42
|
// Check if ALL permission is selected
|
|
38
43
|
const isAllSelected = tempPermissions.includes('ALL');
|
|
39
44
|
|
|
40
45
|
// Update temp permissions when permissions change, but only if user hasn't interacted
|
|
41
46
|
React.useEffect(() => {
|
|
42
|
-
if (
|
|
47
|
+
if (permissionSaveDraft) {
|
|
48
|
+
setTempPermissions(permissionSaveDraft);
|
|
49
|
+
} else if (!hasUserInteracted) {
|
|
43
50
|
setTempPermissions(permissions);
|
|
44
51
|
}
|
|
45
|
-
}, [permissions, hasUserInteracted]);
|
|
52
|
+
}, [permissions, permissionSaveDraft, hasUserInteracted]);
|
|
46
53
|
|
|
47
54
|
// When ALL is selected, automatically select all other permissions
|
|
48
55
|
// This handles cases where ALL is set from initial permissions or when availablePermissions loads
|
|
@@ -86,13 +93,8 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
86
93
|
&& (!walletInfo?.id || !hasRecordedWalletVerification(walletInfo));
|
|
87
94
|
|
|
88
95
|
const handleSave = async () => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
await onSave(tempPermissions);
|
|
92
|
-
setHasUserInteracted(false);
|
|
93
|
-
} finally {
|
|
94
|
-
setIsSaving(false);
|
|
95
|
-
}
|
|
96
|
+
await onSave(tempPermissions);
|
|
97
|
+
setHasUserInteracted(false);
|
|
96
98
|
};
|
|
97
99
|
|
|
98
100
|
const handleCancel = () => {
|
|
@@ -439,7 +441,7 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
439
441
|
color: #666 !important;
|
|
440
442
|
flex-shrink: 0 !important;
|
|
441
443
|
`}>Permissions</h4>
|
|
442
|
-
{isAITLoading ? (
|
|
444
|
+
{isAITLoading && !hasPermissionSnapshot ? (
|
|
443
445
|
<div css={css`
|
|
444
446
|
background-color: #f8f9fa !important;
|
|
445
447
|
padding: 16px !important;
|
|
@@ -489,14 +491,14 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
489
491
|
display: flex !important;
|
|
490
492
|
align-items: center !important;
|
|
491
493
|
gap: 12px !important;
|
|
492
|
-
cursor: ${
|
|
494
|
+
cursor: ${isPermissionFormBusy || isOtherPermissionDisabled ? 'not-allowed' : 'pointer'} !important;
|
|
493
495
|
padding: 8px !important;
|
|
494
496
|
border-radius: 6px !important;
|
|
495
497
|
transition: background-color 0.2s !important;
|
|
496
|
-
opacity: ${
|
|
498
|
+
opacity: ${isPermissionFormBusy || isOtherPermissionDisabled ? 0.6 : 1} !important;
|
|
497
499
|
|
|
498
500
|
&:hover {
|
|
499
|
-
background-color: ${!
|
|
501
|
+
background-color: ${!isPermissionFormBusy && !isOtherPermissionDisabled ? '#e9ecef' : 'transparent'} !important;
|
|
500
502
|
}
|
|
501
503
|
`}
|
|
502
504
|
>
|
|
@@ -504,7 +506,7 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
504
506
|
type="checkbox"
|
|
505
507
|
checked={isChecked}
|
|
506
508
|
onChange={() => {
|
|
507
|
-
if (!
|
|
509
|
+
if (!isPermissionFormBusy) {
|
|
508
510
|
if (isAllPermission) {
|
|
509
511
|
// Handle ALL permission toggle
|
|
510
512
|
if (isAllSelected) {
|
|
@@ -532,12 +534,12 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
532
534
|
setIsDisabled(false);
|
|
533
535
|
}
|
|
534
536
|
}}
|
|
535
|
-
disabled={
|
|
537
|
+
disabled={isPermissionFormBusy || runtimePermissionsUnavailable || isOtherPermissionDisabled}
|
|
536
538
|
css={css`
|
|
537
539
|
margin: 0 !important;
|
|
538
540
|
width: 18px !important;
|
|
539
541
|
height: 18px !important;
|
|
540
|
-
cursor: ${
|
|
542
|
+
cursor: ${isPermissionFormBusy || isOtherPermissionDisabled ? 'not-allowed' : 'pointer'} !important;
|
|
541
543
|
`}
|
|
542
544
|
/>
|
|
543
545
|
<span css={css`
|
|
@@ -584,14 +586,14 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
584
586
|
</button>
|
|
585
587
|
<button
|
|
586
588
|
onClick={handleSave}
|
|
587
|
-
disabled={!hasPermissionChanges() ||
|
|
589
|
+
disabled={!hasPermissionChanges() || isPermissionFormBusy || runtimePermissionsUnavailable}
|
|
588
590
|
css={css`
|
|
589
591
|
padding: 10px 20px !important;
|
|
590
|
-
background-color: ${!hasPermissionChanges() ||
|
|
591
|
-
color: ${!hasPermissionChanges() ||
|
|
592
|
+
background-color: ${!hasPermissionChanges() || isPermissionFormBusy ? '#e9ecef' : '#007bff'} !important;
|
|
593
|
+
color: ${!hasPermissionChanges() || isPermissionFormBusy ? '#6c757d' : 'white'} !important;
|
|
592
594
|
border: none !important;
|
|
593
595
|
border-radius: 8px !important;
|
|
594
|
-
cursor: ${!hasPermissionChanges() ||
|
|
596
|
+
cursor: ${!hasPermissionChanges() || isPermissionFormBusy ? 'not-allowed' : 'pointer'} !important;
|
|
595
597
|
font-size: 14px !important;
|
|
596
598
|
font-weight: 500 !important;
|
|
597
599
|
transition: all 0.2s !important;
|
|
@@ -606,7 +608,7 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
606
608
|
}
|
|
607
609
|
`}
|
|
608
610
|
>
|
|
609
|
-
{
|
|
611
|
+
{isPermissionSaving ? 'Saving...' : isAITLoading ? 'Refreshing...' : 'Save'}
|
|
610
612
|
</button>
|
|
611
613
|
</div>
|
|
612
614
|
</>
|