@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.11 → 0.4.13
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 +87 -32
- package/dist/pendingTextToolRetry.d.ts +5 -0
- package/dist/pendingTextToolRetry.d.ts.map +1 -1
- package/dist/pendingTextToolRetry.js +6 -0
- package/dist/types/ChatBotTypes.d.ts +3 -0
- package/dist/types/ChatBotTypes.d.ts.map +1 -1
- package/dist/ui/MessageList.d.ts.map +1 -1
- package/dist/ui/MessageList.js +12 -4
- package/dist/ui/PermissionForm.d.ts.map +1 -1
- package/dist/ui/PermissionForm.js +25 -25
- package/package.json +3 -3
- package/src/context/ChatBotContext.tsx +108 -33
- package/src/pendingTextToolRetry.ts +14 -0
- package/src/types/ChatBotTypes.ts +3 -0
- package/src/ui/MessageList.tsx +12 -3
- 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 {
|
|
@@ -1494,6 +1505,15 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
1494
1505
|
if ('error' in response || response.result === 'error') {
|
|
1495
1506
|
// Check if it's an AIT-related error
|
|
1496
1507
|
const errorResponse = response;
|
|
1508
|
+
// A backend authorization rejection happens before the frontend sees a
|
|
1509
|
+
// toolCall, so the normal preflight path below cannot remember this
|
|
1510
|
+
// turn. Preserve it here so a successful wallet/permission recovery
|
|
1511
|
+
// can replay the exact original request once.
|
|
1512
|
+
pendingTextToolRetryRef.current.captureAuthorizationRecovery(errorResponse, {
|
|
1513
|
+
content,
|
|
1514
|
+
isPresetMessage,
|
|
1515
|
+
attachments,
|
|
1516
|
+
});
|
|
1497
1517
|
if (errorResponse.requiresWalletConnection) {
|
|
1498
1518
|
// Case where wallet connection is required - trigger auto-connect logic
|
|
1499
1519
|
// Try to auto-connect wallet first
|
|
@@ -2050,7 +2070,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2050
2070
|
stopTextToSpeechAndReset();
|
|
2051
2071
|
}
|
|
2052
2072
|
}, [textToSpeechEnabled, stopTextToSpeechAndReset]);
|
|
2053
|
-
const { isVoiceMode, voiceStatus, isVoiceConnecting, isMicMuted, remoteAudioRef, enterVoiceMode, exitVoiceMode, toggleMicMute: toggleVoiceMicMute, interruptVoice, micRms, } = useVoiceMode({
|
|
2073
|
+
const { isVoiceMode, voiceStatus, isVoiceConnecting, isMicMuted, remoteAudioRef, enterVoiceMode, exitVoiceMode, toggleMicMute: toggleVoiceMicMute, interruptVoice, retryVoicePermissionRequest, micRms, } = useVoiceMode({
|
|
2054
2074
|
apiKey: apiKey ?? '',
|
|
2055
2075
|
apiSecret: apiSecret ?? '',
|
|
2056
2076
|
serviceToken,
|
|
@@ -2060,6 +2080,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2060
2080
|
aitId: ait?.aitId,
|
|
2061
2081
|
walletAddress: hitAddress || undefined,
|
|
2062
2082
|
aitToken: nxtlinqAITServiceAccessToken || undefined,
|
|
2083
|
+
permissions,
|
|
2063
2084
|
metadata: customUserInfo,
|
|
2064
2085
|
nxtlinqApi,
|
|
2065
2086
|
getMessages: () => messagesRef.current,
|
|
@@ -2332,41 +2353,68 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2332
2353
|
// Save permissions
|
|
2333
2354
|
const savePermissions = async (newPermissions) => {
|
|
2334
2355
|
setIsDisabled(true);
|
|
2335
|
-
|
|
2336
|
-
if (!hitAddress) {
|
|
2337
|
-
throw new Error('Please connect your wallet first');
|
|
2338
|
-
}
|
|
2339
|
-
const context = {
|
|
2340
|
-
controller: hitAddress,
|
|
2341
|
-
serviceId,
|
|
2342
|
-
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2343
|
-
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2344
|
-
};
|
|
2345
|
-
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2346
|
-
await runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
|
|
2347
|
-
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2348
|
-
await replaceRuntimeActivePermissions(context, checkedPermissions);
|
|
2349
|
-
});
|
|
2350
|
-
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2351
|
-
setShowPermissionForm(false);
|
|
2352
|
-
setIsPermissionFormOpen(false);
|
|
2353
|
-
await retryPendingTextTool();
|
|
2354
|
-
}
|
|
2355
|
-
catch (error) {
|
|
2356
|
-
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2357
|
-
console.error('Failed to update AIT deny-list:', error);
|
|
2358
|
-
}
|
|
2356
|
+
if (!hitAddress) {
|
|
2359
2357
|
setIsDisabled(false);
|
|
2360
|
-
|
|
2361
|
-
|
|
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();
|
|
2362
2391
|
}
|
|
2363
|
-
|
|
2364
|
-
|
|
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
|
+
}
|
|
2365
2409
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2410
|
+
finally {
|
|
2411
|
+
if (permissionSaveOperationRef.current?.operationId === operationId) {
|
|
2412
|
+
permissionSaveOperationRef.current = null;
|
|
2413
|
+
}
|
|
2368
2414
|
}
|
|
2369
|
-
}
|
|
2415
|
+
})();
|
|
2416
|
+
permissionSaveOperationRef.current = { operationId, subjectKey, promise: operation };
|
|
2417
|
+
return operation;
|
|
2370
2418
|
};
|
|
2371
2419
|
// Handle verify wallet click
|
|
2372
2420
|
const handleVerifyWalletClick = async (method) => {
|
|
@@ -2643,6 +2691,10 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2643
2691
|
updateExternalId();
|
|
2644
2692
|
}, [hitAddress, nxtlinqApi, authFields, pseudoId]);
|
|
2645
2693
|
const runtimeAuthorizationMatchesRenderedContext = runtimeAuthorizationMatchesContext(runtimeAuthorizationContextKey, runtimeContext);
|
|
2694
|
+
const renderedPermissionSaveState = runtimeContext
|
|
2695
|
+
&& permissionSaveState?.subjectKey === runtimeAITSubjectKey(runtimeContext)
|
|
2696
|
+
? permissionSaveState
|
|
2697
|
+
: null;
|
|
2646
2698
|
const contextValue = {
|
|
2647
2699
|
// State
|
|
2648
2700
|
messages,
|
|
@@ -2663,6 +2715,8 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2663
2715
|
showPermissionForm,
|
|
2664
2716
|
isPermissionFormOpen,
|
|
2665
2717
|
isAITLoading,
|
|
2718
|
+
permissionSaveDraft: renderedPermissionSaveState?.permissions ?? null,
|
|
2719
|
+
isPermissionSaving: renderedPermissionSaveState?.status === 'saving',
|
|
2666
2720
|
isDisabled,
|
|
2667
2721
|
walletInfo,
|
|
2668
2722
|
isWalletLoading,
|
|
@@ -2733,6 +2787,7 @@ customError, voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
|
|
|
2733
2787
|
exitVoiceMode: handleExitVoiceMode,
|
|
2734
2788
|
toggleVoiceMicMute,
|
|
2735
2789
|
interruptVoice,
|
|
2790
|
+
retryVoicePermissionRequest,
|
|
2736
2791
|
micRms,
|
|
2737
2792
|
debugVoiceRms,
|
|
2738
2793
|
// Additional properties for PermissionForm
|
|
@@ -4,11 +4,16 @@ export type PendingTextToolRequest = {
|
|
|
4
4
|
isPresetMessage: boolean;
|
|
5
5
|
attachments?: Attachment[];
|
|
6
6
|
};
|
|
7
|
+
export type TextToolAuthorizationRecovery = {
|
|
8
|
+
requiresWalletConnection?: boolean;
|
|
9
|
+
requiresPermissionUpdate?: boolean;
|
|
10
|
+
};
|
|
7
11
|
/** Keeps one interrupted text-tool request and serializes all resume attempts. */
|
|
8
12
|
export declare class PendingTextToolRetryController {
|
|
9
13
|
private pending;
|
|
10
14
|
private inFlight;
|
|
11
15
|
set(request: PendingTextToolRequest): void;
|
|
16
|
+
captureAuthorizationRecovery(recovery: TextToolAuthorizationRecovery, request: PendingTextToolRequest): boolean;
|
|
12
17
|
clear(): void;
|
|
13
18
|
hasPending(): boolean;
|
|
14
19
|
retry(execute: (request: PendingTextToolRequest) => Promise<void>): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pendingTextToolRetry.d.ts","sourceRoot":"","sources":["../src/pendingTextToolRetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,CAAC;AAEF,kFAAkF;AAClF,qBAAa,8BAA8B;IACzC,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,QAAQ,CAAiC;IAEjD,GAAG,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAI1C,KAAK,IAAI,IAAI;IAIb,UAAU,IAAI,OAAO;IAIrB,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAarF"}
|
|
1
|
+
{"version":3,"file":"pendingTextToolRetry.d.ts","sourceRoot":"","sources":["../src/pendingTextToolRetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,kFAAkF;AAClF,qBAAa,8BAA8B;IACzC,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,QAAQ,CAAiC;IAEjD,GAAG,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAI1C,4BAA4B,CAC1B,QAAQ,EAAE,6BAA6B,EACvC,OAAO,EAAE,sBAAsB,GAC9B,OAAO;IAMV,KAAK,IAAI,IAAI;IAIb,UAAU,IAAI,OAAO;IAIrB,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAarF"}
|
|
@@ -7,6 +7,12 @@ export class PendingTextToolRetryController {
|
|
|
7
7
|
set(request) {
|
|
8
8
|
this.pending = request;
|
|
9
9
|
}
|
|
10
|
+
captureAuthorizationRecovery(recovery, request) {
|
|
11
|
+
if (!recovery.requiresWalletConnection && !recovery.requiresPermissionUpdate)
|
|
12
|
+
return false;
|
|
13
|
+
this.set(request);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
10
16
|
clear() {
|
|
11
17
|
this.pending = null;
|
|
12
18
|
}
|
|
@@ -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;
|
|
@@ -164,6 +166,7 @@ export interface ChatBotContextType {
|
|
|
164
166
|
exitVoiceMode: () => Promise<void>;
|
|
165
167
|
toggleVoiceMicMute: () => void;
|
|
166
168
|
interruptVoice: () => void;
|
|
169
|
+
retryVoicePermissionRequest: () => Promise<boolean>;
|
|
167
170
|
onSave: (newPermissions?: string[]) => Promise<void>;
|
|
168
171
|
onConnectWallet: () => Promise<string | false | undefined>;
|
|
169
172
|
onSignIn: () => Promise<boolean>;
|
|
@@ -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":"MessageList.d.ts","sourceRoot":"","sources":["../../src/ui/MessageList.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuT/B,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/ui/MessageList.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuT/B,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAqd/B,CAAC"}
|
package/dist/ui/MessageList.js
CHANGED
|
@@ -231,7 +231,7 @@ const PiiStatusHeader = React.memo(({ message }) => {
|
|
|
231
231
|
return (_jsxs("div", { css: piiHeaderRow, children: [_jsx(ShieldIcon, {}), _jsx("span", { children: "\u2713 Protected" })] }));
|
|
232
232
|
});
|
|
233
233
|
export const MessageList = () => {
|
|
234
|
-
const { messages, isLoading, isTtsProcessing, requiresGesture, retryTtsWithGesture, connectWallet, signInWallet, retryPendingTextTool, hitAddress, isAutoConnecting, isNeedSignInWithWallet, enableAIT, isAITLoading, isAITEnabling, sendMessage, permissions, availableModels, serviceId, piiDisplayMode, setShowPermissionForm, setIsPermissionFormOpen, } = useChatBot();
|
|
234
|
+
const { messages, isLoading, isTtsProcessing, requiresGesture, retryTtsWithGesture, connectWallet, signInWallet, retryPendingTextTool, retryVoicePermissionRequest, hitAddress, isAutoConnecting, isNeedSignInWithWallet, enableAIT, isAITLoading, isAITEnabling, sendMessage, permissions, availableModels, serviceId, piiDisplayMode, setShowPermissionForm, setIsPermissionFormOpen, } = useChatBot();
|
|
235
235
|
const messagesEndRef = React.useRef(null);
|
|
236
236
|
const scrollToBottom = () => {
|
|
237
237
|
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
@@ -246,6 +246,14 @@ export const MessageList = () => {
|
|
|
246
246
|
if (isLoading) {
|
|
247
247
|
return;
|
|
248
248
|
}
|
|
249
|
+
const retryInterruptedTool = async () => {
|
|
250
|
+
if (message.metadata?.voiceAuthorizationPrompt === true) {
|
|
251
|
+
await retryVoicePermissionRequest();
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
await retryPendingTextTool();
|
|
255
|
+
}
|
|
256
|
+
};
|
|
249
257
|
if (buttonType === 'connectWallet') {
|
|
250
258
|
const connected = await connectWallet(false);
|
|
251
259
|
if (connected) {
|
|
@@ -253,20 +261,20 @@ export const MessageList = () => {
|
|
|
253
261
|
// signature UI instead of leaving the user on a stale connect prompt.
|
|
254
262
|
const signedIn = await signInWallet(true);
|
|
255
263
|
if (signedIn)
|
|
256
|
-
await
|
|
264
|
+
await retryInterruptedTool();
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
267
|
else if (buttonType === 'signIn') {
|
|
260
268
|
const signedIn = await signInWallet(true);
|
|
261
269
|
if (signedIn)
|
|
262
|
-
await
|
|
270
|
+
await retryInterruptedTool();
|
|
263
271
|
}
|
|
264
272
|
else if (buttonType === 'enableAIT') {
|
|
265
273
|
const requiredPermission = message.metadata?.requiredPermission;
|
|
266
274
|
if (requiredPermission) {
|
|
267
275
|
const success = await enableAIT(requiredPermission);
|
|
268
276
|
if (success) {
|
|
269
|
-
await
|
|
277
|
+
await retryInterruptedTool();
|
|
270
278
|
}
|
|
271
279
|
}
|
|
272
280
|
}
|
|
@@ -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.13",
|
|
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.
|
|
42
|
-
"@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.
|
|
41
|
+
"@bytexbyte/nxtlinq-ai-agent-core-development": "2.0.5",
|
|
42
|
+
"@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.6",
|
|
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 {
|
|
@@ -1757,6 +1784,15 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
1757
1784
|
if ('error' in response || (response as any).result === 'error') {
|
|
1758
1785
|
// Check if it's an AIT-related error
|
|
1759
1786
|
const errorResponse = response as any;
|
|
1787
|
+
// A backend authorization rejection happens before the frontend sees a
|
|
1788
|
+
// toolCall, so the normal preflight path below cannot remember this
|
|
1789
|
+
// turn. Preserve it here so a successful wallet/permission recovery
|
|
1790
|
+
// can replay the exact original request once.
|
|
1791
|
+
pendingTextToolRetryRef.current.captureAuthorizationRecovery(errorResponse, {
|
|
1792
|
+
content,
|
|
1793
|
+
isPresetMessage,
|
|
1794
|
+
attachments,
|
|
1795
|
+
});
|
|
1760
1796
|
if (errorResponse.requiresWalletConnection) {
|
|
1761
1797
|
// Case where wallet connection is required - trigger auto-connect logic
|
|
1762
1798
|
// Try to auto-connect wallet first
|
|
@@ -2365,6 +2401,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2365
2401
|
exitVoiceMode,
|
|
2366
2402
|
toggleMicMute: toggleVoiceMicMute,
|
|
2367
2403
|
interruptVoice,
|
|
2404
|
+
retryVoicePermissionRequest,
|
|
2368
2405
|
micRms,
|
|
2369
2406
|
} = useVoiceMode({
|
|
2370
2407
|
apiKey: apiKey ?? '',
|
|
@@ -2376,6 +2413,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2376
2413
|
aitId: ait?.aitId,
|
|
2377
2414
|
walletAddress: hitAddress || undefined,
|
|
2378
2415
|
aitToken: nxtlinqAITServiceAccessToken || undefined,
|
|
2416
|
+
permissions,
|
|
2379
2417
|
metadata: customUserInfo,
|
|
2380
2418
|
nxtlinqApi,
|
|
2381
2419
|
getMessages: () => messagesRef.current,
|
|
@@ -2666,41 +2704,71 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2666
2704
|
// Save permissions
|
|
2667
2705
|
const savePermissions = async (newPermissions?: string[]) => {
|
|
2668
2706
|
setIsDisabled(true);
|
|
2669
|
-
|
|
2670
|
-
if (!hitAddress) {
|
|
2671
|
-
throw new Error('Please connect your wallet first');
|
|
2672
|
-
}
|
|
2673
|
-
const context: RuntimeAITContext = {
|
|
2674
|
-
controller: hitAddress,
|
|
2675
|
-
serviceId,
|
|
2676
|
-
...(roles !== undefined ? { roles: [...roles] } : {}),
|
|
2677
|
-
...(permissionGroup !== undefined ? { permissionGroup } : {}),
|
|
2678
|
-
};
|
|
2679
|
-
const checkedPermissions = [...(newPermissions ?? permissions)];
|
|
2680
|
-
await runtimeMutationQueueRef.current.run(
|
|
2681
|
-
runtimeAITSubjectKey(context),
|
|
2682
|
-
async () => {
|
|
2683
|
-
runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
|
|
2684
|
-
await replaceRuntimeActivePermissions(context, checkedPermissions);
|
|
2685
|
-
},
|
|
2686
|
-
);
|
|
2687
|
-
showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
|
|
2688
|
-
setShowPermissionForm(false);
|
|
2689
|
-
setIsPermissionFormOpen(false);
|
|
2690
|
-
await retryPendingTextTool();
|
|
2691
|
-
} catch (error) {
|
|
2692
|
-
if (!(error instanceof StaleRuntimeAITResponseError)) {
|
|
2693
|
-
console.error('Failed to update AIT deny-list:', error);
|
|
2694
|
-
}
|
|
2707
|
+
if (!hitAddress) {
|
|
2695
2708
|
setIsDisabled(false);
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
} else if (error instanceof Error) {
|
|
2699
|
-
showError(error.message);
|
|
2700
|
-
} else {
|
|
2701
|
-
showError('Failed to save permissions. Please try again.');
|
|
2702
|
-
}
|
|
2709
|
+
showError('Please connect your wallet first');
|
|
2710
|
+
return;
|
|
2703
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;
|
|
2704
2772
|
};
|
|
2705
2773
|
|
|
2706
2774
|
// Handle verify wallet click
|
|
@@ -2987,6 +3055,10 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
2987
3055
|
|
|
2988
3056
|
const runtimeAuthorizationMatchesRenderedContext =
|
|
2989
3057
|
runtimeAuthorizationMatchesContext(runtimeAuthorizationContextKey, runtimeContext);
|
|
3058
|
+
const renderedPermissionSaveState = runtimeContext
|
|
3059
|
+
&& permissionSaveState?.subjectKey === runtimeAITSubjectKey(runtimeContext)
|
|
3060
|
+
? permissionSaveState
|
|
3061
|
+
: null;
|
|
2990
3062
|
const contextValue: ChatBotContextType = {
|
|
2991
3063
|
// State
|
|
2992
3064
|
messages,
|
|
@@ -3007,6 +3079,8 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3007
3079
|
showPermissionForm,
|
|
3008
3080
|
isPermissionFormOpen,
|
|
3009
3081
|
isAITLoading,
|
|
3082
|
+
permissionSaveDraft: renderedPermissionSaveState?.permissions ?? null,
|
|
3083
|
+
isPermissionSaving: renderedPermissionSaveState?.status === 'saving',
|
|
3010
3084
|
isDisabled,
|
|
3011
3085
|
walletInfo,
|
|
3012
3086
|
isWalletLoading,
|
|
@@ -3079,6 +3153,7 @@ export const ChatBotProvider: React.FC<ChatBotProps> = ({
|
|
|
3079
3153
|
exitVoiceMode: handleExitVoiceMode,
|
|
3080
3154
|
toggleVoiceMicMute,
|
|
3081
3155
|
interruptVoice,
|
|
3156
|
+
retryVoicePermissionRequest,
|
|
3082
3157
|
micRms,
|
|
3083
3158
|
debugVoiceRms,
|
|
3084
3159
|
|
|
@@ -6,6 +6,11 @@ export type PendingTextToolRequest = {
|
|
|
6
6
|
attachments?: Attachment[];
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
export type TextToolAuthorizationRecovery = {
|
|
10
|
+
requiresWalletConnection?: boolean;
|
|
11
|
+
requiresPermissionUpdate?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
9
14
|
/** Keeps one interrupted text-tool request and serializes all resume attempts. */
|
|
10
15
|
export class PendingTextToolRetryController {
|
|
11
16
|
private pending: PendingTextToolRequest | null = null;
|
|
@@ -15,6 +20,15 @@ export class PendingTextToolRetryController {
|
|
|
15
20
|
this.pending = request;
|
|
16
21
|
}
|
|
17
22
|
|
|
23
|
+
captureAuthorizationRecovery(
|
|
24
|
+
recovery: TextToolAuthorizationRecovery,
|
|
25
|
+
request: PendingTextToolRequest,
|
|
26
|
+
): boolean {
|
|
27
|
+
if (!recovery.requiresWalletConnection && !recovery.requiresPermissionUpdate) return false;
|
|
28
|
+
this.set(request);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
18
32
|
clear(): void {
|
|
19
33
|
this.pending = null;
|
|
20
34
|
}
|
|
@@ -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;
|
|
@@ -190,6 +192,7 @@ export interface ChatBotContextType {
|
|
|
190
192
|
exitVoiceMode: () => Promise<void>;
|
|
191
193
|
toggleVoiceMicMute: () => void;
|
|
192
194
|
interruptVoice: () => void;
|
|
195
|
+
retryVoicePermissionRequest: () => Promise<boolean>;
|
|
193
196
|
|
|
194
197
|
// Additional properties for PermissionForm
|
|
195
198
|
onSave: (newPermissions?: string[]) => Promise<void>;
|
package/src/ui/MessageList.tsx
CHANGED
|
@@ -320,6 +320,7 @@ export const MessageList: React.FC = () => {
|
|
|
320
320
|
connectWallet,
|
|
321
321
|
signInWallet,
|
|
322
322
|
retryPendingTextTool,
|
|
323
|
+
retryVoicePermissionRequest,
|
|
323
324
|
hitAddress,
|
|
324
325
|
isAutoConnecting,
|
|
325
326
|
isNeedSignInWithWallet,
|
|
@@ -353,23 +354,31 @@ export const MessageList: React.FC = () => {
|
|
|
353
354
|
return;
|
|
354
355
|
}
|
|
355
356
|
|
|
357
|
+
const retryInterruptedTool = async () => {
|
|
358
|
+
if (message.metadata?.voiceAuthorizationPrompt === true) {
|
|
359
|
+
await retryVoicePermissionRequest();
|
|
360
|
+
} else {
|
|
361
|
+
await retryPendingTextTool();
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
|
|
356
365
|
if (buttonType === 'connectWallet') {
|
|
357
366
|
const connected = await connectWallet(false);
|
|
358
367
|
if (connected) {
|
|
359
368
|
// Continue the interrupted flow immediately. This opens the wallet
|
|
360
369
|
// signature UI instead of leaving the user on a stale connect prompt.
|
|
361
370
|
const signedIn = await signInWallet(true);
|
|
362
|
-
if (signedIn) await
|
|
371
|
+
if (signedIn) await retryInterruptedTool();
|
|
363
372
|
}
|
|
364
373
|
} else if (buttonType === 'signIn') {
|
|
365
374
|
const signedIn = await signInWallet(true);
|
|
366
|
-
if (signedIn) await
|
|
375
|
+
if (signedIn) await retryInterruptedTool();
|
|
367
376
|
} else if (buttonType === 'enableAIT') {
|
|
368
377
|
const requiredPermission = message.metadata?.requiredPermission;
|
|
369
378
|
if (requiredPermission) {
|
|
370
379
|
const success = await enableAIT(requiredPermission);
|
|
371
380
|
if (success) {
|
|
372
|
-
await
|
|
381
|
+
await retryInterruptedTool();
|
|
373
382
|
}
|
|
374
383
|
}
|
|
375
384
|
} else if (buttonType === 'verifyWallet') {
|
|
@@ -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
|
</>
|