@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.1.1
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/NxtlinqAgentChat.d.ts +26 -0
- package/dist/NxtlinqAgentChat.d.ts.map +1 -0
- package/dist/NxtlinqAgentChat.js +28 -0
- package/dist/components/AgentAssistantShell.d.ts +5 -0
- package/dist/components/AgentAssistantShell.d.ts.map +1 -0
- package/dist/components/AgentAssistantShell.js +52 -0
- package/dist/components/AgentComposer.d.ts +3 -0
- package/dist/components/AgentComposer.d.ts.map +1 -0
- package/dist/components/AgentComposer.js +60 -0
- package/dist/components/AgentMessageList.d.ts +3 -0
- package/dist/components/AgentMessageList.d.ts.map +1 -0
- package/dist/components/AgentMessageList.js +37 -0
- package/dist/components/AgentRemoteAudio.d.ts +4 -0
- package/dist/components/AgentRemoteAudio.d.ts.map +1 -0
- package/dist/components/AgentRemoteAudio.js +34 -0
- package/dist/components/AgentVoiceBar.d.ts +3 -0
- package/dist/components/AgentVoiceBar.d.ts.map +1 -0
- package/dist/components/AgentVoiceBar.js +91 -0
- package/dist/components/PresetMessageChips.d.ts +3 -0
- package/dist/components/PresetMessageChips.d.ts.map +1 -0
- package/dist/components/PresetMessageChips.js +23 -0
- package/dist/context/AgentAssistantContext.d.ts +32 -0
- package/dist/context/AgentAssistantContext.d.ts.map +1 -0
- package/dist/context/AgentAssistantContext.js +159 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts +2 -0
- package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts.map +1 -0
- package/dist/legacy/assets/images/adiSideItalicDataUri.js +1 -0
- package/dist/legacy/chatbot/ChatBot.d.ts +5 -0
- package/dist/legacy/chatbot/ChatBot.d.ts.map +1 -0
- package/dist/legacy/chatbot/ChatBot.js +35 -0
- package/dist/legacy/chatbot/context/ChatBotContext.d.ts +5 -0
- package/dist/legacy/chatbot/context/ChatBotContext.d.ts.map +1 -0
- package/dist/legacy/chatbot/context/ChatBotContext.js +2908 -0
- package/dist/legacy/chatbot/types/ChatBotTypes.d.ts +166 -0
- package/dist/legacy/chatbot/types/ChatBotTypes.d.ts.map +1 -0
- package/dist/legacy/chatbot/types/ChatBotTypes.js +1 -0
- package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts +17 -0
- package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/BerifyMeModal.js +110 -0
- package/dist/legacy/chatbot/ui/ChatBotUI.d.ts +3 -0
- package/dist/legacy/chatbot/ui/ChatBotUI.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/ChatBotUI.js +625 -0
- package/dist/legacy/chatbot/ui/MessageInput.d.ts +3 -0
- package/dist/legacy/chatbot/ui/MessageInput.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/MessageInput.js +321 -0
- package/dist/legacy/chatbot/ui/MessageList.d.ts +4 -0
- package/dist/legacy/chatbot/ui/MessageList.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/MessageList.js +455 -0
- package/dist/legacy/chatbot/ui/ModelSelector.d.ts +4 -0
- package/dist/legacy/chatbot/ui/ModelSelector.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/ModelSelector.js +122 -0
- package/dist/legacy/chatbot/ui/NotificationModal.d.ts +15 -0
- package/dist/legacy/chatbot/ui/NotificationModal.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/NotificationModal.js +53 -0
- package/dist/legacy/chatbot/ui/PermissionForm.d.ts +8 -0
- package/dist/legacy/chatbot/ui/PermissionForm.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/PermissionForm.js +465 -0
- package/dist/legacy/chatbot/ui/PresetMessages.d.ts +4 -0
- package/dist/legacy/chatbot/ui/PresetMessages.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/PresetMessages.js +33 -0
- package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts +3 -0
- package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/VoiceModePanel.js +95 -0
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts +73 -0
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts.map +1 -0
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.js +985 -0
- package/dist/legacy/index.d.ts +14 -0
- package/dist/legacy/index.d.ts.map +1 -0
- package/dist/legacy/index.js +12 -0
- package/dist/theme/defaultTheme.d.ts +3 -0
- package/dist/theme/defaultTheme.d.ts.map +1 -0
- package/dist/theme/defaultTheme.js +20 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/voice/useVoiceConnectOrchestration.d.ts +21 -0
- package/dist/voice/useVoiceConnectOrchestration.d.ts.map +1 -0
- package/dist/voice/useVoiceConnectOrchestration.js +86 -0
- package/dist/voice/useVoiceMicState.d.ts +15 -0
- package/dist/voice/useVoiceMicState.d.ts.map +1 -0
- package/dist/voice/useVoiceMicState.js +94 -0
- package/dist/voice/useVoiceSilenceCommit.d.ts +10 -0
- package/dist/voice/useVoiceSilenceCommit.d.ts.map +1 -0
- package/dist/voice/useVoiceSilenceCommit.js +67 -0
- package/dist/voice/useVoiceTranscriptMessages.d.ts +16 -0
- package/dist/voice/useVoiceTranscriptMessages.d.ts.map +1 -0
- package/dist/voice/useVoiceTranscriptMessages.js +129 -0
- package/dist/voice/useWsRealtimeAudio.d.ts +18 -0
- package/dist/voice/useWsRealtimeAudio.d.ts.map +1 -0
- package/dist/voice/useWsRealtimeAudio.js +102 -0
- package/dist/voice/voiceMicConstants.d.ts +4 -0
- package/dist/voice/voiceMicConstants.d.ts.map +1 -0
- package/dist/voice/voiceMicConstants.js +10 -0
- package/dist/voice/ws/BrowserWsPcmPlayer.d.ts +23 -0
- package/dist/voice/ws/BrowserWsPcmPlayer.d.ts.map +1 -0
- package/dist/voice/ws/BrowserWsPcmPlayer.js +137 -0
- package/dist/voice/ws/BrowserWsPcmRecorder.d.ts +17 -0
- package/dist/voice/ws/BrowserWsPcmRecorder.d.ts.map +1 -0
- package/dist/voice/ws/BrowserWsPcmRecorder.js +71 -0
- package/dist/voice/ws/float32ToPcm16.d.ts +2 -0
- package/dist/voice/ws/float32ToPcm16.d.ts.map +1 -0
- package/dist/voice/ws/float32ToPcm16.js +8 -0
- package/dist/voice/ws/voiceSilenceConstants.d.ts +5 -0
- package/dist/voice/ws/voiceSilenceConstants.d.ts.map +1 -0
- package/dist/voice/ws/voiceSilenceConstants.js +4 -0
- package/dist/voice/ws/wsRealtimeConstants.d.ts +2 -0
- package/dist/voice/ws/wsRealtimeConstants.d.ts.map +1 -0
- package/dist/voice/ws/wsRealtimeConstants.js +1 -0
- package/package.json +60 -0
- package/src/NxtlinqAgentChat.tsx +79 -0
- package/src/components/AgentAssistantShell.tsx +104 -0
- package/src/components/AgentComposer.tsx +134 -0
- package/src/components/AgentMessageList.tsx +78 -0
- package/src/components/AgentRemoteAudio.tsx +34 -0
- package/src/components/AgentVoiceBar.tsx +173 -0
- package/src/components/PresetMessageChips.tsx +41 -0
- package/src/context/AgentAssistantContext.tsx +276 -0
- package/src/index.ts +78 -0
- package/src/legacy/assets/images/adiSideItalicDataUri.ts +1 -0
- package/src/legacy/chatbot/ChatBot.tsx +61 -0
- package/src/legacy/chatbot/context/ChatBotContext.tsx +3227 -0
- package/src/legacy/chatbot/types/ChatBotTypes.ts +195 -0
- package/src/legacy/chatbot/ui/BerifyMeModal.tsx +145 -0
- package/src/legacy/chatbot/ui/ChatBotUI.tsx +949 -0
- package/src/legacy/chatbot/ui/MessageInput.tsx +517 -0
- package/src/legacy/chatbot/ui/MessageList.tsx +764 -0
- package/src/legacy/chatbot/ui/ModelSelector.tsx +190 -0
- package/src/legacy/chatbot/ui/NotificationModal.tsx +110 -0
- package/src/legacy/chatbot/ui/PermissionForm.tsx +632 -0
- package/src/legacy/chatbot/ui/PresetMessages.tsx +50 -0
- package/src/legacy/chatbot/ui/VoiceModePanel.tsx +168 -0
- package/src/legacy/chatbot/ui/styles/isolatedStyles.ts +1058 -0
- package/src/legacy/index.ts +26 -0
- package/src/theme/defaultTheme.ts +22 -0
- package/src/types.ts +65 -0
- package/src/voice/useVoiceConnectOrchestration.ts +117 -0
- package/src/voice/useVoiceMicState.ts +117 -0
- package/src/voice/useVoiceTranscriptMessages.ts +173 -0
- package/src/voice/voiceMicConstants.ts +13 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
/** @jsxImportSource @emotion/react */
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { css } from '@emotion/react';
|
|
5
|
+
import { convertUrlsToLinks, walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
6
|
+
import { useChatBot } from '../context/ChatBotContext';
|
|
7
|
+
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
|
8
|
+
import { messageListContainer, messageBubble, userMessage, messageContent, userMessageContent, retryMessageContent, chatbotButton, connectedButton, loadingIndicator, modelIndicator, modelBadge, modelDot, streamingCaret, streamingContainer, streamingHeader, streamingIcon, streamingToolName, streamingProgressPercent, streamingProgressContainer, streamingProgressBar, streamingPartialText, streamingStatus, streamingStepsContainer, streamingStepItem, streamingStepCheck, piiTokenReveal, } from './styles/isolatedStyles';
|
|
9
|
+
const piiTokenStatic = {
|
|
10
|
+
fontFamily: 'monospace',
|
|
11
|
+
fontWeight: 400,
|
|
12
|
+
display: 'inline',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Highlight PII tokens in anonymized content.
|
|
16
|
+
* When animate=true (live transition), each token gets a staggered glow animation.
|
|
17
|
+
* When animate=false (loaded from history), tokens are styled statically.
|
|
18
|
+
*/
|
|
19
|
+
function highlightPiiTokens(text, animate = false) {
|
|
20
|
+
const parts = text.split(/(<?[A-Z][A-Z_]*_\d+>?)/g);
|
|
21
|
+
if (parts.length === 1)
|
|
22
|
+
return text;
|
|
23
|
+
let tokenIndex = 0;
|
|
24
|
+
return React.createElement(React.Fragment, null, ...parts.map((part, i) => {
|
|
25
|
+
if (/^<?[A-Z][A-Z_]*_\d+>?$/.test(part)) {
|
|
26
|
+
const idx = tokenIndex++;
|
|
27
|
+
if (animate) {
|
|
28
|
+
return React.createElement('span', {
|
|
29
|
+
key: i,
|
|
30
|
+
css: piiTokenReveal,
|
|
31
|
+
style: { animationDelay: `${idx * 0.25 + 0.6}s` },
|
|
32
|
+
}, part);
|
|
33
|
+
}
|
|
34
|
+
return React.createElement('span', { key: i, style: piiTokenStatic }, part);
|
|
35
|
+
}
|
|
36
|
+
return part;
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
// ===== PII Bubble Header =====
|
|
40
|
+
/** Word-boundary match — prevents PERSON_1 from matching inside PERSON_11 */
|
|
41
|
+
function tokenInText(text, token) {
|
|
42
|
+
return new RegExp(`\\b${token.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(text);
|
|
43
|
+
}
|
|
44
|
+
const ShieldIcon = () => (_jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z" }) }));
|
|
45
|
+
// --- Styles: all PII header styles co-located for maintainability ---
|
|
46
|
+
/** Scan line overlay on the blue bubble during scanning */
|
|
47
|
+
const piiScanOverlay = css `
|
|
48
|
+
overflow: hidden !important;
|
|
49
|
+
&::before {
|
|
50
|
+
content: '' !important;
|
|
51
|
+
position: absolute !important;
|
|
52
|
+
top: 0 !important;
|
|
53
|
+
left: 0 !important;
|
|
54
|
+
width: 100% !important;
|
|
55
|
+
height: 100% !important;
|
|
56
|
+
border-radius: inherit !important;
|
|
57
|
+
pointer-events: none !important;
|
|
58
|
+
z-index: 1 !important;
|
|
59
|
+
background: linear-gradient(
|
|
60
|
+
90deg,
|
|
61
|
+
transparent 0%,
|
|
62
|
+
rgba(255,255,255,0.06) 30%,
|
|
63
|
+
rgba(255,255,255,0.18) 50%,
|
|
64
|
+
rgba(255,255,255,0.06) 70%,
|
|
65
|
+
transparent 100%
|
|
66
|
+
) !important;
|
|
67
|
+
@keyframes piiScanLine {
|
|
68
|
+
0% { transform: translateX(-100%); }
|
|
69
|
+
100% { transform: translateX(100%); }
|
|
70
|
+
}
|
|
71
|
+
animation: piiScanLine 1.8s ease-in-out infinite !important;
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
/** Content fade-in when text swaps from original → redacted */
|
|
75
|
+
const piiContentFadeIn = css `
|
|
76
|
+
@keyframes piiFadeIn {
|
|
77
|
+
0% { opacity: 0.2; }
|
|
78
|
+
100% { opacity: 1; }
|
|
79
|
+
}
|
|
80
|
+
animation: piiFadeIn 0.6s ease-out !important;
|
|
81
|
+
`;
|
|
82
|
+
const piiHeaderRow = css `
|
|
83
|
+
display: flex !important;
|
|
84
|
+
align-items: center !important;
|
|
85
|
+
gap: 5px !important;
|
|
86
|
+
font-size: 11px !important;
|
|
87
|
+
font-weight: 500 !important;
|
|
88
|
+
font-family: inherit !important;
|
|
89
|
+
margin-bottom: 6px !important;
|
|
90
|
+
padding-bottom: 5px !important;
|
|
91
|
+
border-bottom: 1px solid rgba(255,255,255,0.15) !important;
|
|
92
|
+
color: rgba(255,255,255,0.85) !important;
|
|
93
|
+
`;
|
|
94
|
+
const piiScanLabel = css `
|
|
95
|
+
@keyframes piiPulse {
|
|
96
|
+
0%, 100% { opacity: 1; }
|
|
97
|
+
50% { opacity: 0.5; }
|
|
98
|
+
}
|
|
99
|
+
display: inline-flex !important;
|
|
100
|
+
align-items: baseline !important;
|
|
101
|
+
animation: piiPulse 1.2s ease-in-out infinite !important;
|
|
102
|
+
`;
|
|
103
|
+
const piiBounceDot0 = css `
|
|
104
|
+
@keyframes piiBounce {
|
|
105
|
+
0%, 100% { transform: translateY(0); }
|
|
106
|
+
50% { transform: translateY(-3px); }
|
|
107
|
+
}
|
|
108
|
+
display: inline-block !important;
|
|
109
|
+
margin-left: 2px !important;
|
|
110
|
+
animation: piiBounce 0.6s ease-in-out infinite !important;
|
|
111
|
+
animation-delay: 0ms !important;
|
|
112
|
+
`;
|
|
113
|
+
const piiBounceDot1 = css `
|
|
114
|
+
display: inline-block !important;
|
|
115
|
+
animation: piiBounce 0.6s ease-in-out infinite !important;
|
|
116
|
+
animation-delay: 150ms !important;
|
|
117
|
+
`;
|
|
118
|
+
const piiBounceDot2 = css `
|
|
119
|
+
display: inline-block !important;
|
|
120
|
+
animation: piiBounce 0.6s ease-in-out infinite !important;
|
|
121
|
+
animation-delay: 300ms !important;
|
|
122
|
+
`;
|
|
123
|
+
/** Below-bubble green badge: "✓ {N} items protected ▸" */
|
|
124
|
+
const piiBelowBubbleBtn = css `
|
|
125
|
+
all: unset !important;
|
|
126
|
+
display: inline-flex !important;
|
|
127
|
+
align-items: center !important;
|
|
128
|
+
gap: 4px !important;
|
|
129
|
+
font-size: 11px !important;
|
|
130
|
+
font-weight: 600 !important;
|
|
131
|
+
font-family: inherit !important;
|
|
132
|
+
color: #2e7d32 !important;
|
|
133
|
+
background: #e8f5e9 !important;
|
|
134
|
+
border-radius: 12px !important;
|
|
135
|
+
padding: 3px 10px !important;
|
|
136
|
+
margin-top: 6px !important;
|
|
137
|
+
cursor: pointer !important;
|
|
138
|
+
&:hover { background: #c8e6c9 !important; }
|
|
139
|
+
`;
|
|
140
|
+
const piiNoPiiStyle = css `
|
|
141
|
+
@keyframes piiFadeOut {
|
|
142
|
+
0% { opacity: 1; }
|
|
143
|
+
70% { opacity: 1; }
|
|
144
|
+
100% { opacity: 0; }
|
|
145
|
+
}
|
|
146
|
+
animation: piiFadeOut 2s ease-out forwards !important;
|
|
147
|
+
`;
|
|
148
|
+
/** Entity mapping panel — below bubble, original card style */
|
|
149
|
+
const piiEntityPanel = css `
|
|
150
|
+
margin-top: 6px !important;
|
|
151
|
+
padding: 8px 12px !important;
|
|
152
|
+
background-color: #fafafa !important;
|
|
153
|
+
border: 1px solid #e0e0e0 !important;
|
|
154
|
+
border-radius: 8px !important;
|
|
155
|
+
font-family: inherit !important;
|
|
156
|
+
`;
|
|
157
|
+
const piiEntityRowStyle = css `
|
|
158
|
+
display: flex !important;
|
|
159
|
+
align-items: center !important;
|
|
160
|
+
gap: 6px !important;
|
|
161
|
+
font-size: 11px !important;
|
|
162
|
+
line-height: 1.6 !important;
|
|
163
|
+
`;
|
|
164
|
+
const piiOriginalStyle = css `
|
|
165
|
+
color: #d32f2f !important;
|
|
166
|
+
text-decoration: line-through !important;
|
|
167
|
+
font-family: inherit !important;
|
|
168
|
+
`;
|
|
169
|
+
const piiArrowStyle = css `
|
|
170
|
+
color: #bdbdbd !important;
|
|
171
|
+
font-size: 10px !important;
|
|
172
|
+
`;
|
|
173
|
+
const piiTokenMappingStyle = css `
|
|
174
|
+
color: #1565c0 !important;
|
|
175
|
+
font-family: monospace !important;
|
|
176
|
+
font-weight: 600 !important;
|
|
177
|
+
`;
|
|
178
|
+
/** Green checkmark icon for below-bubble badge */
|
|
179
|
+
const GreenCheckIcon = () => (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "#2e7d32", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }));
|
|
180
|
+
/** Status-only header inside the bubble */
|
|
181
|
+
const PiiStatusHeader = React.memo(({ message }) => {
|
|
182
|
+
const getInitialPhase = () => {
|
|
183
|
+
if (message.piiStatus === 'complete' && message.piiProtection?.anonymizedContent)
|
|
184
|
+
return 'done';
|
|
185
|
+
if (message.piiStatus === 'none')
|
|
186
|
+
return 'faded';
|
|
187
|
+
if (message.piiStatus === 'scanning')
|
|
188
|
+
return 'scanning';
|
|
189
|
+
return 'idle';
|
|
190
|
+
};
|
|
191
|
+
const [phase, setPhase] = React.useState(getInitialPhase);
|
|
192
|
+
const prevStatusRef = React.useRef(message.piiStatus);
|
|
193
|
+
const timerRef = React.useRef(null);
|
|
194
|
+
React.useEffect(() => () => { if (timerRef.current)
|
|
195
|
+
clearTimeout(timerRef.current); }, []);
|
|
196
|
+
React.useEffect(() => {
|
|
197
|
+
const prev = prevStatusRef.current;
|
|
198
|
+
const curr = message.piiStatus;
|
|
199
|
+
prevStatusRef.current = curr;
|
|
200
|
+
if (timerRef.current) {
|
|
201
|
+
clearTimeout(timerRef.current);
|
|
202
|
+
timerRef.current = null;
|
|
203
|
+
}
|
|
204
|
+
if (curr === 'scanning' && prev !== 'scanning') {
|
|
205
|
+
setPhase('scanning');
|
|
206
|
+
}
|
|
207
|
+
else if (curr === 'complete') {
|
|
208
|
+
setPhase(message.piiProtection?.anonymizedContent ? 'done' : 'faded');
|
|
209
|
+
}
|
|
210
|
+
else if (curr === 'none') {
|
|
211
|
+
if (prev === 'scanning') {
|
|
212
|
+
setPhase('no-pii');
|
|
213
|
+
timerRef.current = setTimeout(() => setPhase('faded'), 2000);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
setPhase('faded');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}, [message.piiStatus, message.piiProtection?.anonymizedContent]);
|
|
220
|
+
if (phase === 'idle' || phase === 'faded')
|
|
221
|
+
return null;
|
|
222
|
+
if (phase === 'scanning') {
|
|
223
|
+
const step = message.piiStep ?? 0;
|
|
224
|
+
const label = step >= 1 ? 'Sending' : 'Scanning';
|
|
225
|
+
return (_jsxs("div", { css: piiHeaderRow, children: [_jsx(ShieldIcon, {}), _jsxs("span", { css: piiScanLabel, children: [label, _jsx("span", { css: piiBounceDot0, children: "." }), _jsx("span", { css: piiBounceDot1, children: "." }), _jsx("span", { css: piiBounceDot2, children: "." })] })] }));
|
|
226
|
+
}
|
|
227
|
+
if (phase === 'no-pii') {
|
|
228
|
+
return (_jsxs("div", { css: [piiHeaderRow, piiNoPiiStyle], children: [_jsx(ShieldIcon, {}), _jsx("span", { children: "No sensitive data found" })] }));
|
|
229
|
+
}
|
|
230
|
+
// Done: simple status label
|
|
231
|
+
return (_jsxs("div", { css: piiHeaderRow, children: [_jsx(ShieldIcon, {}), _jsx("span", { children: "\u2713 Protected" })] }));
|
|
232
|
+
});
|
|
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();
|
|
235
|
+
const messagesEndRef = React.useRef(null);
|
|
236
|
+
const scrollToBottom = () => {
|
|
237
|
+
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
238
|
+
};
|
|
239
|
+
React.useEffect(() => {
|
|
240
|
+
scrollToBottom();
|
|
241
|
+
}, [messages]);
|
|
242
|
+
// Track which message's PII entity panel is expanded (only one at a time)
|
|
243
|
+
const [expandedPiiMsgId, setExpandedPiiMsgId] = React.useState(null);
|
|
244
|
+
const handleButtonClick = async (buttonType, message) => {
|
|
245
|
+
// Prevent sending messages while AI Agent is processing
|
|
246
|
+
if (isLoading) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (buttonType === 'connectWallet') {
|
|
250
|
+
connectWallet(true);
|
|
251
|
+
}
|
|
252
|
+
else if (buttonType === 'signIn') {
|
|
253
|
+
signInWallet(true);
|
|
254
|
+
}
|
|
255
|
+
else if (buttonType === 'enableAIT') {
|
|
256
|
+
const requiredPermission = message.metadata?.requiredPermission;
|
|
257
|
+
if (requiredPermission) {
|
|
258
|
+
const success = await enableAIT(requiredPermission);
|
|
259
|
+
if (success) {
|
|
260
|
+
// Find the last user message
|
|
261
|
+
const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
|
|
262
|
+
if (lastUserMsg && lastUserMsg.content) {
|
|
263
|
+
// Re-execute the previous user message (retryCount=1 to skip duplicate PII log)
|
|
264
|
+
await sendMessage(lastUserMsg.content, 1);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else if (buttonType === 'continue') {
|
|
270
|
+
const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
|
|
271
|
+
if (lastUserMsg && lastUserMsg.content) {
|
|
272
|
+
// Re-execute the previous user message (retryCount=1 to skip duplicate PII log)
|
|
273
|
+
await sendMessage(lastUserMsg.content, 1);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
// Get model display name from API-provided model list
|
|
278
|
+
const getModelDisplayName = (modelValue) => {
|
|
279
|
+
if (!modelValue)
|
|
280
|
+
return '';
|
|
281
|
+
// Special case: show "Adi" for specific serviceId
|
|
282
|
+
const targetServiceId = 'e48fc2b9-a7d1-49e3-85cb-9d621a0bf774';
|
|
283
|
+
if (serviceId && serviceId.trim() === targetServiceId) {
|
|
284
|
+
return 'Adi';
|
|
285
|
+
}
|
|
286
|
+
// Find model in the list returned by API
|
|
287
|
+
const model = availableModels.find(m => m.value === modelValue);
|
|
288
|
+
// Use label from API or fallback to value
|
|
289
|
+
return model?.label || modelValue;
|
|
290
|
+
};
|
|
291
|
+
return (_jsxs("div", { css: messageListContainer, children: [messages.map((message) => {
|
|
292
|
+
// Determine user message content based on piiStep
|
|
293
|
+
// Show redacted as soon as piiStep >= 1 ({N} protected) — data available
|
|
294
|
+
const showRedacted = message.role === 'user'
|
|
295
|
+
&& piiDisplayMode === 'redacted'
|
|
296
|
+
&& message.piiProtection?.anonymizedContent
|
|
297
|
+
&& (message.piiStep !== undefined && message.piiStep >= 1);
|
|
298
|
+
// Is the bubble currently in scanning state? (for scan overlay animation)
|
|
299
|
+
const isUserScanning = message.role === 'user'
|
|
300
|
+
&& piiDisplayMode === 'redacted'
|
|
301
|
+
&& message.piiStatus === 'scanning';
|
|
302
|
+
const showPiiHeader = message.role === 'user'
|
|
303
|
+
&& piiDisplayMode === 'redacted'
|
|
304
|
+
&& !!message.piiStatus;
|
|
305
|
+
const isPiiExpanded = expandedPiiMsgId === message.id;
|
|
306
|
+
// Compute relevant entity mapping for this message
|
|
307
|
+
let relevantMapping = {};
|
|
308
|
+
if (showPiiHeader && message.piiProtection?.mapping && message.piiProtection?.anonymizedContent) {
|
|
309
|
+
const content = message.piiProtection.anonymizedContent;
|
|
310
|
+
for (const [original, token] of Object.entries(message.piiProtection.mapping)) {
|
|
311
|
+
if (tokenInText(content, token)) {
|
|
312
|
+
relevantMapping[original] = token;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const entityCount = Object.keys(relevantMapping).length;
|
|
317
|
+
const isAgentLikeStream = message.metadata?.agentLlmStream
|
|
318
|
+
|| message.metadata?.voiceRealtime
|
|
319
|
+
|| message.metadata?.model?.endsWith('-stream');
|
|
320
|
+
const isAgentStreamAwaitingFirstToken = message.role === 'assistant'
|
|
321
|
+
&& message.isStreaming
|
|
322
|
+
&& (message.metadata?.agentLlmStream || message.metadata?.model?.endsWith('-stream'))
|
|
323
|
+
&& !(message.partialContent ?? '').length;
|
|
324
|
+
if (isAgentStreamAwaitingFirstToken) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
return (_jsxs("div", { css: message.role === 'user' ? userMessage : messageBubble, children: [_jsxs("div", { css: [
|
|
328
|
+
message.role === 'user'
|
|
329
|
+
? userMessageContent
|
|
330
|
+
: message.metadata?.isRetry
|
|
331
|
+
? retryMessageContent
|
|
332
|
+
: messageContent,
|
|
333
|
+
isUserScanning && piiScanOverlay,
|
|
334
|
+
], children: [showPiiHeader && (_jsx(PiiStatusHeader, { message: message })), message.metadata?.isRetry && (_jsx("span", { css: css `margin-right: 8px !important; font-size: 14px !important;`, children: "\uD83D\uDD04" })), message.attachments && message.attachments.length > 0 && (_jsx("div", { css: css `
|
|
335
|
+
display: flex !important;
|
|
336
|
+
flex-wrap: wrap !important;
|
|
337
|
+
gap: 8px !important;
|
|
338
|
+
margin-bottom: ${message.content ? '10px' : '0'} !important;
|
|
339
|
+
`, children: message.attachments.map((attachment, idx) => (_jsxs("div", { css: css `
|
|
340
|
+
position: relative !important;
|
|
341
|
+
display: inline-block !important;
|
|
342
|
+
border: 1px solid #ddd !important;
|
|
343
|
+
border-radius: 8px !important;
|
|
344
|
+
overflow: hidden !important;
|
|
345
|
+
background: #f5f5f5 !important;
|
|
346
|
+
max-width: 200px !important;
|
|
347
|
+
`, children: [attachment.type === 'image' && (_jsx("img", { src: attachment.url, alt: attachment.name, css: css `
|
|
348
|
+
max-width: 200px !important;
|
|
349
|
+
max-height: 200px !important;
|
|
350
|
+
object-fit: cover !important;
|
|
351
|
+
display: block !important;
|
|
352
|
+
cursor: pointer !important;
|
|
353
|
+
`, onClick: () => {
|
|
354
|
+
// Open image in new window on click
|
|
355
|
+
const newWindow = window.open();
|
|
356
|
+
if (newWindow) {
|
|
357
|
+
newWindow.document.write(`<img src="${attachment.url}" style="max-width: 100%; height: auto;" />`);
|
|
358
|
+
}
|
|
359
|
+
} })), attachment.type === 'file' && (_jsxs("div", { css: css `
|
|
360
|
+
padding: 20px 15px !important;
|
|
361
|
+
text-align: center !important;
|
|
362
|
+
min-width: 150px !important;
|
|
363
|
+
display: flex !important;
|
|
364
|
+
align-items: center !important;
|
|
365
|
+
justify-content: center !important;
|
|
366
|
+
flex-direction: column !important;
|
|
367
|
+
gap: 8px !important;
|
|
368
|
+
`, children: [_jsx(AttachFileIcon, { css: css `font-size: 32px !important; color: #666 !important;` }), _jsx("span", { css: css `
|
|
369
|
+
font-size: 12px !important;
|
|
370
|
+
color: #666 !important;
|
|
371
|
+
word-break: break-word !important;
|
|
372
|
+
max-width: 120px !important;
|
|
373
|
+
`, children: attachment.name }), attachment.size && (_jsxs("span", { css: css `
|
|
374
|
+
font-size: 10px !important;
|
|
375
|
+
color: #999 !important;
|
|
376
|
+
`, children: [(attachment.size / 1024).toFixed(1), " KB"] }))] }))] }, idx))) })), message.isStreaming && message.metadata?.voiceRealtime
|
|
377
|
+
&& (message.partialContent ?? '').length > 0 && (_jsxs("div", { css: streamingPartialText, children: [message.role === 'assistant'
|
|
378
|
+
? convertUrlsToLinks(message.partialContent ?? '')
|
|
379
|
+
: message.partialContent, _jsx("span", { css: streamingCaret, children: "\u258A" })] })), message.isStreaming && message.role === 'assistant'
|
|
380
|
+
&& (message.metadata?.agentLlmStream || message.metadata?.model?.endsWith('-stream'))
|
|
381
|
+
&& !message.metadata?.voiceRealtime
|
|
382
|
+
&& (message.partialContent ?? '').length > 0 && (_jsxs("div", { css: streamingPartialText, children: [convertUrlsToLinks(message.partialContent ?? ''), _jsx("span", { css: streamingCaret, children: "\u258A" })] })), message.isStreaming && message.partialContent
|
|
383
|
+
&& !message.metadata?.voiceRealtime
|
|
384
|
+
&& !(message.metadata?.agentLlmStream || message.metadata?.model?.endsWith('-stream')) && (_jsxs("div", { css: streamingPartialText, children: [message.role === 'assistant' ? convertUrlsToLinks(message.partialContent) : message.partialContent, _jsx("span", { css: streamingCaret, children: "\u258A" })] })), message.isStreaming && !message.partialContent && message.role === 'assistant'
|
|
385
|
+
&& !isAgentLikeStream && (_jsxs("div", { css: streamingContainer, children: [_jsxs("div", { css: streamingHeader, children: [_jsx("span", { css: streamingIcon, children: "\uD83D\uDD27" }), _jsx("span", { css: streamingToolName, children: message.streamingToolName || 'Processing' }), message.streamingProgress !== undefined && (_jsxs("span", { css: streamingProgressPercent, children: [message.streamingProgress, "%"] }))] }), message.streamingProgress !== undefined && (_jsx("div", { css: streamingProgressContainer, children: _jsx("div", { css: [streamingProgressBar, css `width: ${message.streamingProgress}% !important;`] }) })), message.streamingStatus && (_jsx("div", { css: streamingStatus, children: message.streamingStatus })), message.streamingSteps && message.streamingSteps.length > 0 && (_jsx("div", { css: streamingStepsContainer, children: message.streamingSteps.map((step, idx) => (_jsxs("div", { css: streamingStepItem, children: [_jsx("span", { css: streamingStepCheck, children: "\u2713" }), _jsx("span", { children: step })] }, idx))) }))] })), !message.isStreaming && (() => {
|
|
386
|
+
// User message with redacted PII available — show tokens with fade-in
|
|
387
|
+
if (showRedacted) {
|
|
388
|
+
const isLive = message.piiStatus === 'scanning';
|
|
389
|
+
const content = highlightPiiTokens(message.piiProtection.anonymizedContent, isLive);
|
|
390
|
+
return isLive
|
|
391
|
+
? _jsx("span", { css: piiContentFadeIn, children: content })
|
|
392
|
+
: content;
|
|
393
|
+
}
|
|
394
|
+
// User message during scanning (step 0) — show original text (scan overlay handles animation)
|
|
395
|
+
if (isUserScanning && !showRedacted) {
|
|
396
|
+
return message.content;
|
|
397
|
+
}
|
|
398
|
+
// Assistant message with redacted PII
|
|
399
|
+
if (message.role === 'assistant'
|
|
400
|
+
&& piiDisplayMode === 'redacted'
|
|
401
|
+
&& message.piiProtection?.anonymizedContent) {
|
|
402
|
+
return highlightPiiTokens(message.piiProtection.anonymizedContent, false);
|
|
403
|
+
}
|
|
404
|
+
// Default
|
|
405
|
+
return message.role === 'assistant'
|
|
406
|
+
? convertUrlsToLinks(message.content)
|
|
407
|
+
: message.content;
|
|
408
|
+
})(), message.button && (_jsx("div", { css: css `margin-top: 10px !important;`, children: _jsx("button", { onClick: () => {
|
|
409
|
+
if (message.button && message.button.trim()) {
|
|
410
|
+
handleButtonClick(message.button, message);
|
|
411
|
+
}
|
|
412
|
+
}, disabled: isAutoConnecting ||
|
|
413
|
+
(message.button === 'connectWallet' && Boolean(hitAddress)) ||
|
|
414
|
+
(message.button === 'signIn' && !isNeedSignInWithWallet) ||
|
|
415
|
+
(message.button === 'enableAIT' && (isAITLoading || isAITEnabling ||
|
|
416
|
+
(message.metadata?.requiredPermission && permissions.includes(message.metadata.requiredPermission)))) || false, css: (message.button === 'connectWallet' && Boolean(hitAddress)) ? connectedButton :
|
|
417
|
+
(message.button === 'signIn' && !isNeedSignInWithWallet) ? connectedButton :
|
|
418
|
+
(message.button === 'continue') ? connectedButton :
|
|
419
|
+
(message.button === 'enableAIT' && (message.metadata?.requiredPermission && permissions.includes(message.metadata.requiredPermission))) ? connectedButton :
|
|
420
|
+
chatbotButton, children: isAutoConnecting ? 'Connecting...' :
|
|
421
|
+
message.button === 'connectWallet' ? (Boolean(hitAddress) ? 'Connected' : walletTextUtils.getWalletText('Connect Wallet', serviceId)) :
|
|
422
|
+
message.button === 'signIn' ? (!isNeedSignInWithWallet ? 'Signed In' : 'Sign In') :
|
|
423
|
+
message.button === 'continue' ? 'Continue' :
|
|
424
|
+
message.button === 'enableAIT' ?
|
|
425
|
+
((isAITLoading || isAITEnabling) ? 'Enabling...' :
|
|
426
|
+
(message.metadata?.requiredPermission && permissions.includes(message.metadata.requiredPermission)) ? 'AIT Enabled' : 'Enable AIT Permissions') :
|
|
427
|
+
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
|
+
${modelIndicator}
|
|
429
|
+
gap: 8px !important;
|
|
430
|
+
`, 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 `
|
|
431
|
+
display: flex !important;
|
|
432
|
+
align-items: center !important;
|
|
433
|
+
font-size: 12px !important;
|
|
434
|
+
color: #666 !important;
|
|
435
|
+
gap: 4px !important;
|
|
436
|
+
`, children: [_jsx("span", { role: "img", "aria-hidden": "true", children: "\uD83D\uDD0A" }), _jsx("span", { children: requiresGesture ? (_jsx("button", { onClick: () => retryTtsWithGesture && retryTtsWithGesture(), css: css `
|
|
437
|
+
background: none !important;
|
|
438
|
+
border: none !important;
|
|
439
|
+
color: #1976d2 !important;
|
|
440
|
+
padding: 0 !important;
|
|
441
|
+
text-decoration: underline !important;
|
|
442
|
+
cursor: pointer !important;
|
|
443
|
+
`, children: "Tap to play voice" })) : 'Preparing voice reply...' })] }))] }))] }, message.id));
|
|
444
|
+
}), isLoading && (() => {
|
|
445
|
+
// During PII pipeline (step 0-1), hide "Thinking..." — message hasn't been sent to AI yet.
|
|
446
|
+
// Only show once Send step (2) is reached, meaning the anonymized message was sent to AI.
|
|
447
|
+
if (piiDisplayMode === 'redacted') {
|
|
448
|
+
const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
|
|
449
|
+
if (lastUserMsg?.piiStatus === 'scanning' && (lastUserMsg.piiStep === undefined || lastUserMsg.piiStep < 2)) {
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return (_jsx("div", { css: loadingIndicator, children: "Thinking..." }));
|
|
454
|
+
})(), _jsx("div", { ref: messagesEndRef })] }));
|
|
455
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../../../src/legacy/chatbot/ui/ModelSelector.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAsLjC,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
/** @jsxImportSource @emotion/react */
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { css } from '@emotion/react';
|
|
5
|
+
import { useChatBot } from '../context/ChatBotContext';
|
|
6
|
+
import { walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
7
|
+
import { adiSideItalicDataUri } from '../../assets/images/adiSideItalicDataUri';
|
|
8
|
+
export const ModelSelector = () => {
|
|
9
|
+
const { availableModels, selectedModelIndex, handleModelChange, serviceId } = useChatBot();
|
|
10
|
+
// Safety check: ensure selectedModelIndex is within bounds
|
|
11
|
+
const safeSelectedModelIndex = selectedModelIndex >= availableModels.length ? 0 : selectedModelIndex;
|
|
12
|
+
// Check if current service is Adilas
|
|
13
|
+
const isAdilasService = walletTextUtils.isAdilasService(serviceId);
|
|
14
|
+
// Get fallback model label (first available model or 'Unknown')
|
|
15
|
+
// For Adilas, we don't show the label, only the image
|
|
16
|
+
const fallbackModelLabel = availableModels.length > 0
|
|
17
|
+
? availableModels[0].label
|
|
18
|
+
: 'Unknown';
|
|
19
|
+
const [anchorEl, setAnchorEl] = React.useState(null);
|
|
20
|
+
const open = Boolean(anchorEl);
|
|
21
|
+
const handleClick = (event) => {
|
|
22
|
+
setAnchorEl(event.currentTarget);
|
|
23
|
+
};
|
|
24
|
+
const handleMenuItemClick = (event, index) => {
|
|
25
|
+
handleModelChange(index);
|
|
26
|
+
setAnchorEl(null);
|
|
27
|
+
};
|
|
28
|
+
const handleClose = () => {
|
|
29
|
+
setAnchorEl(null);
|
|
30
|
+
};
|
|
31
|
+
// Don't show anything if no models available
|
|
32
|
+
if (availableModels.length === 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
// For Adilas: only show image, no text (Adilas always has only 1 model)
|
|
36
|
+
if (isAdilasService) {
|
|
37
|
+
return (_jsx("div", { css: css `
|
|
38
|
+
display: flex !important;
|
|
39
|
+
align-items: center !important;
|
|
40
|
+
gap: 6px !important;
|
|
41
|
+
`, children: _jsx("div", { css: css `
|
|
42
|
+
background-color: white !important;
|
|
43
|
+
border-radius: 4px !important;
|
|
44
|
+
padding: 2px !important;
|
|
45
|
+
display: flex !important;
|
|
46
|
+
align-items: center !important;
|
|
47
|
+
justify-content: center !important;
|
|
48
|
+
`, children: _jsx("img", { src: adiSideItalicDataUri, alt: "Adi", css: css `
|
|
49
|
+
width: 28px !important;
|
|
50
|
+
height: 28px !important;
|
|
51
|
+
display: block !important;
|
|
52
|
+
` }) }) }));
|
|
53
|
+
}
|
|
54
|
+
// For other services: handle single or multiple models
|
|
55
|
+
// If only 1 model, show model name
|
|
56
|
+
if (availableModels.length === 1) {
|
|
57
|
+
return (_jsx("div", { css: css `
|
|
58
|
+
display: flex !important;
|
|
59
|
+
align-items: center !important;
|
|
60
|
+
gap: 6px !important;
|
|
61
|
+
`, children: _jsx("div", { css: css `
|
|
62
|
+
display: flex !important;
|
|
63
|
+
align-items: center !important;
|
|
64
|
+
padding: 4px 8px !important;
|
|
65
|
+
border-radius: 4px !important;
|
|
66
|
+
background-color: rgba(255, 255, 255, 0.1) !important;
|
|
67
|
+
font-size: 12px !important;
|
|
68
|
+
font-weight: 500 !important;
|
|
69
|
+
`, children: _jsx("span", { children: availableModels[0].label }) }) }));
|
|
70
|
+
}
|
|
71
|
+
// If 2+ models, show full selector with dropdown
|
|
72
|
+
return (_jsxs("div", { css: css `
|
|
73
|
+
display: flex !important;
|
|
74
|
+
align-items: center !important;
|
|
75
|
+
position: relative !important;
|
|
76
|
+
gap: 6px !important;
|
|
77
|
+
`, children: [_jsxs("div", { css: css `
|
|
78
|
+
display: flex !important;
|
|
79
|
+
align-items: center !important;
|
|
80
|
+
cursor: pointer !important;
|
|
81
|
+
padding: 4px 8px !important;
|
|
82
|
+
border-radius: 4px !important;
|
|
83
|
+
background-color: rgba(255, 255, 255, 0.1) !important;
|
|
84
|
+
transition: background-color 0.2s !important;
|
|
85
|
+
font-size: 12px !important;
|
|
86
|
+
font-weight: 500 !important;
|
|
87
|
+
gap: 6px !important;
|
|
88
|
+
|
|
89
|
+
&:hover {
|
|
90
|
+
background-color: rgba(255, 255, 255, 0.2) !important;
|
|
91
|
+
}
|
|
92
|
+
`, onClick: handleClick, title: "Change AI Model", children: [_jsx("span", { children: availableModels[safeSelectedModelIndex]?.label || fallbackModelLabel }), _jsx("span", { css: css `font-size: 10px !important;`, children: "\u25BC" })] }), open && (_jsx("div", { css: css `
|
|
93
|
+
position: absolute !important;
|
|
94
|
+
top: 100% !important;
|
|
95
|
+
left: 0 !important;
|
|
96
|
+
background-color: white !important;
|
|
97
|
+
border: 1px solid #ddd !important;
|
|
98
|
+
border-radius: 4px !important;
|
|
99
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
|
|
100
|
+
z-index: 1000 !important;
|
|
101
|
+
min-width: 120px !important;
|
|
102
|
+
margin-top: 4px !important;
|
|
103
|
+
`, children: availableModels.map((model, index) => (_jsx("div", { css: css `
|
|
104
|
+
padding: 8px 12px !important;
|
|
105
|
+
cursor: pointer !important;
|
|
106
|
+
background-color: ${index === safeSelectedModelIndex ? '#f0f0f0' : 'transparent'} !important;
|
|
107
|
+
color: ${index === safeSelectedModelIndex ? '#007bff' : '#333'} !important;
|
|
108
|
+
font-size: 12px !important;
|
|
109
|
+
border-bottom: ${index < availableModels.length - 1 ? '1px solid #eee' : 'none'} !important;
|
|
110
|
+
|
|
111
|
+
&:hover {
|
|
112
|
+
background-color: ${index === safeSelectedModelIndex ? '#f0f0f0' : '#f8f9fa'} !important;
|
|
113
|
+
}
|
|
114
|
+
`, onClick: (event) => handleMenuItemClick(event, index), children: model.label }, model.value))) })), open && (_jsx("div", { css: css `
|
|
115
|
+
position: fixed !important;
|
|
116
|
+
top: 0 !important;
|
|
117
|
+
left: 0 !important;
|
|
118
|
+
right: 0 !important;
|
|
119
|
+
bottom: 0 !important;
|
|
120
|
+
z-index: 999 !important;
|
|
121
|
+
`, onClick: handleClose }))] }));
|
|
122
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @jsxImportSource @emotion/react */
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
interface NotificationModalProps {
|
|
4
|
+
type: 'success' | 'error' | 'info' | 'warning';
|
|
5
|
+
title: string;
|
|
6
|
+
message: string;
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
onConfirm?: () => void;
|
|
9
|
+
showConfirm?: boolean;
|
|
10
|
+
confirmText?: string;
|
|
11
|
+
cancelText?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const NotificationModal: React.FC<NotificationModalProps>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=NotificationModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationModal.d.ts","sourceRoot":"","sources":["../../../../src/legacy/chatbot/ui/NotificationModal.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,UAAU,sBAAsB;IAC9B,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA4F9D,CAAC"}
|