@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.3.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context/ChatBotContext.d.ts.map +1 -1
- package/dist/context/ChatBotContext.js +179 -160
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/permissionState.d.ts +53 -0
- package/dist/permissionState.d.ts.map +1 -0
- package/dist/permissionState.js +217 -0
- package/dist/types/ChatBotTypes.d.ts +6 -5
- package/dist/types/ChatBotTypes.d.ts.map +1 -1
- package/dist/ui/ModelSelector.js +2 -2
- package/dist/ui/PermissionForm.d.ts.map +1 -1
- package/dist/ui/PermissionForm.js +14 -28
- package/package.json +3 -3
- package/src/context/ChatBotContext.tsx +252 -195
- package/src/index.ts +0 -1
- package/src/permissionState.ts +313 -0
- package/src/types/ChatBotTypes.ts +7 -7
- package/src/ui/ModelSelector.tsx +5 -5
- package/src/ui/PermissionForm.tsx +20 -31
- package/dist/NxtlinqAgentChat.d.ts +0 -26
- package/dist/NxtlinqAgentChat.d.ts.map +0 -1
- package/dist/NxtlinqAgentChat.js +0 -28
- package/dist/components/AgentAssistantShell.d.ts +0 -5
- package/dist/components/AgentAssistantShell.d.ts.map +0 -1
- package/dist/components/AgentAssistantShell.js +0 -52
- package/dist/components/AgentComposer.d.ts +0 -3
- package/dist/components/AgentComposer.d.ts.map +0 -1
- package/dist/components/AgentComposer.js +0 -60
- package/dist/components/AgentMessageList.d.ts +0 -3
- package/dist/components/AgentMessageList.d.ts.map +0 -1
- package/dist/components/AgentMessageList.js +0 -37
- package/dist/components/AgentRemoteAudio.d.ts +0 -4
- package/dist/components/AgentRemoteAudio.d.ts.map +0 -1
- package/dist/components/AgentRemoteAudio.js +0 -34
- package/dist/components/AgentVoiceBar.d.ts +0 -3
- package/dist/components/AgentVoiceBar.d.ts.map +0 -1
- package/dist/components/AgentVoiceBar.js +0 -91
- package/dist/components/PresetMessageChips.d.ts +0 -3
- package/dist/components/PresetMessageChips.d.ts.map +0 -1
- package/dist/components/PresetMessageChips.js +0 -23
- package/dist/context/AgentAssistantContext.d.ts +0 -32
- package/dist/context/AgentAssistantContext.d.ts.map +0 -1
- package/dist/context/AgentAssistantContext.js +0 -179
- package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts +0 -2
- package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts.map +0 -1
- package/dist/legacy/assets/images/adiSideItalicDataUri.js +0 -1
- package/dist/legacy/chatbot/ChatBot.d.ts +0 -5
- package/dist/legacy/chatbot/ChatBot.d.ts.map +0 -1
- package/dist/legacy/chatbot/ChatBot.js +0 -35
- package/dist/legacy/chatbot/context/ChatBotContext.d.ts +0 -5
- package/dist/legacy/chatbot/context/ChatBotContext.d.ts.map +0 -1
- package/dist/legacy/chatbot/context/ChatBotContext.js +0 -2922
- package/dist/legacy/chatbot/types/ChatBotTypes.d.ts +0 -166
- package/dist/legacy/chatbot/types/ChatBotTypes.d.ts.map +0 -1
- package/dist/legacy/chatbot/types/ChatBotTypes.js +0 -1
- package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts +0 -17
- package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/BerifyMeModal.js +0 -110
- package/dist/legacy/chatbot/ui/ChatBotHeader.d.ts +0 -15
- package/dist/legacy/chatbot/ui/ChatBotHeader.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/ChatBotHeader.js +0 -62
- package/dist/legacy/chatbot/ui/ChatBotUI.d.ts +0 -3
- package/dist/legacy/chatbot/ui/ChatBotUI.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/ChatBotUI.js +0 -557
- package/dist/legacy/chatbot/ui/MessageInput.d.ts +0 -3
- package/dist/legacy/chatbot/ui/MessageInput.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/MessageInput.js +0 -321
- package/dist/legacy/chatbot/ui/MessageList.d.ts +0 -4
- package/dist/legacy/chatbot/ui/MessageList.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/MessageList.js +0 -455
- package/dist/legacy/chatbot/ui/ModelSelector.d.ts +0 -4
- package/dist/legacy/chatbot/ui/ModelSelector.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/ModelSelector.js +0 -122
- package/dist/legacy/chatbot/ui/NotificationModal.d.ts +0 -15
- package/dist/legacy/chatbot/ui/NotificationModal.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/NotificationModal.js +0 -53
- package/dist/legacy/chatbot/ui/PermissionForm.d.ts +0 -8
- package/dist/legacy/chatbot/ui/PermissionForm.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/PermissionForm.js +0 -465
- package/dist/legacy/chatbot/ui/PresetMessages.d.ts +0 -4
- package/dist/legacy/chatbot/ui/PresetMessages.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/PresetMessages.js +0 -33
- package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts +0 -3
- package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/VoiceModePanel.js +0 -95
- package/dist/legacy/chatbot/ui/chatBotHeaderParts.d.ts +0 -15
- package/dist/legacy/chatbot/ui/chatBotHeaderParts.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/chatBotHeaderParts.js +0 -50
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts +0 -73
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.js +0 -985
- package/dist/legacy/index.d.ts +0 -14
- package/dist/legacy/index.d.ts.map +0 -1
- package/dist/legacy/index.js +0 -12
- package/dist/theme/defaultTheme.d.ts +0 -3
- package/dist/theme/defaultTheme.d.ts.map +0 -1
- package/dist/theme/defaultTheme.js +0 -20
- package/dist/types.d.ts +0 -62
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -1
- package/dist/voice/useVoiceConnectOrchestration.d.ts +0 -21
- package/dist/voice/useVoiceConnectOrchestration.d.ts.map +0 -1
- package/dist/voice/useVoiceConnectOrchestration.js +0 -86
- package/dist/voice/useVoiceMicState.d.ts +0 -15
- package/dist/voice/useVoiceMicState.d.ts.map +0 -1
- package/dist/voice/useVoiceMicState.js +0 -94
- package/dist/voice/useVoiceSilenceCommit.d.ts +0 -10
- package/dist/voice/useVoiceSilenceCommit.d.ts.map +0 -1
- package/dist/voice/useVoiceSilenceCommit.js +0 -67
- package/dist/voice/useVoiceTranscriptMessages.d.ts +0 -18
- package/dist/voice/useVoiceTranscriptMessages.d.ts.map +0 -1
- package/dist/voice/useVoiceTranscriptMessages.js +0 -132
- package/dist/voice/useWsRealtimeAudio.d.ts +0 -18
- package/dist/voice/useWsRealtimeAudio.d.ts.map +0 -1
- package/dist/voice/useWsRealtimeAudio.js +0 -102
- package/dist/voice/voiceMicConstants.d.ts +0 -4
- package/dist/voice/voiceMicConstants.d.ts.map +0 -1
- package/dist/voice/voiceMicConstants.js +0 -10
- package/dist/voice/voiceUserBubble.d.ts +0 -10
- package/dist/voice/voiceUserBubble.d.ts.map +0 -1
- package/dist/voice/voiceUserBubble.js +0 -52
- package/dist/voice/ws/BrowserWsPcmPlayer.d.ts +0 -23
- package/dist/voice/ws/BrowserWsPcmPlayer.d.ts.map +0 -1
- package/dist/voice/ws/BrowserWsPcmPlayer.js +0 -137
- package/dist/voice/ws/BrowserWsPcmRecorder.d.ts +0 -17
- package/dist/voice/ws/BrowserWsPcmRecorder.d.ts.map +0 -1
- package/dist/voice/ws/BrowserWsPcmRecorder.js +0 -71
- package/dist/voice/ws/float32ToPcm16.d.ts +0 -2
- package/dist/voice/ws/float32ToPcm16.d.ts.map +0 -1
- package/dist/voice/ws/float32ToPcm16.js +0 -8
- package/dist/voice/ws/voiceSilenceConstants.d.ts +0 -5
- package/dist/voice/ws/voiceSilenceConstants.d.ts.map +0 -1
- package/dist/voice/ws/voiceSilenceConstants.js +0 -4
- package/dist/voice/ws/wsRealtimeConstants.d.ts +0 -2
- package/dist/voice/ws/wsRealtimeConstants.d.ts.map +0 -1
- package/dist/voice/ws/wsRealtimeConstants.js +0 -1
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
Attachment,
|
|
24
24
|
ClientTtsVoiceSettings,
|
|
25
25
|
Message,
|
|
26
|
+
RuntimeAITResult,
|
|
26
27
|
ServicePermission,
|
|
27
28
|
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
28
29
|
import {
|
|
@@ -31,6 +32,22 @@ import {
|
|
|
31
32
|
ChatBotProps,
|
|
32
33
|
PresetMessage
|
|
33
34
|
} from '../types/ChatBotTypes';
|
|
35
|
+
import {
|
|
36
|
+
dispatchRuntimeAITCompleteReplacement,
|
|
37
|
+
removeOneDeniedPermission,
|
|
38
|
+
replaceCurrentMaximumDenyList,
|
|
39
|
+
RuntimeAITMutationQueue,
|
|
40
|
+
RuntimeAITRecomputeCoordinator,
|
|
41
|
+
StaleRuntimeAITResponseError,
|
|
42
|
+
runtimeAITContextKey,
|
|
43
|
+
runtimeAITSubjectKey,
|
|
44
|
+
runtimeAuthorizationMatchesContext,
|
|
45
|
+
runtimeAuthorizationState,
|
|
46
|
+
unavailableRuntimeAuthorization,
|
|
47
|
+
useProviderRuntimeCommit,
|
|
48
|
+
useRuntimeAITContextCommit,
|
|
49
|
+
type RuntimeAITContext,
|
|
50
|
+
} from '../permissionState';
|
|
34
51
|
|
|
35
52
|
const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
|
|
36
53
|
|
|
@@ -61,6 +78,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
61
78
|
environment = 'production',
|
|
62
79
|
onVerifyWallet,
|
|
63
80
|
permissionGroup,
|
|
81
|
+
roles,
|
|
64
82
|
children,
|
|
65
83
|
// AI Model related attributes
|
|
66
84
|
onModelChange,
|
|
@@ -85,9 +103,6 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
85
103
|
debugVoiceRms = false,
|
|
86
104
|
sttGlossary,
|
|
87
105
|
}) => {
|
|
88
|
-
// Set API hosts immediately based on environment (before any API calls)
|
|
89
|
-
setApiHosts(environment);
|
|
90
|
-
|
|
91
106
|
const nxtlinqApi = React.useMemo(
|
|
92
107
|
() => (serviceToken || getAuthToken
|
|
93
108
|
? createNxtlinqApi({ apiKey, apiSecret, serviceToken, getAuthToken })
|
|
@@ -147,7 +162,22 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
147
162
|
const [hitAddress, setHitAddress] = React.useState<string | null>(null);
|
|
148
163
|
const [ait, setAit] = React.useState<AIT | null>(null);
|
|
149
164
|
const [permissions, setPermissions] = React.useState<string[]>([]);
|
|
150
|
-
const [
|
|
165
|
+
const [maximumPermissions, setMaximumPermissions] = React.useState<string[]>([]);
|
|
166
|
+
const [deniedPermissions, setDeniedPermissions] = React.useState<string[]>([]);
|
|
167
|
+
const [runtimePermissionsUnavailable, setRuntimePermissionsUnavailable] = React.useState(false);
|
|
168
|
+
const [runtimeAuthorizationContextKey, setRuntimeAuthorizationContextKey] =
|
|
169
|
+
React.useState<string | null>(null);
|
|
170
|
+
const [servicePermissionCatalog, setServicePermissionCatalog] = React.useState<ServicePermission[]>([]);
|
|
171
|
+
const availablePermissions = React.useMemo(
|
|
172
|
+
() => maximumPermissions.map((label) =>
|
|
173
|
+
servicePermissionCatalog.find((permission) => permission.label === label) ?? {
|
|
174
|
+
id: label,
|
|
175
|
+
label,
|
|
176
|
+
description: '',
|
|
177
|
+
groups: [],
|
|
178
|
+
}),
|
|
179
|
+
[maximumPermissions, servicePermissionCatalog],
|
|
180
|
+
);
|
|
151
181
|
const [showPermissionForm, setShowPermissionForm] = React.useState(false);
|
|
152
182
|
const [isPermissionFormOpen, setIsPermissionFormOpen] = React.useState(false);
|
|
153
183
|
const [isAITLoading, setIsAITLoading] = React.useState(false);
|
|
@@ -156,6 +186,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
156
186
|
const [walletInfo, setWalletInfo] = React.useState<any>(null);
|
|
157
187
|
const [isWalletLoading, setIsWalletLoading] = React.useState(false);
|
|
158
188
|
const [isAutoConnecting, setIsAutoConnecting] = React.useState(false);
|
|
189
|
+
const runtimeRolesKey = JSON.stringify(roles ?? null);
|
|
159
190
|
|
|
160
191
|
// Persistent data (always use localStorage)
|
|
161
192
|
const [nxtlinqAITServiceAccessToken, setNxtlinqAITServiceAccessToken] = useLocalStorage<string>('nxtlinqAITServiceAccessToken', '');
|
|
@@ -212,8 +243,17 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
212
243
|
const hitAddressRef = React.useRef(hitAddress);
|
|
213
244
|
const aitRef = React.useRef(ait);
|
|
214
245
|
const permissionsRef = React.useRef(permissions);
|
|
246
|
+
const deniedPermissionsRef = React.useRef(deniedPermissions);
|
|
215
247
|
const nxtlinqAITServiceAccessTokenRef = React.useRef(nxtlinqAITServiceAccessToken);
|
|
216
248
|
const signerRef = React.useRef(signer);
|
|
249
|
+
const runtimeRecomputeCoordinatorRef = React.useRef(new RuntimeAITRecomputeCoordinator());
|
|
250
|
+
const runtimeMutationQueueRef = React.useRef(new RuntimeAITMutationQueue());
|
|
251
|
+
useProviderRuntimeCommit(
|
|
252
|
+
hitAddressRef,
|
|
253
|
+
hitAddress,
|
|
254
|
+
environment,
|
|
255
|
+
setApiHosts,
|
|
256
|
+
);
|
|
217
257
|
|
|
218
258
|
// Helper function to combine customUsername with Adilas customUserInfo
|
|
219
259
|
const getFinalCustomUsername = React.useCallback((username: string | undefined): string | undefined => {
|
|
@@ -546,10 +586,6 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
546
586
|
}, []);
|
|
547
587
|
|
|
548
588
|
// Update refs when state changes
|
|
549
|
-
React.useEffect(() => {
|
|
550
|
-
hitAddressRef.current = hitAddress;
|
|
551
|
-
}, [hitAddress]);
|
|
552
|
-
|
|
553
589
|
React.useEffect(() => {
|
|
554
590
|
aitRef.current = ait;
|
|
555
591
|
}, [ait]);
|
|
@@ -558,6 +594,10 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
558
594
|
permissionsRef.current = permissions;
|
|
559
595
|
}, [permissions]);
|
|
560
596
|
|
|
597
|
+
React.useEffect(() => {
|
|
598
|
+
deniedPermissionsRef.current = deniedPermissions;
|
|
599
|
+
}, [deniedPermissions]);
|
|
600
|
+
|
|
561
601
|
React.useEffect(() => {
|
|
562
602
|
nxtlinqAITServiceAccessTokenRef.current = nxtlinqAITServiceAccessToken;
|
|
563
603
|
}, [nxtlinqAITServiceAccessToken]);
|
|
@@ -979,7 +1019,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
979
1019
|
console.error('Failed to fetch permissions:', result.error);
|
|
980
1020
|
return undefined;
|
|
981
1021
|
}
|
|
982
|
-
|
|
1022
|
+
setServicePermissionCatalog(result.permissions);
|
|
983
1023
|
return result.permissions;
|
|
984
1024
|
} catch (error) {
|
|
985
1025
|
console.error('Error fetching permissions:', error);
|
|
@@ -987,12 +1027,116 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
987
1027
|
}
|
|
988
1028
|
};
|
|
989
1029
|
|
|
990
|
-
|
|
1030
|
+
const clearRuntimeAuthorization = React.useCallback(() => {
|
|
1031
|
+
const cleared = unavailableRuntimeAuthorization(deniedPermissionsRef.current);
|
|
1032
|
+
const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
|
|
1033
|
+
aitRef.current = null;
|
|
1034
|
+
permissionsRef.current = [];
|
|
1035
|
+
setAit(cleared.ait);
|
|
1036
|
+
setPermissions(cleared.effectivePermissions);
|
|
1037
|
+
setMaximumPermissions(cleared.maximumPermissions);
|
|
1038
|
+
setRuntimePermissionsUnavailable(cleared.unavailable);
|
|
1039
|
+
setRuntimeAuthorizationContextKey(
|
|
1040
|
+
activeContext ? runtimeAITContextKey(activeContext) : null,
|
|
1041
|
+
);
|
|
1042
|
+
}, []);
|
|
1043
|
+
|
|
1044
|
+
const applyRuntimeResult = React.useCallback((result: RuntimeAITResult, context: RuntimeAITContext) => {
|
|
1045
|
+
const next = runtimeAuthorizationState(result, context.controller, context.serviceId);
|
|
1046
|
+
aitRef.current = next.ait;
|
|
1047
|
+
permissionsRef.current = next.effectivePermissions;
|
|
1048
|
+
setAit(next.ait);
|
|
1049
|
+
setPermissions(next.effectivePermissions);
|
|
1050
|
+
setMaximumPermissions(next.maximumPermissions);
|
|
1051
|
+
setDeniedPermissions(next.deniedPermissions);
|
|
1052
|
+
deniedPermissionsRef.current = next.deniedPermissions;
|
|
1053
|
+
setRuntimePermissionsUnavailable(false);
|
|
1054
|
+
setRuntimeAuthorizationContextKey(runtimeAITContextKey(context));
|
|
1055
|
+
return result;
|
|
1056
|
+
}, []);
|
|
1057
|
+
|
|
1058
|
+
const runtimeContext = React.useMemo<RuntimeAITContext | null>(() => hitAddress ? {
|
|
1059
|
+
controller: hitAddress,
|
|
1060
|
+
serviceId,
|
|
1061
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
1062
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
1063
|
+
} : null, [hitAddress, permissionGroup, runtimeRolesKey, serviceId]);
|
|
1064
|
+
const invalidateCommittedRuntimeContext = React.useCallback(() => {
|
|
1065
|
+
const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
|
|
1066
|
+
aitRef.current = null;
|
|
1067
|
+
permissionsRef.current = [];
|
|
1068
|
+
deniedPermissionsRef.current = [];
|
|
1069
|
+
setAit(null);
|
|
1070
|
+
setPermissions([]);
|
|
1071
|
+
setMaximumPermissions([]);
|
|
1072
|
+
setDeniedPermissions([]);
|
|
1073
|
+
setRuntimePermissionsUnavailable(activeContext !== null);
|
|
1074
|
+
setRuntimeAuthorizationContextKey(
|
|
1075
|
+
activeContext ? runtimeAITContextKey(activeContext) : null,
|
|
1076
|
+
);
|
|
1077
|
+
}, []);
|
|
1078
|
+
useRuntimeAITContextCommit(
|
|
1079
|
+
runtimeRecomputeCoordinatorRef.current,
|
|
1080
|
+
runtimeContext,
|
|
1081
|
+
invalidateCommittedRuntimeContext,
|
|
1082
|
+
);
|
|
1083
|
+
|
|
1084
|
+
const recomputeRuntimeAIT = React.useCallback(async (context: RuntimeAITContext) => {
|
|
1085
|
+
const capturedContext: RuntimeAITContext = {
|
|
1086
|
+
controller: context.controller,
|
|
1087
|
+
serviceId: context.serviceId,
|
|
1088
|
+
...(context.roles !== undefined ? { roles: [...context.roles] } : {}),
|
|
1089
|
+
...(context.permissionGroup !== undefined ? { permissionGroup: context.permissionGroup } : {}),
|
|
1090
|
+
};
|
|
1091
|
+
return runtimeRecomputeCoordinatorRef.current.run(
|
|
1092
|
+
capturedContext,
|
|
1093
|
+
() => nxtlinqApi.ait.recomputeAIT(capturedContext),
|
|
1094
|
+
applyRuntimeResult,
|
|
1095
|
+
clearRuntimeAuthorization,
|
|
1096
|
+
);
|
|
1097
|
+
}, [applyRuntimeResult, clearRuntimeAuthorization, nxtlinqApi]);
|
|
1098
|
+
|
|
1099
|
+
const queueRuntimeAITRefresh = React.useCallback(
|
|
1100
|
+
(context: RuntimeAITContext) => runtimeMutationQueueRef.current.run(
|
|
1101
|
+
runtimeAITSubjectKey(context),
|
|
1102
|
+
async () => {
|
|
1103
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
1104
|
+
return recomputeRuntimeAIT(context);
|
|
1105
|
+
},
|
|
1106
|
+
),
|
|
1107
|
+
[recomputeRuntimeAIT],
|
|
1108
|
+
);
|
|
1109
|
+
|
|
1110
|
+
const convergeRuntimeAITSubject = React.useCallback(async (subjectKey: string) => {
|
|
1111
|
+
const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
|
|
1112
|
+
if (!activeContext || runtimeAITSubjectKey(activeContext) !== subjectKey) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
await recomputeRuntimeAIT(activeContext);
|
|
1116
|
+
}, [recomputeRuntimeAIT]);
|
|
1117
|
+
|
|
1118
|
+
const dispatchRuntimeDenyListReplacement = React.useCallback(async (
|
|
1119
|
+
context: RuntimeAITContext,
|
|
1120
|
+
nextDeniedPermissions: string[],
|
|
1121
|
+
) => dispatchRuntimeAITCompleteReplacement(
|
|
1122
|
+
runtimeRecomputeCoordinatorRef.current,
|
|
1123
|
+
context,
|
|
1124
|
+
() => nxtlinqApi.ait.updatePermissionDenyList({
|
|
1125
|
+
...context,
|
|
1126
|
+
deniedPermissions: nextDeniedPermissions,
|
|
1127
|
+
}),
|
|
1128
|
+
convergeRuntimeAITSubject,
|
|
1129
|
+
clearRuntimeAuthorization,
|
|
1130
|
+
), [clearRuntimeAuthorization, convergeRuntimeAITSubject, nxtlinqApi]);
|
|
1131
|
+
|
|
1132
|
+
// Refresh the authoritative runtime AIT state.
|
|
991
1133
|
const refreshAIT = async (forceUpdatePermissions = false) => {
|
|
992
1134
|
if (!hitAddress) {
|
|
993
1135
|
setAit(null);
|
|
994
1136
|
setPermissions([]);
|
|
1137
|
+
setMaximumPermissions([]);
|
|
995
1138
|
setWalletInfo(null);
|
|
1139
|
+
setRuntimePermissionsUnavailable(false);
|
|
996
1140
|
setIsAITLoading(false);
|
|
997
1141
|
return;
|
|
998
1142
|
}
|
|
@@ -1017,35 +1161,18 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
1017
1161
|
}
|
|
1018
1162
|
}
|
|
1019
1163
|
|
|
1020
|
-
//
|
|
1164
|
+
// Recompute is the sole mint/reuse path and the only permission authority.
|
|
1021
1165
|
if (nxtlinqAITServiceAccessToken) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
controller: hitAddress,
|
|
1025
|
-
customUsername: (!requireWalletIDVVerification && customUsername) ? getFinalCustomUsername(customUsername) : undefined
|
|
1026
|
-
}, nxtlinqAITServiceAccessToken);
|
|
1027
|
-
|
|
1028
|
-
if ('error' in response) {
|
|
1029
|
-
console.error('Failed to fetch AIT:', response.error);
|
|
1030
|
-
setAit(null);
|
|
1031
|
-
setPermissions([]);
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
setAit(response);
|
|
1036
|
-
if (!isPermissionFormOpen || forceUpdatePermissions) {
|
|
1037
|
-
const newPermissions = response.metadata?.permissions || [];
|
|
1038
|
-
setPermissions(newPermissions);
|
|
1166
|
+
if (runtimeContext) {
|
|
1167
|
+
await queueRuntimeAITRefresh(runtimeContext);
|
|
1039
1168
|
}
|
|
1040
1169
|
} else {
|
|
1041
|
-
|
|
1042
|
-
setAit(null);
|
|
1043
|
-
setPermissions([]);
|
|
1170
|
+
clearRuntimeAuthorization();
|
|
1044
1171
|
}
|
|
1045
1172
|
} catch (error) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1173
|
+
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
1174
|
+
console.error('Failed to recompute AIT:', error);
|
|
1175
|
+
}
|
|
1049
1176
|
} finally {
|
|
1050
1177
|
setIsAITLoading(false);
|
|
1051
1178
|
}
|
|
@@ -1250,10 +1377,13 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
1250
1377
|
}
|
|
1251
1378
|
const { accessToken } = response;
|
|
1252
1379
|
setNxtlinqAITServiceAccessToken(accessToken);
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1380
|
+
localStorage.setItem('nxtlinqAITServiceAccessToken', JSON.stringify(accessToken));
|
|
1381
|
+
await queueRuntimeAITRefresh({
|
|
1382
|
+
controller: addressToUse,
|
|
1383
|
+
serviceId,
|
|
1384
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
1385
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
1386
|
+
});
|
|
1257
1387
|
|
|
1258
1388
|
if (autoShowSuccessMessage) {
|
|
1259
1389
|
showSuccess(walletTextUtils.getWalletText('Successfully signed in with your HIT wallet. You can now use the AI agent.', serviceId));
|
|
@@ -2717,109 +2847,6 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2717
2847
|
}
|
|
2718
2848
|
};
|
|
2719
2849
|
|
|
2720
|
-
// Generate and register AIT
|
|
2721
|
-
const generateAndRegisterAIT = async (newPermissions?: string[], isFromAIAgent = false) => {
|
|
2722
|
-
let currentSigner = signer;
|
|
2723
|
-
let currentAddress = hitAddress;
|
|
2724
|
-
|
|
2725
|
-
// If we have an address but no signer, try to auto-connect wallet
|
|
2726
|
-
if (currentAddress && !currentSigner) {
|
|
2727
|
-
const storedWalletAddress = localStorage.getItem('walletAddress');
|
|
2728
|
-
if (storedWalletAddress === currentAddress) {
|
|
2729
|
-
try {
|
|
2730
|
-
const autoConnectResult = await connectWallet(false); // Don't show sign-in message yet
|
|
2731
|
-
if (autoConnectResult) {
|
|
2732
|
-
// Wait for state to update
|
|
2733
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
2734
|
-
// Get the updated signer and address
|
|
2735
|
-
currentSigner = signerRef.current || signer;
|
|
2736
|
-
currentAddress = hitAddressRef.current || hitAddress;
|
|
2737
|
-
}
|
|
2738
|
-
} catch (error) {
|
|
2739
|
-
console.error('Auto-connect failed during AIT generation:', error);
|
|
2740
|
-
}
|
|
2741
|
-
}
|
|
2742
|
-
}
|
|
2743
|
-
|
|
2744
|
-
if (!currentSigner || !currentAddress) {
|
|
2745
|
-
throw new Error('Missing signer or wallet address');
|
|
2746
|
-
}
|
|
2747
|
-
|
|
2748
|
-
return generateAndRegisterAITWithSigner(newPermissions, isFromAIAgent, currentSigner, currentAddress);
|
|
2749
|
-
};
|
|
2750
|
-
|
|
2751
|
-
// Generate and register AIT with explicit signer and address
|
|
2752
|
-
const generateAndRegisterAITWithSigner = async (
|
|
2753
|
-
newPermissions?: string[],
|
|
2754
|
-
isFromAIAgent = false,
|
|
2755
|
-
explicitSigner?: ethers.JsonRpcSigner,
|
|
2756
|
-
explicitAddress?: string
|
|
2757
|
-
) => {
|
|
2758
|
-
const currentSigner = explicitSigner || signer;
|
|
2759
|
-
const currentAddress = explicitAddress || hitAddress;
|
|
2760
|
-
|
|
2761
|
-
if (!currentSigner || !currentAddress) {
|
|
2762
|
-
throw new Error('Missing signer or wallet address');
|
|
2763
|
-
}
|
|
2764
|
-
|
|
2765
|
-
// If AI Agent is creating, must check if user has existing AIT
|
|
2766
|
-
if (isFromAIAgent && !aitRef.current) {
|
|
2767
|
-
throw new Error('You must have an existing AIT before AI Agent can create new AITs');
|
|
2768
|
-
}
|
|
2769
|
-
|
|
2770
|
-
// aitId is assigned by AIT-Service (UUIDv7) and returned in the response. It must not be
|
|
2771
|
-
// minted here: the client cannot guarantee uniqueness, and this value feeds parentAITId, which
|
|
2772
|
-
// is part of the on-chain commitment -- a locally invented id would anchor a parent that does
|
|
2773
|
-
// not exist.
|
|
2774
|
-
|
|
2775
|
-
const metadata = {
|
|
2776
|
-
permissions: newPermissions || permissions,
|
|
2777
|
-
issuedBy: currentAddress,
|
|
2778
|
-
};
|
|
2779
|
-
|
|
2780
|
-
const metadataStr = stringify(metadata);
|
|
2781
|
-
// ethers v6: utils.keccak256 -> keccak256, utils.toUtf8Bytes -> toUtf8Bytes
|
|
2782
|
-
const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr));
|
|
2783
|
-
|
|
2784
|
-
// AIT-Service no longer publishes metadata to IPFS: the registry is hash-only, integrity comes
|
|
2785
|
-
// from the on-chain commitment, and /api/metadata has been removed. `permissions` now travels
|
|
2786
|
-
// in the request body instead of being recovered from a CID, so nothing is uploaded here.
|
|
2787
|
-
|
|
2788
|
-
const createAITParams = {
|
|
2789
|
-
controller: currentAddress,
|
|
2790
|
-
serviceId,
|
|
2791
|
-
permissions: metadata.permissions,
|
|
2792
|
-
metadataHash,
|
|
2793
|
-
isFromAIAgent: isFromAIAgent,
|
|
2794
|
-
parentAITId: isFromAIAgent ? aitRef.current?.aitId : undefined,
|
|
2795
|
-
};
|
|
2796
|
-
|
|
2797
|
-
const createAITResponse = await nxtlinqApi.ait.createAIT(createAITParams, nxtlinqAITServiceAccessToken || '');
|
|
2798
|
-
|
|
2799
|
-
if ('error' in createAITResponse) {
|
|
2800
|
-
throw new Error(`Failed to create AIT: ${createAITResponse.error}`);
|
|
2801
|
-
}
|
|
2802
|
-
|
|
2803
|
-
const aitId = (createAITResponse as { aitId?: string }).aitId;
|
|
2804
|
-
if (!aitId) {
|
|
2805
|
-
// Surfaced rather than substituted: this id becomes parentAITId on agent-created AITs, and
|
|
2806
|
-
// parentAITId is committed on chain. Guessing one would anchor a dangling parent link.
|
|
2807
|
-
throw new Error('AIT-Service did not return an aitId; refusing to invent one.');
|
|
2808
|
-
}
|
|
2809
|
-
|
|
2810
|
-
const aitInfo = {
|
|
2811
|
-
aitId,
|
|
2812
|
-
controller: currentAddress,
|
|
2813
|
-
metadata,
|
|
2814
|
-
metadataHash,
|
|
2815
|
-
};
|
|
2816
|
-
|
|
2817
|
-
setAit(aitInfo);
|
|
2818
|
-
setPermissions(newPermissions || permissions);
|
|
2819
|
-
};
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
2850
|
// Auto enable AIT permission
|
|
2824
2851
|
const enableAIT = async (toolName: string) => {
|
|
2825
2852
|
if (isAITEnabling) return false; // Prevent duplicate
|
|
@@ -2886,40 +2913,45 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2886
2913
|
}
|
|
2887
2914
|
|
|
2888
2915
|
try {
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2916
|
+
const context: RuntimeAITContext = {
|
|
2917
|
+
controller: currentHitAddress,
|
|
2918
|
+
serviceId,
|
|
2919
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2920
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2921
|
+
};
|
|
2922
|
+
const enabled = await runtimeMutationQueueRef.current.run(
|
|
2923
|
+
runtimeAITSubjectKey(context),
|
|
2924
|
+
async () => {
|
|
2925
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2926
|
+
const current = await recomputeRuntimeAIT(context);
|
|
2927
|
+
if (!current.maximumPermissions.includes(toolName)) {
|
|
2928
|
+
return false;
|
|
2929
|
+
}
|
|
2930
|
+
const nextDeniedPermissions = removeOneDeniedPermission(
|
|
2931
|
+
current.deniedPermissions,
|
|
2932
|
+
toolName,
|
|
2933
|
+
);
|
|
2934
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2935
|
+
await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
|
|
2936
|
+
return true;
|
|
2937
|
+
},
|
|
2938
|
+
);
|
|
2939
|
+
if (!enabled) {
|
|
2892
2940
|
showError(`Tool ${toolName} is not available for your current identity provider`);
|
|
2893
2941
|
setIsAITEnabling(false);
|
|
2894
2942
|
return false;
|
|
2895
2943
|
}
|
|
2896
|
-
|
|
2897
|
-
// Get current permissions from AIT metadata instead of React state
|
|
2898
|
-
// This ensures we don't lose existing permissions when enabling new ones
|
|
2899
|
-
const currentAITPermissions = aitRef.current?.metadata?.permissions || permissions;
|
|
2900
|
-
const newPermissions = [...currentAITPermissions];
|
|
2901
|
-
if (!newPermissions.includes(toolName)) {
|
|
2902
|
-
newPermissions.push(toolName);
|
|
2903
|
-
}
|
|
2904
|
-
|
|
2905
|
-
// Filter out deleted permissions before saving
|
|
2906
|
-
const validPermissions = newPermissions.filter(permission =>
|
|
2907
|
-
availablePermissionLabels.includes(permission)
|
|
2908
|
-
);
|
|
2909
|
-
|
|
2910
|
-
// Generate and register AIT with new permissions
|
|
2911
|
-
// For auto-enable, we should create a regular AIT (not AI Agent AIT) if user doesn't have existing AIT
|
|
2912
|
-
const shouldCreateAsAIAgent = !!aitRef.current; // Only create as AI Agent if user already has an AIT
|
|
2913
|
-
|
|
2914
|
-
await generateAndRegisterAITWithSigner(validPermissions, shouldCreateAsAIAgent, currentSigner, currentHitAddress);
|
|
2915
2944
|
showSuccess('AIT permission enabled successfully! You can now use the AI agent.');
|
|
2916
|
-
await refreshAIT(true);
|
|
2917
2945
|
setIsAITEnabling(false);
|
|
2918
2946
|
return true;
|
|
2919
2947
|
} catch (error) {
|
|
2920
|
-
|
|
2948
|
+
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2949
|
+
console.error('Failed to auto-enable AIT:', error);
|
|
2950
|
+
}
|
|
2921
2951
|
setIsAITEnabling(false);
|
|
2922
|
-
if (error instanceof
|
|
2952
|
+
if (error instanceof StaleRuntimeAITResponseError) {
|
|
2953
|
+
return false;
|
|
2954
|
+
} else if (error instanceof Error) {
|
|
2923
2955
|
showError(error.message);
|
|
2924
2956
|
} else {
|
|
2925
2957
|
showError('Failed to enable AIT permission. Please try again.');
|
|
@@ -2932,22 +2964,41 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2932
2964
|
const savePermissions = async (newPermissions?: string[]) => {
|
|
2933
2965
|
setIsDisabled(true);
|
|
2934
2966
|
try {
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
const
|
|
2939
|
-
|
|
2967
|
+
if (!hitAddress) {
|
|
2968
|
+
throw new Error('Please connect your wallet first');
|
|
2969
|
+
}
|
|
2970
|
+
const context: RuntimeAITContext = {
|
|
2971
|
+
controller: hitAddress,
|
|
2972
|
+
serviceId,
|
|
2973
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2974
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2975
|
+
};
|
|
2976
|
+
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2977
|
+
await runtimeMutationQueueRef.current.run(
|
|
2978
|
+
runtimeAITSubjectKey(context),
|
|
2979
|
+
async () => {
|
|
2980
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2981
|
+
const fresh = await recomputeRuntimeAIT(context);
|
|
2982
|
+
const nextDeniedPermissions = replaceCurrentMaximumDenyList(
|
|
2983
|
+
fresh.deniedPermissions,
|
|
2984
|
+
fresh.maximumPermissions,
|
|
2985
|
+
checkedPermissions,
|
|
2986
|
+
);
|
|
2987
|
+
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2988
|
+
await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
|
|
2989
|
+
},
|
|
2940
2990
|
);
|
|
2941
|
-
|
|
2942
|
-
await generateAndRegisterAIT(validPermissions, false);
|
|
2943
2991
|
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2944
2992
|
setShowPermissionForm(false);
|
|
2945
2993
|
setIsPermissionFormOpen(false);
|
|
2946
|
-
await refreshAIT(true);
|
|
2947
2994
|
} catch (error) {
|
|
2948
|
-
|
|
2995
|
+
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2996
|
+
console.error('Failed to update AIT deny-list:', error);
|
|
2997
|
+
}
|
|
2949
2998
|
setIsDisabled(false);
|
|
2950
|
-
if (error instanceof
|
|
2999
|
+
if (error instanceof StaleRuntimeAITResponseError) {
|
|
3000
|
+
return;
|
|
3001
|
+
} else if (error instanceof Error) {
|
|
2951
3002
|
showError(error.message);
|
|
2952
3003
|
} else {
|
|
2953
3004
|
showError('Failed to save permissions. Please try again.');
|
|
@@ -2996,14 +3047,12 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2996
3047
|
const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
|
|
2997
3048
|
if (!('error' in walletResponse)) {
|
|
2998
3049
|
setWalletInfo(walletResponse);
|
|
2999
|
-
|
|
3000
|
-
serviceId,
|
|
3050
|
+
await queueRuntimeAITRefresh({
|
|
3001
3051
|
controller: address,
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
}
|
|
3052
|
+
serviceId,
|
|
3053
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
3054
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
3055
|
+
});
|
|
3007
3056
|
}
|
|
3008
3057
|
} finally {
|
|
3009
3058
|
setIsWalletLoading(false);
|
|
@@ -3034,14 +3083,12 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3034
3083
|
const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
|
|
3035
3084
|
if (!('error' in walletResponse)) {
|
|
3036
3085
|
setWalletInfo(walletResponse);
|
|
3037
|
-
|
|
3038
|
-
serviceId,
|
|
3086
|
+
await queueRuntimeAITRefresh({
|
|
3039
3087
|
controller: address,
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
}
|
|
3088
|
+
serviceId,
|
|
3089
|
+
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
3090
|
+
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
3091
|
+
});
|
|
3045
3092
|
}
|
|
3046
3093
|
} finally {
|
|
3047
3094
|
setIsWalletLoading(false);
|
|
@@ -3148,7 +3195,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3148
3195
|
if (hitAddress && nxtlinqAITServiceAccessToken) {
|
|
3149
3196
|
refreshAIT();
|
|
3150
3197
|
}
|
|
3151
|
-
}, [hitAddress, nxtlinqAITServiceAccessToken]);
|
|
3198
|
+
}, [hitAddress, nxtlinqAITServiceAccessToken, permissionGroup, runtimeRolesKey, serviceId]);
|
|
3152
3199
|
|
|
3153
3200
|
// Set loading state when permission form opens
|
|
3154
3201
|
React.useEffect(() => {
|
|
@@ -3236,6 +3283,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3236
3283
|
updateExternalId()
|
|
3237
3284
|
}, [hitAddress, nxtlinqApi, authFields, pseudoId]);
|
|
3238
3285
|
|
|
3286
|
+
const runtimeAuthorizationMatchesRenderedContext =
|
|
3287
|
+
runtimeAuthorizationMatchesContext(runtimeAuthorizationContextKey, runtimeContext);
|
|
3239
3288
|
const contextValue: ChatBotContextType = {
|
|
3240
3289
|
// State
|
|
3241
3290
|
messages,
|
|
@@ -3243,9 +3292,16 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3243
3292
|
isLoading,
|
|
3244
3293
|
isOpen,
|
|
3245
3294
|
hitAddress,
|
|
3246
|
-
ait,
|
|
3247
|
-
permissions,
|
|
3248
|
-
|
|
3295
|
+
ait: runtimeAuthorizationMatchesRenderedContext ? ait : null,
|
|
3296
|
+
permissions: runtimeAuthorizationMatchesRenderedContext ? permissions : [],
|
|
3297
|
+
maximumPermissions: runtimeAuthorizationMatchesRenderedContext ? maximumPermissions : [],
|
|
3298
|
+
deniedPermissions: runtimeAuthorizationMatchesRenderedContext ? deniedPermissions : [],
|
|
3299
|
+
runtimePermissionsUnavailable: runtimeAuthorizationMatchesRenderedContext
|
|
3300
|
+
? runtimePermissionsUnavailable
|
|
3301
|
+
: runtimeContext !== null,
|
|
3302
|
+
availablePermissions: runtimeAuthorizationMatchesRenderedContext
|
|
3303
|
+
? availablePermissions
|
|
3304
|
+
: [],
|
|
3249
3305
|
showPermissionForm,
|
|
3250
3306
|
isPermissionFormOpen,
|
|
3251
3307
|
isAITLoading,
|
|
@@ -3282,7 +3338,6 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3282
3338
|
setIsOpen,
|
|
3283
3339
|
setShowPermissionForm,
|
|
3284
3340
|
setIsPermissionFormOpen,
|
|
3285
|
-
setPermissions,
|
|
3286
3341
|
setIsDisabled,
|
|
3287
3342
|
setIsWalletLoading,
|
|
3288
3343
|
setNotification,
|
|
@@ -3332,6 +3387,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3332
3387
|
onVerifyWallet: (method: 'berifyme' | 'custom') => handleVerifyWalletClick(method),
|
|
3333
3388
|
serviceId,
|
|
3334
3389
|
permissionGroup,
|
|
3390
|
+
roles,
|
|
3335
3391
|
|
|
3336
3392
|
// Props
|
|
3337
3393
|
props: {
|
|
@@ -3350,6 +3406,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3350
3406
|
getAuthToken,
|
|
3351
3407
|
onVerifyWallet,
|
|
3352
3408
|
permissionGroup,
|
|
3409
|
+
roles,
|
|
3353
3410
|
onModelChange,
|
|
3354
3411
|
storageMode,
|
|
3355
3412
|
requireWalletIDVVerification,
|