@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.1 → 0.4.2
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 -402
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +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/ui/ChatBotUI.d.ts.map +1 -1
- package/dist/ui/ChatBotUI.js +6 -4
- package/dist/ui/MessageList.d.ts.map +1 -1
- package/dist/ui/MessageList.js +11 -6
- package/dist/ui/PermissionForm.d.ts.map +1 -1
- package/dist/ui/PermissionForm.js +6 -9
- package/package.json +4 -4
- package/src/context/ChatBotContext.tsx +83 -435
- package/src/index.ts +5 -0
- package/src/ui/ChatBotUI.tsx +6 -4
- package/src/ui/MessageList.tsx +6 -0
- package/src/ui/PermissionForm.tsx +7 -12
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
const useCommitPhaseEffect = typeof window === 'undefined'
|
|
3
|
+
? React.useEffect
|
|
4
|
+
: React.useLayoutEffect;
|
|
5
|
+
export function commitProviderRuntime(identityRef, identity, environment, publishEnvironment) {
|
|
6
|
+
identityRef.current = identity;
|
|
7
|
+
publishEnvironment(environment);
|
|
8
|
+
}
|
|
9
|
+
export function useProviderRuntimeCommit(identityRef, identity, environment, publishEnvironment) {
|
|
10
|
+
useCommitPhaseEffect(() => {
|
|
11
|
+
commitProviderRuntime(identityRef, identity, environment, publishEnvironment);
|
|
12
|
+
}, [environment, identity, identityRef, publishEnvironment]);
|
|
13
|
+
}
|
|
14
|
+
function stableUnique(values) {
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const result = [];
|
|
17
|
+
for (const value of values) {
|
|
18
|
+
if (!seen.has(value)) {
|
|
19
|
+
seen.add(value);
|
|
20
|
+
result.push(value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
export function replaceCurrentMaximumDenyList(persistedDeniedPermissions, maximumPermissions, checkedPermissions) {
|
|
26
|
+
const maximum = new Set(maximumPermissions);
|
|
27
|
+
const checked = new Set(checkedPermissions);
|
|
28
|
+
for (const permission of checked) {
|
|
29
|
+
if (!maximum.has(permission)) {
|
|
30
|
+
throw new Error(`Permission is outside the authoritative maximum: ${permission}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const retainedOutsideMaximum = persistedDeniedPermissions.filter((permission) => !maximum.has(permission));
|
|
34
|
+
const deniedInsideMaximum = maximumPermissions.filter((permission) => !checked.has(permission));
|
|
35
|
+
return stableUnique([...retainedOutsideMaximum, ...deniedInsideMaximum]);
|
|
36
|
+
}
|
|
37
|
+
export function removeOneDeniedPermission(persistedDeniedPermissions, permission) {
|
|
38
|
+
return stableUnique(persistedDeniedPermissions).filter((value) => value !== permission);
|
|
39
|
+
}
|
|
40
|
+
export function runtimeAITContextKey(context) {
|
|
41
|
+
return JSON.stringify([
|
|
42
|
+
context.controller,
|
|
43
|
+
context.serviceId,
|
|
44
|
+
context.roles === undefined ? null : [...context.roles],
|
|
45
|
+
context.permissionGroup ?? null,
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
export function runtimeAITSubjectKey(context) {
|
|
49
|
+
return JSON.stringify([context.controller, context.serviceId]);
|
|
50
|
+
}
|
|
51
|
+
export function runtimeAuthorizationMatchesContext(authorizationContextKey, renderedContext) {
|
|
52
|
+
return authorizationContextKey === (renderedContext ? runtimeAITContextKey(renderedContext) : null);
|
|
53
|
+
}
|
|
54
|
+
export class StaleRuntimeAITResponseError extends Error {
|
|
55
|
+
constructor() {
|
|
56
|
+
super('Stale runtime AIT response was discarded');
|
|
57
|
+
this.name = 'StaleRuntimeAITResponseError';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Owns the authoritative recompute lifecycle. Only the newest request for the
|
|
62
|
+
* active captured context may write state; its failures clear state first.
|
|
63
|
+
*/
|
|
64
|
+
export class RuntimeAITRecomputeCoordinator {
|
|
65
|
+
constructor() {
|
|
66
|
+
this.activeContextKey = null;
|
|
67
|
+
this.activeContext = null;
|
|
68
|
+
this.generation = 0;
|
|
69
|
+
}
|
|
70
|
+
commitContext(context, invalidate) {
|
|
71
|
+
const nextKey = context ? runtimeAITContextKey(context) : null;
|
|
72
|
+
if (nextKey === this.activeContextKey) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
this.activeContextKey = nextKey;
|
|
76
|
+
this.activeContext = context ? {
|
|
77
|
+
controller: context.controller,
|
|
78
|
+
serviceId: context.serviceId,
|
|
79
|
+
...(context.roles !== undefined ? { roles: [...context.roles] } : {}),
|
|
80
|
+
...(context.permissionGroup !== undefined
|
|
81
|
+
? { permissionGroup: context.permissionGroup }
|
|
82
|
+
: {}),
|
|
83
|
+
} : null;
|
|
84
|
+
this.generation += 1;
|
|
85
|
+
invalidate();
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
getActiveContext() {
|
|
89
|
+
return this.activeContext ? {
|
|
90
|
+
controller: this.activeContext.controller,
|
|
91
|
+
serviceId: this.activeContext.serviceId,
|
|
92
|
+
...(this.activeContext.roles !== undefined
|
|
93
|
+
? { roles: [...this.activeContext.roles] }
|
|
94
|
+
: {}),
|
|
95
|
+
...(this.activeContext.permissionGroup !== undefined
|
|
96
|
+
? { permissionGroup: this.activeContext.permissionGroup }
|
|
97
|
+
: {}),
|
|
98
|
+
} : null;
|
|
99
|
+
}
|
|
100
|
+
isContextActive(context) {
|
|
101
|
+
return runtimeAITContextKey(context) === this.activeContextKey;
|
|
102
|
+
}
|
|
103
|
+
assertContextActive(context) {
|
|
104
|
+
if (!this.isContextActive(context)) {
|
|
105
|
+
throw new StaleRuntimeAITResponseError();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async run(context, request, apply, clear) {
|
|
109
|
+
this.assertContextActive(context);
|
|
110
|
+
const contextKey = runtimeAITContextKey(context);
|
|
111
|
+
const generation = ++this.generation;
|
|
112
|
+
try {
|
|
113
|
+
const result = await request();
|
|
114
|
+
if (generation !== this.generation || contextKey !== this.activeContextKey) {
|
|
115
|
+
throw new StaleRuntimeAITResponseError();
|
|
116
|
+
}
|
|
117
|
+
apply(result, context);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (!(error instanceof StaleRuntimeAITResponseError)
|
|
122
|
+
&& generation === this.generation
|
|
123
|
+
&& contextKey === this.activeContextKey) {
|
|
124
|
+
clear();
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export function useRuntimeAITContextCommit(coordinator, context, invalidate) {
|
|
131
|
+
const contextKey = context ? runtimeAITContextKey(context) : null;
|
|
132
|
+
useCommitPhaseEffect(() => {
|
|
133
|
+
coordinator.commitContext(context, invalidate);
|
|
134
|
+
}, [contextKey, coordinator, invalidate]);
|
|
135
|
+
}
|
|
136
|
+
export async function dispatchRuntimeAITCompleteReplacement(coordinator, context, update, converge, clear) {
|
|
137
|
+
const subjectKey = runtimeAITSubjectKey(context);
|
|
138
|
+
coordinator.assertContextActive(context);
|
|
139
|
+
let updateFailed = false;
|
|
140
|
+
let updateError;
|
|
141
|
+
try {
|
|
142
|
+
await update();
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
updateFailed = true;
|
|
146
|
+
updateError = error;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
await converge(subjectKey);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
if (!updateFailed) {
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (updateFailed) {
|
|
157
|
+
if (!coordinator.isContextActive(context)) {
|
|
158
|
+
throw new StaleRuntimeAITResponseError();
|
|
159
|
+
}
|
|
160
|
+
clear();
|
|
161
|
+
throw updateError;
|
|
162
|
+
}
|
|
163
|
+
coordinator.assertContextActive(context);
|
|
164
|
+
}
|
|
165
|
+
/** Serializes reads, complete replacements, and convergence for one persistence subject. */
|
|
166
|
+
export class RuntimeAITMutationQueue {
|
|
167
|
+
constructor() {
|
|
168
|
+
this.tails = new Map();
|
|
169
|
+
}
|
|
170
|
+
async run(subjectKey, mutation) {
|
|
171
|
+
const previous = this.tails.get(subjectKey) ?? Promise.resolve();
|
|
172
|
+
const result = previous.catch(() => undefined).then(mutation);
|
|
173
|
+
const tail = result.then(() => undefined, () => undefined);
|
|
174
|
+
this.tails.set(subjectKey, tail);
|
|
175
|
+
try {
|
|
176
|
+
return await result;
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
if (this.tails.get(subjectKey) === tail) {
|
|
180
|
+
this.tails.delete(subjectKey);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export function runtimeAuthorizationState(result, controller, serviceId) {
|
|
186
|
+
return {
|
|
187
|
+
ait: result.aitId
|
|
188
|
+
? {
|
|
189
|
+
aitId: result.aitId,
|
|
190
|
+
controller,
|
|
191
|
+
serviceId,
|
|
192
|
+
metadata: { permissions: [...result.effectivePermissions] },
|
|
193
|
+
}
|
|
194
|
+
: null,
|
|
195
|
+
maximumPermissions: [...result.maximumPermissions],
|
|
196
|
+
effectivePermissions: [...result.effectivePermissions],
|
|
197
|
+
deniedPermissions: [...result.deniedPermissions],
|
|
198
|
+
selectedRuleId: result.selectedRuleId,
|
|
199
|
+
selectedRuleType: result.selectedRuleType,
|
|
200
|
+
expiresAt: result.expiresAt,
|
|
201
|
+
grantActive: result.grantActive,
|
|
202
|
+
unavailable: false,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export function unavailableRuntimeAuthorization(persistedDeniedPermissions) {
|
|
206
|
+
return {
|
|
207
|
+
ait: null,
|
|
208
|
+
maximumPermissions: [],
|
|
209
|
+
effectivePermissions: [],
|
|
210
|
+
deniedPermissions: [...persistedDeniedPermissions],
|
|
211
|
+
selectedRuleId: null,
|
|
212
|
+
selectedRuleType: 'none',
|
|
213
|
+
expiresAt: null,
|
|
214
|
+
grantActive: false,
|
|
215
|
+
unavailable: true,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBotUI.d.ts","sourceRoot":"","sources":["../../src/ui/ChatBotUI.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatBotUI.d.ts","sourceRoot":"","sources":["../../src/ui/ChatBotUI.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsG/B,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAktB7B,CAAC"}
|
package/dist/ui/ChatBotUI.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/reac
|
|
|
2
2
|
/** @jsxImportSource @emotion/react */
|
|
3
3
|
import { css } from '@emotion/react';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
+
import { hasRecordedWalletVerification } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
5
6
|
import { useDraggable, useLocalStorage, useResizable, walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
6
7
|
import { useChatBot } from '../context/ChatBotContext';
|
|
7
8
|
import { ChatBotHeader } from './ChatBotHeader';
|
|
@@ -93,7 +94,8 @@ export const ChatBotUI = () => {
|
|
|
93
94
|
// Check if there's a berifyme token in URL (indicating recent berifyme verification)
|
|
94
95
|
const urlParams = new URLSearchParams(window.location.search);
|
|
95
96
|
const hasBerifymeToken = urlParams.get('token') && urlParams.get('method') === 'berifyme';
|
|
96
|
-
const
|
|
97
|
+
const hasRecordedVerification = Boolean(walletInfo?.id)
|
|
98
|
+
&& hasRecordedWalletVerification(walletInfo);
|
|
97
99
|
// Helper function to update IDV suggestion state based on storage value
|
|
98
100
|
const updateIDVSuggestionState = React.useCallback((dismissedValue) => {
|
|
99
101
|
// Clear any existing countdown interval
|
|
@@ -150,14 +152,14 @@ export const ChatBotUI = () => {
|
|
|
150
152
|
const shouldShowBanner = hitAddress &&
|
|
151
153
|
!props.requireWalletIDVVerification &&
|
|
152
154
|
!hasBerifymeToken &&
|
|
153
|
-
!
|
|
155
|
+
!hasRecordedVerification &&
|
|
154
156
|
!isNeedSignInWithWallet;
|
|
155
157
|
if (shouldShowBanner) {
|
|
156
158
|
const timer = setTimeout(() => {
|
|
157
159
|
const shouldShowBannerAfterDelay = hitAddress &&
|
|
158
160
|
!props.requireWalletIDVVerification &&
|
|
159
161
|
!hasBerifymeToken &&
|
|
160
|
-
!
|
|
162
|
+
!hasRecordedVerification &&
|
|
161
163
|
!isNeedSignInWithWallet;
|
|
162
164
|
if (shouldShowBannerAfterDelay) {
|
|
163
165
|
const dismissed = localStorage.getItem('idv-suggestion-dismissed');
|
|
@@ -530,7 +532,7 @@ export const ChatBotUI = () => {
|
|
|
530
532
|
left: ${MOBILE_EDGE_MARGIN}px !important;
|
|
531
533
|
top: ${MOBILE_EDGE_MARGIN}px !important;
|
|
532
534
|
` : ''}
|
|
533
|
-
`], children: [!mobileLayout && (_jsxs(_Fragment, { children: [_jsx("div", { css: resizeHandleNW, onPointerDown: handleResizeStart('nw'), title: "Resize", "aria-label": "Resize chat window from top-left" }), _jsx("div", { css: resizeHandleNE, onPointerDown: handleResizeStart('ne'), title: "Resize", "aria-label": "Resize chat window from top-right" }), _jsx("div", { css: resizeHandleSW, onPointerDown: handleResizeStart('sw'), title: "Resize", "aria-label": "Resize chat window from bottom-left" }), _jsx("div", { css: resizeHandleSE, onPointerDown: handleResizeStart('se'), title: "Resize", "aria-label": "Resize chat window from bottom-right" })] })), _jsx(ChatBotHeader, { mobileLayout: headerCompactLayout, isDragging: isDragging, onDragStart: handleDragStart, isVoiceMode: isVoiceMode, isVoiceConnecting: isVoiceConnecting, onVoiceToggle: () => void ((isVoiceMode || isVoiceConnecting) ? exitVoiceMode() : enterVoiceMode()), piiDisplayMode: piiDisplayMode, isAITLoading: isAITLoading, onSettingsClick: handleSettingsClick, onClose: handleClose }), showIDVSuggestion && hitAddress && !props.requireWalletIDVVerification && !hasBerifymeToken && !
|
|
535
|
+
`], children: [!mobileLayout && (_jsxs(_Fragment, { children: [_jsx("div", { css: resizeHandleNW, onPointerDown: handleResizeStart('nw'), title: "Resize", "aria-label": "Resize chat window from top-left" }), _jsx("div", { css: resizeHandleNE, onPointerDown: handleResizeStart('ne'), title: "Resize", "aria-label": "Resize chat window from top-right" }), _jsx("div", { css: resizeHandleSW, onPointerDown: handleResizeStart('sw'), title: "Resize", "aria-label": "Resize chat window from bottom-left" }), _jsx("div", { css: resizeHandleSE, onPointerDown: handleResizeStart('se'), title: "Resize", "aria-label": "Resize chat window from bottom-right" })] })), _jsx(ChatBotHeader, { mobileLayout: headerCompactLayout, isDragging: isDragging, onDragStart: handleDragStart, isVoiceMode: isVoiceMode, isVoiceConnecting: isVoiceConnecting, onVoiceToggle: () => void ((isVoiceMode || isVoiceConnecting) ? exitVoiceMode() : enterVoiceMode()), piiDisplayMode: piiDisplayMode, isAITLoading: isAITLoading, onSettingsClick: handleSettingsClick, onClose: handleClose }), showIDVSuggestion && hitAddress && !props.requireWalletIDVVerification && !hasBerifymeToken && !hasRecordedVerification && (_jsxs("div", { "data-idv-banner": true, css: idvBanner, children: [_jsx("div", { css: css `
|
|
534
536
|
font-size: 20px !important;
|
|
535
537
|
color: #f39c12 !important;
|
|
536
538
|
`, children: "\uD83D\uDCA1" }), _jsxs("div", { css: css `flex: 1 !important;`, children: [_jsx("h5", { css: idvBannerTitle, children: walletTextUtils.getWalletText('Recommended: Verify Your Wallet', serviceId) }), _jsx("p", { css: idvBannerText, children: walletTextUtils.getWalletText('While not required, verifying your wallet with Berify.me provides additional security and trust for your AI agent interactions.', serviceId) }), _jsx("button", { onClick: () => onVerifyWallet('berifyme'), css: idvVerifyButton, children: walletTextUtils.getWalletText('Verify Wallet', serviceId) })] }), _jsx("button", { onClick: handleDismissIDV, css: idvDismissButton, title: `Hide for ${Math.floor((props.idvBannerDismissSeconds || 86400) / 3600)} hours`, children: "\u00D7" })] })), !showIDVSuggestion && dismissUntil && timeRemaining && (_jsxs("div", { css: css `
|
|
@@ -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,EAyc/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, hitAddress, isAutoConnecting, isNeedSignInWithWallet, enableAIT, isAITLoading, isAITEnabling, sendMessage, permissions, availableModels, serviceId, piiDisplayMode, } = useChatBot();
|
|
234
|
+
const { messages, isLoading, isTtsProcessing, requiresGesture, retryTtsWithGesture, connectWallet, signInWallet, 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' });
|
|
@@ -266,6 +266,10 @@ export const MessageList = () => {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
|
+
else if (buttonType === 'verifyWallet') {
|
|
270
|
+
setIsPermissionFormOpen(true);
|
|
271
|
+
setShowPermissionForm(true);
|
|
272
|
+
}
|
|
269
273
|
else if (buttonType === 'continue') {
|
|
270
274
|
const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
|
|
271
275
|
if (lastUserMsg && lastUserMsg.content) {
|
|
@@ -420,11 +424,12 @@ export const MessageList = () => {
|
|
|
420
424
|
chatbotButton, children: isAutoConnecting ? 'Connecting...' :
|
|
421
425
|
message.button === 'connectWallet' ? (Boolean(hitAddress) ? 'Connected' : walletTextUtils.getWalletText('Connect Wallet', serviceId)) :
|
|
422
426
|
message.button === 'signIn' ? (!isNeedSignInWithWallet ? 'Signed In' : 'Sign In') :
|
|
423
|
-
message.button === '
|
|
424
|
-
message.button === '
|
|
425
|
-
|
|
426
|
-
(
|
|
427
|
-
|
|
427
|
+
message.button === 'verifyWallet' ? 'Verify Wallet' :
|
|
428
|
+
message.button === 'continue' ? 'Continue' :
|
|
429
|
+
message.button === 'enableAIT' ?
|
|
430
|
+
((isAITLoading || isAITEnabling) ? 'Enabling...' :
|
|
431
|
+
(message.metadata?.requiredPermission && permissions.includes(message.metadata.requiredPermission)) ? 'AIT Enabled' : 'Enable AIT Permissions') :
|
|
432
|
+
message.button }) }))] }), showPiiHeader && message.piiStatus === 'complete' && entityCount > 0 && (_jsxs("div", { css: css `text-align: right !important;`, children: [_jsxs("button", { css: piiBelowBubbleBtn, onClick: () => setExpandedPiiMsgId(v => v === message.id ? null : message.id), type: "button", children: [_jsx(GreenCheckIcon, {}), entityCount, " item", entityCount !== 1 ? 's' : '', " protected ", isPiiExpanded ? '▴' : '▸'] }), isPiiExpanded && (_jsx("div", { css: piiEntityPanel, children: Object.entries(relevantMapping).map(([original, token]) => (_jsxs("div", { css: piiEntityRowStyle, children: [_jsx("span", { css: piiOriginalStyle, children: original }), _jsx("span", { css: piiArrowStyle, children: "\u2192" }), _jsx("span", { css: piiTokenMappingStyle, children: token })] }, original))) }))] })), message.role === 'assistant' && message.metadata?.model && (_jsxs("div", { css: css `
|
|
428
433
|
${modelIndicator}
|
|
429
434
|
gap: 8px !important;
|
|
430
435
|
`, children: [_jsxs("div", { css: modelBadge, children: [_jsx("span", { css: modelDot }), getModelDisplayName(message.metadata.model)] }), (isTtsProcessing || requiresGesture) && !isLoading && message.id === messages[messages.length - 1]?.id && (_jsxs("div", { css: css `
|
|
@@ -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;
|
|
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,CAsmBxD,CAAC"}
|
|
@@ -4,6 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
import { css } from '@emotion/react';
|
|
5
5
|
import { useChatBot } from '../context/ChatBotContext';
|
|
6
6
|
import { walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
7
|
+
import { hasRecordedWalletVerification } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
7
8
|
import { actionButton } from './styles/isolatedStyles';
|
|
8
9
|
export const PermissionForm = ({ onClose }) => {
|
|
9
10
|
const { hitAddress, permissions, setPermissions, setIsDisabled, onSave, onConnectWallet, onSignIn, isNeedSignInWithWallet, walletInfo, onVerifyWallet, serviceId, nxtlinqApi, permissionGroup, isAITLoading, isWalletLoading = false, refreshAIT, props } = useChatBot();
|
|
@@ -73,12 +74,10 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
73
74
|
}, [hitAddress]);
|
|
74
75
|
// Check if wallet IDV verification is required based on configuration
|
|
75
76
|
const requireWalletIDVVerification = props.requireWalletIDVVerification ?? true; // Default to true
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// 2. IDV verification is required AND wallet is verified but not with Berifyme
|
|
81
|
-
const shouldShowVerificationPrompt = requireWalletIDVVerification && (!isWalletVerified || !isWalletVerifiedWithBerifyme);
|
|
77
|
+
// Any recorded verification source is valid. Custom additionally requires
|
|
78
|
+
// its explicit username evidence so synthetic AIT-provisioned rows do not count.
|
|
79
|
+
const shouldShowVerificationPrompt = requireWalletIDVVerification
|
|
80
|
+
&& (!walletInfo?.id || !hasRecordedWalletVerification(walletInfo));
|
|
82
81
|
const handleSave = async () => {
|
|
83
82
|
setIsSaving(true);
|
|
84
83
|
try {
|
|
@@ -309,9 +308,7 @@ export const PermissionForm = ({ onClose }) => {
|
|
|
309
308
|
margin-bottom: 24px !important;
|
|
310
309
|
font-size: 16px !important;
|
|
311
310
|
color: #666 !important;
|
|
312
|
-
`, children:
|
|
313
|
-
? walletTextUtils.getWalletText('Your wallet is verified with custom method, but Berify.me verification is required to continue.', serviceId)
|
|
314
|
-
: walletTextUtils.getWalletText('Please verify your wallet with Berify.me to continue', serviceId) }), _jsx("button", { onClick: () => onVerifyWallet('berifyme'), css: css `
|
|
311
|
+
`, children: walletTextUtils.getWalletText('Please verify your wallet identity to continue', serviceId) }), _jsx("button", { onClick: () => onVerifyWallet('berifyme'), css: css `
|
|
315
312
|
${actionButton}
|
|
316
313
|
padding: 12px 24px !important;
|
|
317
314
|
background-color: #007bff !important;
|
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.2",
|
|
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": "0.
|
|
42
|
-
"@bytexbyte/nxtlinq-ai-agent-web-development": "0.
|
|
41
|
+
"@bytexbyte/nxtlinq-ai-agent-core-development": "2.0.1",
|
|
42
|
+
"@bytexbyte/nxtlinq-ai-agent-web-development": "1.0.1",
|
|
43
43
|
"@emotion/react": "^11.14.0",
|
|
44
44
|
"@emotion/styled": "^11.14.1",
|
|
45
45
|
"@mui/icons-material": "^7.2.0",
|
|
@@ -55,4 +55,4 @@
|
|
|
55
55
|
"react-dom": "^18.2.0",
|
|
56
56
|
"typescript": "^5.4.2"
|
|
57
57
|
}
|
|
58
|
-
}
|
|
58
|
+
}
|