@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.0 → 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 +84 -405
- 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/types/ChatBotTypes.d.ts +0 -5
- package/dist/types/ChatBotTypes.d.ts.map +1 -1
- package/dist/ui/ChatBotHeader.d.ts.map +1 -1
- package/dist/ui/ChatBotHeader.js +6 -2
- package/dist/ui/ChatBotUI.d.ts.map +1 -1
- package/dist/ui/ChatBotUI.js +13 -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/dist/ui/styles/isolatedStyles.d.ts.map +1 -1
- package/dist/ui/styles/isolatedStyles.js +1 -0
- package/package.json +3 -3
- package/src/context/ChatBotContext.tsx +92 -437
- package/src/index.ts +5 -0
- package/src/types/ChatBotTypes.ts +2 -6
- package/src/ui/ChatBotHeader.tsx +9 -3
- package/src/ui/ChatBotUI.tsx +14 -5
- package/src/ui/MessageList.tsx +6 -0
- package/src/ui/PermissionForm.tsx +7 -12
- package/src/ui/styles/isolatedStyles.ts +1 -0
- package/dist/NxtlinqAgentChat.d.ts +0 -26
- package/dist/NxtlinqAgentChat.d.ts.map +0 -1
- package/dist/NxtlinqAgentChat.js +0 -28
- package/dist/components/AgentAssistantShell.d.ts +0 -5
- package/dist/components/AgentAssistantShell.d.ts.map +0 -1
- package/dist/components/AgentAssistantShell.js +0 -52
- package/dist/components/AgentComposer.d.ts +0 -3
- package/dist/components/AgentComposer.d.ts.map +0 -1
- package/dist/components/AgentComposer.js +0 -60
- package/dist/components/AgentMessageList.d.ts +0 -3
- package/dist/components/AgentMessageList.d.ts.map +0 -1
- package/dist/components/AgentMessageList.js +0 -37
- package/dist/components/AgentRemoteAudio.d.ts +0 -4
- package/dist/components/AgentRemoteAudio.d.ts.map +0 -1
- package/dist/components/AgentRemoteAudio.js +0 -34
- package/dist/components/AgentVoiceBar.d.ts +0 -3
- package/dist/components/AgentVoiceBar.d.ts.map +0 -1
- package/dist/components/AgentVoiceBar.js +0 -91
- package/dist/components/PresetMessageChips.d.ts +0 -3
- package/dist/components/PresetMessageChips.d.ts.map +0 -1
- package/dist/components/PresetMessageChips.js +0 -23
- package/dist/context/AgentAssistantContext.d.ts +0 -32
- package/dist/context/AgentAssistantContext.d.ts.map +0 -1
- package/dist/context/AgentAssistantContext.js +0 -179
- package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts +0 -2
- package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts.map +0 -1
- package/dist/legacy/assets/images/adiSideItalicDataUri.js +0 -1
- package/dist/legacy/chatbot/ChatBot.d.ts +0 -5
- package/dist/legacy/chatbot/ChatBot.d.ts.map +0 -1
- package/dist/legacy/chatbot/ChatBot.js +0 -35
- package/dist/legacy/chatbot/context/ChatBotContext.d.ts +0 -5
- package/dist/legacy/chatbot/context/ChatBotContext.d.ts.map +0 -1
- package/dist/legacy/chatbot/context/ChatBotContext.js +0 -2922
- package/dist/legacy/chatbot/types/ChatBotTypes.d.ts +0 -166
- package/dist/legacy/chatbot/types/ChatBotTypes.d.ts.map +0 -1
- package/dist/legacy/chatbot/types/ChatBotTypes.js +0 -1
- package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts +0 -17
- package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/BerifyMeModal.js +0 -110
- package/dist/legacy/chatbot/ui/ChatBotHeader.d.ts +0 -15
- package/dist/legacy/chatbot/ui/ChatBotHeader.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/ChatBotHeader.js +0 -62
- package/dist/legacy/chatbot/ui/ChatBotUI.d.ts +0 -3
- package/dist/legacy/chatbot/ui/ChatBotUI.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/ChatBotUI.js +0 -557
- package/dist/legacy/chatbot/ui/MessageInput.d.ts +0 -3
- package/dist/legacy/chatbot/ui/MessageInput.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/MessageInput.js +0 -321
- package/dist/legacy/chatbot/ui/MessageList.d.ts +0 -4
- package/dist/legacy/chatbot/ui/MessageList.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/MessageList.js +0 -455
- package/dist/legacy/chatbot/ui/ModelSelector.d.ts +0 -4
- package/dist/legacy/chatbot/ui/ModelSelector.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/ModelSelector.js +0 -122
- package/dist/legacy/chatbot/ui/NotificationModal.d.ts +0 -15
- package/dist/legacy/chatbot/ui/NotificationModal.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/NotificationModal.js +0 -53
- package/dist/legacy/chatbot/ui/PermissionForm.d.ts +0 -8
- package/dist/legacy/chatbot/ui/PermissionForm.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/PermissionForm.js +0 -465
- package/dist/legacy/chatbot/ui/PresetMessages.d.ts +0 -4
- package/dist/legacy/chatbot/ui/PresetMessages.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/PresetMessages.js +0 -33
- package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts +0 -3
- package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/VoiceModePanel.js +0 -95
- package/dist/legacy/chatbot/ui/chatBotHeaderParts.d.ts +0 -15
- package/dist/legacy/chatbot/ui/chatBotHeaderParts.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/chatBotHeaderParts.js +0 -50
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts +0 -73
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts.map +0 -1
- package/dist/legacy/chatbot/ui/styles/isolatedStyles.js +0 -985
- package/dist/legacy/index.d.ts +0 -14
- package/dist/legacy/index.d.ts.map +0 -1
- package/dist/legacy/index.js +0 -12
- package/dist/theme/defaultTheme.d.ts +0 -3
- package/dist/theme/defaultTheme.d.ts.map +0 -1
- package/dist/theme/defaultTheme.js +0 -20
- package/dist/types.d.ts +0 -62
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -1
- package/dist/voice/useVoiceConnectOrchestration.d.ts +0 -21
- package/dist/voice/useVoiceConnectOrchestration.d.ts.map +0 -1
- package/dist/voice/useVoiceConnectOrchestration.js +0 -86
- package/dist/voice/useVoiceMicState.d.ts +0 -15
- package/dist/voice/useVoiceMicState.d.ts.map +0 -1
- package/dist/voice/useVoiceMicState.js +0 -94
- package/dist/voice/useVoiceSilenceCommit.d.ts +0 -10
- package/dist/voice/useVoiceSilenceCommit.d.ts.map +0 -1
- package/dist/voice/useVoiceSilenceCommit.js +0 -67
- package/dist/voice/useVoiceTranscriptMessages.d.ts +0 -18
- package/dist/voice/useVoiceTranscriptMessages.d.ts.map +0 -1
- package/dist/voice/useVoiceTranscriptMessages.js +0 -132
- package/dist/voice/useWsRealtimeAudio.d.ts +0 -18
- package/dist/voice/useWsRealtimeAudio.d.ts.map +0 -1
- package/dist/voice/useWsRealtimeAudio.js +0 -102
- package/dist/voice/voiceMicConstants.d.ts +0 -4
- package/dist/voice/voiceMicConstants.d.ts.map +0 -1
- package/dist/voice/voiceMicConstants.js +0 -10
- package/dist/voice/voiceUserBubble.d.ts +0 -10
- package/dist/voice/voiceUserBubble.d.ts.map +0 -1
- package/dist/voice/voiceUserBubble.js +0 -52
- package/dist/voice/ws/BrowserWsPcmPlayer.d.ts +0 -23
- package/dist/voice/ws/BrowserWsPcmPlayer.d.ts.map +0 -1
- package/dist/voice/ws/BrowserWsPcmPlayer.js +0 -137
- package/dist/voice/ws/BrowserWsPcmRecorder.d.ts +0 -17
- package/dist/voice/ws/BrowserWsPcmRecorder.d.ts.map +0 -1
- package/dist/voice/ws/BrowserWsPcmRecorder.js +0 -71
- package/dist/voice/ws/float32ToPcm16.d.ts +0 -2
- package/dist/voice/ws/float32ToPcm16.d.ts.map +0 -1
- package/dist/voice/ws/float32ToPcm16.js +0 -8
- package/dist/voice/ws/voiceSilenceConstants.d.ts +0 -5
- package/dist/voice/ws/voiceSilenceConstants.d.ts.map +0 -1
- package/dist/voice/ws/voiceSilenceConstants.js +0 -4
- package/dist/voice/ws/wsRealtimeConstants.d.ts +0 -2
- package/dist/voice/ws/wsRealtimeConstants.d.ts.map +0 -1
- package/dist/voice/ws/wsRealtimeConstants.js +0 -1
package/src/ui/ChatBotHeader.tsx
CHANGED
|
@@ -121,21 +121,27 @@ export const ChatBotHeader: React.FC<ChatBotHeaderProps> = ({
|
|
|
121
121
|
z-index: 2 !important;
|
|
122
122
|
display: flex !important;
|
|
123
123
|
justify-content: space-between !important;
|
|
124
|
-
align-items:
|
|
124
|
+
align-items: flex-start !important;
|
|
125
125
|
width: 100% !important;
|
|
126
126
|
pointer-events: none !important;
|
|
127
127
|
`}>
|
|
128
128
|
<div css={css`
|
|
129
129
|
display: flex !important;
|
|
130
130
|
align-items: center !important;
|
|
131
|
+
flex-wrap: wrap !important;
|
|
132
|
+
row-gap: 8px !important;
|
|
131
133
|
gap: 10px !important;
|
|
132
134
|
min-width: 0 !important;
|
|
135
|
+
flex: 1 1 auto !important;
|
|
136
|
+
padding-top: 2px !important;
|
|
133
137
|
pointer-events: none !important;
|
|
134
138
|
`}>
|
|
135
|
-
<h3 css={headerTitle}>AI Agent</h3>
|
|
139
|
+
<h3 css={[headerTitle, css`flex-shrink: 0 !important;`]}>AI Agent</h3>
|
|
136
140
|
{metaChips}
|
|
137
141
|
</div>
|
|
138
|
-
{
|
|
142
|
+
<div css={css`flex-shrink: 0 !important;`}>
|
|
143
|
+
{actions}
|
|
144
|
+
</div>
|
|
139
145
|
</div>
|
|
140
146
|
)}
|
|
141
147
|
</div>
|
package/src/ui/ChatBotUI.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @jsxImportSource @emotion/react */
|
|
2
2
|
import { css } from '@emotion/react';
|
|
3
3
|
import * as React from 'react';
|
|
4
|
+
import { hasRecordedWalletVerification } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
4
5
|
import { useDraggable, useLocalStorage, useResizable, walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
5
6
|
import { useChatBot } from '../context/ChatBotContext';
|
|
6
7
|
import { ChatBotHeader } from './ChatBotHeader';
|
|
@@ -33,6 +34,12 @@ import {
|
|
|
33
34
|
const MOBILE_BREAKPOINT = 768;
|
|
34
35
|
const MOBILE_EDGE_MARGIN = 12;
|
|
35
36
|
const MOBILE_FAB_POSITION = { right: MOBILE_EDGE_MARGIN, bottom: MOBILE_EDGE_MARGIN } as const;
|
|
37
|
+
// Below this widget width, the desktop header's single-row layout (title + model/PII chips +
|
|
38
|
+
// voice/settings/close actions, all in one line) has no room left and the chips start
|
|
39
|
+
// overlapping the actions. The user can drag the window this narrow (MIN_WIDTH is 320px) even
|
|
40
|
+
// on a wide desktop viewport, so this must be driven by the widget's own width, not just
|
|
41
|
+
// window.innerWidth — falling back to the same stacked layout used on mobile viewports.
|
|
42
|
+
const HEADER_COMPACT_WIDTH = 420;
|
|
36
43
|
|
|
37
44
|
const isMobileViewport = (): boolean =>
|
|
38
45
|
typeof window !== 'undefined' && window.innerWidth <= MOBILE_BREAKPOINT;
|
|
@@ -123,6 +130,7 @@ export const ChatBotUI: React.FC = () => {
|
|
|
123
130
|
const { position, handleDragStart, isDragging, updatePosition } = useDraggable(dimensions);
|
|
124
131
|
|
|
125
132
|
const [mobileLayout, setMobileLayout] = React.useState(isMobileViewport);
|
|
133
|
+
const headerCompactLayout = mobileLayout || dimensions.width < HEADER_COMPACT_WIDTH;
|
|
126
134
|
React.useEffect(() => {
|
|
127
135
|
if (typeof window === 'undefined') return;
|
|
128
136
|
const mq = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`);
|
|
@@ -154,7 +162,8 @@ export const ChatBotUI: React.FC = () => {
|
|
|
154
162
|
const urlParams = new URLSearchParams(window.location.search);
|
|
155
163
|
const hasBerifymeToken = urlParams.get('token') && urlParams.get('method') === 'berifyme';
|
|
156
164
|
|
|
157
|
-
const
|
|
165
|
+
const hasRecordedVerification = Boolean(walletInfo?.id)
|
|
166
|
+
&& hasRecordedWalletVerification(walletInfo);
|
|
158
167
|
|
|
159
168
|
// Helper function to update IDV suggestion state based on storage value
|
|
160
169
|
const updateIDVSuggestionState = React.useCallback((dismissedValue: string | null) => {
|
|
@@ -214,7 +223,7 @@ export const ChatBotUI: React.FC = () => {
|
|
|
214
223
|
const shouldShowBanner = hitAddress &&
|
|
215
224
|
!props.requireWalletIDVVerification &&
|
|
216
225
|
!hasBerifymeToken &&
|
|
217
|
-
!
|
|
226
|
+
!hasRecordedVerification &&
|
|
218
227
|
!isNeedSignInWithWallet;
|
|
219
228
|
|
|
220
229
|
if (shouldShowBanner) {
|
|
@@ -222,7 +231,7 @@ export const ChatBotUI: React.FC = () => {
|
|
|
222
231
|
const shouldShowBannerAfterDelay = hitAddress &&
|
|
223
232
|
!props.requireWalletIDVVerification &&
|
|
224
233
|
!hasBerifymeToken &&
|
|
225
|
-
!
|
|
234
|
+
!hasRecordedVerification &&
|
|
226
235
|
!isNeedSignInWithWallet;
|
|
227
236
|
|
|
228
237
|
if (shouldShowBannerAfterDelay) {
|
|
@@ -709,7 +718,7 @@ export const ChatBotUI: React.FC = () => {
|
|
|
709
718
|
)}
|
|
710
719
|
|
|
711
720
|
<ChatBotHeader
|
|
712
|
-
mobileLayout={
|
|
721
|
+
mobileLayout={headerCompactLayout}
|
|
713
722
|
isDragging={isDragging}
|
|
714
723
|
onDragStart={handleDragStart}
|
|
715
724
|
isVoiceMode={isVoiceMode}
|
|
@@ -721,7 +730,7 @@ export const ChatBotUI: React.FC = () => {
|
|
|
721
730
|
onClose={handleClose}
|
|
722
731
|
/>
|
|
723
732
|
|
|
724
|
-
{showIDVSuggestion && hitAddress && !props.requireWalletIDVVerification && !hasBerifymeToken && !
|
|
733
|
+
{showIDVSuggestion && hitAddress && !props.requireWalletIDVVerification && !hasBerifymeToken && !hasRecordedVerification && (
|
|
725
734
|
<div
|
|
726
735
|
data-idv-banner
|
|
727
736
|
css={idvBanner}>
|
package/src/ui/MessageList.tsx
CHANGED
|
@@ -330,6 +330,8 @@ export const MessageList: React.FC = () => {
|
|
|
330
330
|
availableModels,
|
|
331
331
|
serviceId,
|
|
332
332
|
piiDisplayMode,
|
|
333
|
+
setShowPermissionForm,
|
|
334
|
+
setIsPermissionFormOpen,
|
|
333
335
|
} = useChatBot();
|
|
334
336
|
const messagesEndRef = React.useRef<HTMLDivElement>(null);
|
|
335
337
|
|
|
@@ -367,6 +369,9 @@ export const MessageList: React.FC = () => {
|
|
|
367
369
|
}
|
|
368
370
|
}
|
|
369
371
|
}
|
|
372
|
+
} else if (buttonType === 'verifyWallet') {
|
|
373
|
+
setIsPermissionFormOpen(true);
|
|
374
|
+
setShowPermissionForm(true);
|
|
370
375
|
} else if (buttonType === 'continue') {
|
|
371
376
|
const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');
|
|
372
377
|
if (lastUserMsg && lastUserMsg.content) {
|
|
@@ -672,6 +677,7 @@ export const MessageList: React.FC = () => {
|
|
|
672
677
|
{isAutoConnecting ? 'Connecting...' :
|
|
673
678
|
message.button === 'connectWallet' ? (Boolean(hitAddress) ? 'Connected' : walletTextUtils.getWalletText('Connect Wallet', serviceId)) :
|
|
674
679
|
message.button === 'signIn' ? (!isNeedSignInWithWallet ? 'Signed In' : 'Sign In') :
|
|
680
|
+
message.button === 'verifyWallet' ? 'Verify Wallet' :
|
|
675
681
|
message.button === 'continue' ? 'Continue' :
|
|
676
682
|
message.button === 'enableAIT' ?
|
|
677
683
|
((isAITLoading || isAITEnabling) ? 'Enabling...' :
|
|
@@ -3,6 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { css } from '@emotion/react';
|
|
4
4
|
import { useChatBot } from '../context/ChatBotContext';
|
|
5
5
|
import { walletTextUtils } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
6
|
+
import { hasRecordedWalletVerification } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
6
7
|
import { actionButton, modalOverlay } from './styles/isolatedStyles';
|
|
7
8
|
|
|
8
9
|
interface PermissionFormProps {
|
|
@@ -103,13 +104,10 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
103
104
|
|
|
104
105
|
// Check if wallet IDV verification is required based on configuration
|
|
105
106
|
const requireWalletIDVVerification = props.requireWalletIDVVerification ?? true; // Default to true
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// 1. IDV verification is required AND wallet is not verified, OR
|
|
111
|
-
// 2. IDV verification is required AND wallet is verified but not with Berifyme
|
|
112
|
-
const shouldShowVerificationPrompt = requireWalletIDVVerification && (!isWalletVerified || !isWalletVerifiedWithBerifyme);
|
|
107
|
+
// Any recorded verification source is valid. Custom additionally requires
|
|
108
|
+
// its explicit username evidence so synthetic AIT-provisioned rows do not count.
|
|
109
|
+
const shouldShowVerificationPrompt = requireWalletIDVVerification
|
|
110
|
+
&& (!walletInfo?.id || !hasRecordedWalletVerification(walletInfo));
|
|
113
111
|
|
|
114
112
|
const handleSave = async () => {
|
|
115
113
|
setIsSaving(true);
|
|
@@ -415,10 +413,7 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
415
413
|
font-size: 16px !important;
|
|
416
414
|
color: #666 !important;
|
|
417
415
|
`}>
|
|
418
|
-
{
|
|
419
|
-
? walletTextUtils.getWalletText('Your wallet is verified with custom method, but Berify.me verification is required to continue.', serviceId)
|
|
420
|
-
: walletTextUtils.getWalletText('Please verify your wallet with Berify.me to continue', serviceId)
|
|
421
|
-
}
|
|
416
|
+
{walletTextUtils.getWalletText('Please verify your wallet identity to continue', serviceId)}
|
|
422
417
|
</p>
|
|
423
418
|
<button
|
|
424
419
|
onClick={() => onVerifyWallet('berifyme')}
|
|
@@ -629,4 +624,4 @@ export const PermissionForm: React.FC<PermissionFormProps> = ({ onClose }) => {
|
|
|
629
624
|
)}
|
|
630
625
|
</div>
|
|
631
626
|
);
|
|
632
|
-
};
|
|
627
|
+
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { NxtlinqAgentChatProps } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* Drop-in React Web assistant UI wired to `@bytexbyte/nxtlinq-ai-agent-web-development`.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```tsx
|
|
8
|
-
* import { NxtlinqAgentChat } from '@bytexbyte/nxtlinq-ai-agent-ui-react-development';
|
|
9
|
-
*
|
|
10
|
-
* export default function Page() {
|
|
11
|
-
* return (
|
|
12
|
-
* <NxtlinqAgentChat
|
|
13
|
-
* style={{ height: '100vh' }}
|
|
14
|
-
* serviceId="..."
|
|
15
|
-
* apiKey="..."
|
|
16
|
-
* apiSecret="..."
|
|
17
|
-
* environment="staging"
|
|
18
|
-
* pseudoId={userId}
|
|
19
|
-
* loadHistoryOnMount
|
|
20
|
-
* />
|
|
21
|
-
* );
|
|
22
|
-
* }
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export declare function NxtlinqAgentChat({ title, placeholder, presetMessages, loadHistoryOnMount, historyLast, enableVoice, enableFileUpload, startInVoiceMode, startWithMicMuted, holdMicDuringAssistant, theme, style, headerStyle, onMessage, onError, onToolUse, children, fetchImpl, getTimezone, resetOnIdentityChange, ...agentConfig }: NxtlinqAgentChatProps): React.ReactElement;
|
|
26
|
-
//# sourceMappingURL=NxtlinqAgentChat.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NxtlinqAgentChat.d.ts","sourceRoot":"","sources":["../src/NxtlinqAgentChat.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,WAAW,EACX,cAAc,EACd,kBAA0B,EAC1B,WAAW,EACX,WAAkB,EAClB,gBAAuB,EACvB,gBAAwB,EACxB,iBAAwB,EACxB,sBAA6B,EAC7B,KAAK,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,qBAAqB,EACrB,GAAG,WAAW,EACf,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CA6B5C"}
|
package/dist/NxtlinqAgentChat.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { NxtlinqAgentProvider } from '@bytexbyte/nxtlinq-ai-agent-web-development';
|
|
3
|
-
import { AgentAssistantShell } from './components/AgentAssistantShell';
|
|
4
|
-
/**
|
|
5
|
-
* Drop-in React Web assistant UI wired to `@bytexbyte/nxtlinq-ai-agent-web-development`.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```tsx
|
|
9
|
-
* import { NxtlinqAgentChat } from '@bytexbyte/nxtlinq-ai-agent-ui-react-development';
|
|
10
|
-
*
|
|
11
|
-
* export default function Page() {
|
|
12
|
-
* return (
|
|
13
|
-
* <NxtlinqAgentChat
|
|
14
|
-
* style={{ height: '100vh' }}
|
|
15
|
-
* serviceId="..."
|
|
16
|
-
* apiKey="..."
|
|
17
|
-
* apiSecret="..."
|
|
18
|
-
* environment="staging"
|
|
19
|
-
* pseudoId={userId}
|
|
20
|
-
* loadHistoryOnMount
|
|
21
|
-
* />
|
|
22
|
-
* );
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export function NxtlinqAgentChat({ title, placeholder, presetMessages, loadHistoryOnMount = false, historyLast, enableVoice = true, enableFileUpload = true, startInVoiceMode = false, startWithMicMuted = true, holdMicDuringAssistant = true, theme, style, headerStyle, onMessage, onError, onToolUse, children, fetchImpl, getTimezone, resetOnIdentityChange, ...agentConfig }) {
|
|
27
|
-
return (_jsxs(NxtlinqAgentProvider, { fetchImpl: fetchImpl, getTimezone: getTimezone, resetOnIdentityChange: resetOnIdentityChange, onMessage: onMessage, onError: onError, onToolUse: onToolUse, ...agentConfig, children: [_jsx(AgentAssistantShell, { title: title, placeholder: placeholder, presetMessages: presetMessages, loadHistoryOnMount: loadHistoryOnMount, historyLast: historyLast, enableVoice: enableVoice, enableFileUpload: enableFileUpload, startInVoiceMode: startInVoiceMode, startWithMicMuted: startWithMicMuted, holdMicDuringAssistant: holdMicDuringAssistant, theme: theme, style: style, headerStyle: headerStyle }), children] }));
|
|
28
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { NxtlinqAgentChatProps } from '../types';
|
|
3
|
-
export type AgentAssistantShellProps = Pick<NxtlinqAgentChatProps, 'title' | 'placeholder' | 'presetMessages' | 'enableVoice' | 'enableFileUpload' | 'theme' | 'style' | 'headerStyle' | 'loadHistoryOnMount' | 'historyLast' | 'startInVoiceMode' | 'startWithMicMuted' | 'holdMicDuringAssistant'>;
|
|
4
|
-
export declare function AgentAssistantShell(props: AgentAssistantShellProps): React.ReactElement;
|
|
5
|
-
//# sourceMappingURL=AgentAssistantShell.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AgentAssistantShell.d.ts","sourceRoot":"","sources":["../../src/components/AgentAssistantShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAK3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAOtD,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,qBAAqB,EACnB,OAAO,GACP,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,kBAAkB,GAClB,OAAO,GACP,OAAO,GACP,aAAa,GACb,oBAAoB,GACpB,aAAa,GACb,kBAAkB,GAClB,mBAAmB,GACnB,wBAAwB,CAC3B,CAAC;AA2DF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,KAAK,CAAC,YAAY,CAiBvF"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef, useState } from 'react';
|
|
3
|
-
import { AgentAssistantProvider, useAgentAssistant, } from '../context/AgentAssistantContext';
|
|
4
|
-
import { AgentComposer } from './AgentComposer';
|
|
5
|
-
import { AgentMessageList } from './AgentMessageList';
|
|
6
|
-
import { AgentRemoteAudio } from './AgentRemoteAudio';
|
|
7
|
-
import { AgentVoiceBar } from './AgentVoiceBar';
|
|
8
|
-
import { PresetMessageChips } from './PresetMessageChips';
|
|
9
|
-
function AgentAssistantInner({ title, headerStyle, style, loadHistoryOnMount, historyLast, startInVoiceMode, }) {
|
|
10
|
-
const { theme, loadHistory, startVoice, isVoiceAvailable } = useAgentAssistant();
|
|
11
|
-
const [historyReady, setHistoryReady] = useState(!loadHistoryOnMount);
|
|
12
|
-
const voiceAutoStartRef = useRef(false);
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
if (loadHistoryOnMount) {
|
|
15
|
-
void loadHistory({ last: historyLast ?? 50 }).finally(() => setHistoryReady(true));
|
|
16
|
-
}
|
|
17
|
-
}, [loadHistory, loadHistoryOnMount, historyLast]);
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
if (!startInVoiceMode || !isVoiceAvailable || voiceAutoStartRef.current)
|
|
20
|
-
return;
|
|
21
|
-
voiceAutoStartRef.current = true;
|
|
22
|
-
void startVoice();
|
|
23
|
-
}, [startInVoiceMode, isVoiceAvailable, startVoice]);
|
|
24
|
-
return (_jsxs("div", { style: {
|
|
25
|
-
display: 'flex',
|
|
26
|
-
flexDirection: 'column',
|
|
27
|
-
flex: 1,
|
|
28
|
-
minHeight: 0,
|
|
29
|
-
backgroundColor: theme.colors.background,
|
|
30
|
-
...style,
|
|
31
|
-
}, children: [_jsx("header", { style: {
|
|
32
|
-
padding: theme.spacing.md,
|
|
33
|
-
borderBottom: `1px solid ${theme.colors.border}`,
|
|
34
|
-
backgroundColor: theme.colors.surface,
|
|
35
|
-
fontSize: theme.typography.titleSize,
|
|
36
|
-
fontWeight: 600,
|
|
37
|
-
color: theme.colors.assistantText,
|
|
38
|
-
...headerStyle,
|
|
39
|
-
}, children: title ?? 'AI Assistant' }), _jsx(PresetMessageChips, {}), historyReady ? _jsx(AgentMessageList, {}) : _jsx("div", { style: { flex: 1 } }), _jsx(AgentVoiceBar, {}), _jsx(AgentComposer, {}), _jsx(AgentRemoteAudio, {})] }));
|
|
40
|
-
}
|
|
41
|
-
export function AgentAssistantShell(props) {
|
|
42
|
-
return (_jsx(AgentAssistantProvider, { ui: {
|
|
43
|
-
title: props.title,
|
|
44
|
-
placeholder: props.placeholder,
|
|
45
|
-
presetMessages: props.presetMessages,
|
|
46
|
-
enableVoice: props.enableVoice,
|
|
47
|
-
enableFileUpload: props.enableFileUpload,
|
|
48
|
-
theme: props.theme,
|
|
49
|
-
startWithMicMuted: props.startWithMicMuted,
|
|
50
|
-
holdMicDuringAssistant: props.holdMicDuringAssistant,
|
|
51
|
-
}, children: _jsx(AgentAssistantInner, { ...props }) }));
|
|
52
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AgentComposer.d.ts","sourceRoot":"","sources":["../../src/components/AgentComposer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,wBAAgB,aAAa,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAkIzD"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { useAgentAssistant } from '../context/AgentAssistantContext';
|
|
4
|
-
export function AgentComposer() {
|
|
5
|
-
const { theme, placeholder, inputText, setInputText, sendText, isLoading, isVoiceAvailable, interactionMode, startVoice, isVoiceConnecting, enableFileUpload, sendMessage, } = useAgentAssistant();
|
|
6
|
-
const fileInputRef = React.useRef(null);
|
|
7
|
-
if (interactionMode === 'voice') {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
const handleFiles = async (files) => {
|
|
11
|
-
if (!files?.length)
|
|
12
|
-
return;
|
|
13
|
-
const { fileToAttachment } = await import('@bytexbyte/nxtlinq-ai-agent-web-development');
|
|
14
|
-
const attachments = await Promise.all(Array.from(files).map((file) => fileToAttachment(file)));
|
|
15
|
-
await sendMessage(attachments.length ? `Uploaded ${attachments.length} file(s)` : '', { attachments });
|
|
16
|
-
if (fileInputRef.current)
|
|
17
|
-
fileInputRef.current.value = '';
|
|
18
|
-
};
|
|
19
|
-
return (_jsxs("div", { style: {
|
|
20
|
-
borderTop: `1px solid ${theme.colors.border}`,
|
|
21
|
-
backgroundColor: theme.colors.surface,
|
|
22
|
-
padding: theme.spacing.md,
|
|
23
|
-
}, children: [_jsxs("div", { style: { display: 'flex', gap: theme.spacing.sm, alignItems: 'flex-end' }, children: [enableFileUpload ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => fileInputRef.current?.click(), disabled: isLoading, style: {
|
|
24
|
-
width: 36,
|
|
25
|
-
height: 36,
|
|
26
|
-
borderRadius: theme.radius.button,
|
|
27
|
-
border: `1px solid ${theme.colors.border}`,
|
|
28
|
-
backgroundColor: theme.colors.surface,
|
|
29
|
-
cursor: 'pointer',
|
|
30
|
-
}, "aria-label": "Upload file", children: "+" }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, accept: "image/*,.pdf,.doc,.docx,.txt", style: { display: 'none' }, onChange: (e) => void handleFiles(e.target.files) })] })) : null, _jsx("textarea", { value: inputText, onChange: (e) => setInputText(e.target.value), placeholder: placeholder, rows: 2, disabled: isLoading, maxLength: 4000, style: {
|
|
31
|
-
flex: 1,
|
|
32
|
-
resize: 'none',
|
|
33
|
-
border: `1px solid ${theme.colors.border}`,
|
|
34
|
-
borderRadius: theme.radius.panel,
|
|
35
|
-
padding: theme.spacing.sm,
|
|
36
|
-
fontSize: theme.typography.bodySize,
|
|
37
|
-
color: theme.colors.assistantText,
|
|
38
|
-
} }), _jsx("button", { type: "button", onClick: () => void sendText(), disabled: isLoading || !inputText.trim(), style: {
|
|
39
|
-
backgroundColor: theme.colors.primary,
|
|
40
|
-
color: theme.colors.primaryText,
|
|
41
|
-
border: 'none',
|
|
42
|
-
borderRadius: theme.radius.button,
|
|
43
|
-
padding: `${theme.spacing.sm}px ${theme.spacing.md}px`,
|
|
44
|
-
fontWeight: 600,
|
|
45
|
-
opacity: isLoading || !inputText.trim() ? 0.5 : 1,
|
|
46
|
-
cursor: 'pointer',
|
|
47
|
-
}, children: "Send" })] }), isVoiceAvailable ? (_jsx("button", { type: "button", onClick: () => {
|
|
48
|
-
startVoice().catch((err) => {
|
|
49
|
-
console.warn('[nxtlinq] startVoice failed:', err);
|
|
50
|
-
});
|
|
51
|
-
}, disabled: isVoiceConnecting, style: {
|
|
52
|
-
display: 'block',
|
|
53
|
-
margin: `${theme.spacing.sm}px auto 0`,
|
|
54
|
-
border: 'none',
|
|
55
|
-
background: 'none',
|
|
56
|
-
color: theme.colors.primary,
|
|
57
|
-
fontSize: theme.typography.captionSize,
|
|
58
|
-
cursor: 'pointer',
|
|
59
|
-
}, children: isVoiceConnecting ? 'Connecting voice…' : 'Switch to voice mode' })) : null] }));
|
|
60
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AgentMessageList.d.ts","sourceRoot":"","sources":["../../src/components/AgentMessageList.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAyCjD,wBAAgB,gBAAgB,IAAI,KAAK,CAAC,YAAY,CAmCrD"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
3
|
-
import { useAgentAssistant } from '../context/AgentAssistantContext';
|
|
4
|
-
function MessageBubble({ message }) {
|
|
5
|
-
const { theme } = useAgentAssistant();
|
|
6
|
-
const isUser = message.role === 'user';
|
|
7
|
-
const displayText = message.partialContent && message.isStreaming
|
|
8
|
-
? message.partialContent
|
|
9
|
-
: message.content;
|
|
10
|
-
return (_jsx("div", { style: {
|
|
11
|
-
display: 'flex',
|
|
12
|
-
justifyContent: isUser ? 'flex-end' : 'flex-start',
|
|
13
|
-
marginBottom: theme.spacing.sm,
|
|
14
|
-
}, children: _jsxs("div", { style: {
|
|
15
|
-
maxWidth: '85%',
|
|
16
|
-
padding: `${theme.spacing.sm}px ${theme.spacing.md}px`,
|
|
17
|
-
borderRadius: theme.radius.bubble,
|
|
18
|
-
backgroundColor: isUser ? theme.colors.userBubble : theme.colors.assistantBubble,
|
|
19
|
-
color: isUser ? theme.colors.userText : theme.colors.assistantText,
|
|
20
|
-
fontSize: theme.typography.bodySize,
|
|
21
|
-
whiteSpace: 'pre-wrap',
|
|
22
|
-
}, children: [displayText || ' ', message.error ? (_jsx("div", { style: { color: theme.colors.error, fontSize: theme.typography.captionSize }, children: message.error })) : null] }) }));
|
|
23
|
-
}
|
|
24
|
-
export function AgentMessageList() {
|
|
25
|
-
const { messages, isLoading, theme } = useAgentAssistant();
|
|
26
|
-
const endRef = useRef(null);
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
endRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
29
|
-
}, [messages.length, messages[messages.length - 1]?.content, messages[messages.length - 1]?.partialContent]);
|
|
30
|
-
return (_jsxs("div", { style: {
|
|
31
|
-
flex: 1,
|
|
32
|
-
minHeight: 0,
|
|
33
|
-
overflowY: 'auto',
|
|
34
|
-
padding: theme.spacing.md,
|
|
35
|
-
backgroundColor: theme.colors.background,
|
|
36
|
-
}, children: [messages.length === 0 ? (_jsx("p", { style: { textAlign: 'center', color: theme.colors.mutedText, marginTop: 40 }, children: "Send a message to start the conversation." })) : (messages.map((message) => (_jsx(MessageBubble, { message: message }, message.id)))), isLoading ? (_jsx("p", { style: { color: theme.colors.mutedText, fontSize: theme.typography.captionSize }, children: "Thinking\u2026" })) : null, _jsx("div", { ref: endRef })] }));
|
|
37
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AgentRemoteAudio.d.ts","sourceRoot":"","sources":["../../src/components/AgentRemoteAudio.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,4EAA4E;AAC5E,wBAAgB,gBAAgB,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CA6B5D"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
3
|
-
import { useAgentAssistant } from '../context/AgentAssistantContext';
|
|
4
|
-
/** Plays assistant WebRTC remote audio with retry until stream is ready. */
|
|
5
|
-
export function AgentRemoteAudio() {
|
|
6
|
-
const { getRemoteAudioStream, isVoiceActive, isVoiceChannelReady } = useAgentAssistant();
|
|
7
|
-
const audioRef = useRef(null);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
const audio = audioRef.current;
|
|
10
|
-
if (!audio || !isVoiceActive)
|
|
11
|
-
return;
|
|
12
|
-
let cancelled = false;
|
|
13
|
-
const attach = () => {
|
|
14
|
-
if (cancelled)
|
|
15
|
-
return;
|
|
16
|
-
const stream = getRemoteAudioStream();
|
|
17
|
-
if (!stream)
|
|
18
|
-
return;
|
|
19
|
-
audio.srcObject = stream;
|
|
20
|
-
void audio.play().catch(() => undefined);
|
|
21
|
-
};
|
|
22
|
-
attach();
|
|
23
|
-
const timer = window.setInterval(attach, 120);
|
|
24
|
-
return () => {
|
|
25
|
-
cancelled = true;
|
|
26
|
-
window.clearInterval(timer);
|
|
27
|
-
audio.pause();
|
|
28
|
-
audio.srcObject = null;
|
|
29
|
-
};
|
|
30
|
-
}, [getRemoteAudioStream, isVoiceActive, isVoiceChannelReady]);
|
|
31
|
-
if (!isVoiceActive)
|
|
32
|
-
return null;
|
|
33
|
-
return _jsx("audio", { ref: audioRef, autoPlay: true, playsInline: true, style: { display: 'none' } });
|
|
34
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AgentVoiceBar.d.ts","sourceRoot":"","sources":["../../src/components/AgentVoiceBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAsC3C,wBAAgB,aAAa,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAsIzD"}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { useCallback } from 'react';
|
|
3
|
-
import { useAgentAssistant, voiceStatusLabel, } from '../context/AgentAssistantContext';
|
|
4
|
-
function statusDotColor(status, theme) {
|
|
5
|
-
switch (status) {
|
|
6
|
-
case 'listening':
|
|
7
|
-
return theme.colors.voiceActive;
|
|
8
|
-
case 'speaking':
|
|
9
|
-
return theme.colors.voiceSpeaking;
|
|
10
|
-
case 'idle':
|
|
11
|
-
return theme.colors.mutedText;
|
|
12
|
-
default:
|
|
13
|
-
return theme.colors.primary;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function MicIcon({ color }) {
|
|
17
|
-
return (_jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: color, "aria-hidden": true, children: _jsx("path", { d: "M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5-3c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z" }) }));
|
|
18
|
-
}
|
|
19
|
-
function MicOffIcon() {
|
|
20
|
-
return (_jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "#ef4444", "aria-hidden": true, children: _jsx("path", { d: "M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3s-3 1.34-3 3v.18l5.98 5.99zM4.27 3L3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z" }) }));
|
|
21
|
-
}
|
|
22
|
-
export function AgentVoiceBar() {
|
|
23
|
-
const { theme, interactionMode, voiceStatus, voiceSessionId, isVoiceConnecting, isVoiceChannelReady, stopVoice, isVoiceAvailable, isMicMuted, isMicHeldForAssistant, toggleVoiceMicMute, } = useAgentAssistant();
|
|
24
|
-
const returnToTextMode = useCallback(() => {
|
|
25
|
-
void stopVoice();
|
|
26
|
-
}, [stopVoice]);
|
|
27
|
-
if (!isVoiceAvailable)
|
|
28
|
-
return null;
|
|
29
|
-
if (interactionMode !== 'voice' && !isVoiceConnecting)
|
|
30
|
-
return null;
|
|
31
|
-
const showConnecting = isVoiceConnecting;
|
|
32
|
-
const awaitingChannel = Boolean(voiceSessionId) &&
|
|
33
|
-
!isVoiceConnecting &&
|
|
34
|
-
!isVoiceChannelReady &&
|
|
35
|
-
voiceStatus === 'idle';
|
|
36
|
-
const statusHint = showConnecting
|
|
37
|
-
? 'Tap Back to text mode below to cancel'
|
|
38
|
-
: awaitingChannel
|
|
39
|
-
? 'Waiting for voice channel…'
|
|
40
|
-
: isMicHeldForAssistant
|
|
41
|
-
? 'Assistant is responding — tap mic to interrupt and speak'
|
|
42
|
-
: isMicMuted
|
|
43
|
-
? 'Mic is off — tap the mic when ready to speak'
|
|
44
|
-
: voiceStatus === 'listening'
|
|
45
|
-
? 'Start speaking'
|
|
46
|
-
: voiceStatus === 'speaking'
|
|
47
|
-
? 'Assistant is speaking…'
|
|
48
|
-
: voiceStatus === 'thinking'
|
|
49
|
-
? 'Thinking…'
|
|
50
|
-
: '';
|
|
51
|
-
return (_jsxs("div", { style: {
|
|
52
|
-
borderTop: `1px solid ${theme.colors.border}`,
|
|
53
|
-
backgroundColor: theme.colors.surface,
|
|
54
|
-
padding: theme.spacing.md,
|
|
55
|
-
}, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 10 }, children: [_jsxs("div", { style: {
|
|
56
|
-
flex: 1,
|
|
57
|
-
minWidth: 0,
|
|
58
|
-
border: `1px solid ${theme.colors.border}`,
|
|
59
|
-
borderRadius: 12,
|
|
60
|
-
backgroundColor: theme.colors.background,
|
|
61
|
-
padding: '8px 10px',
|
|
62
|
-
}, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 6 }, children: [_jsx("span", { style: {
|
|
63
|
-
width: 8,
|
|
64
|
-
height: 8,
|
|
65
|
-
borderRadius: 4,
|
|
66
|
-
backgroundColor: statusDotColor(voiceStatus, theme),
|
|
67
|
-
flexShrink: 0,
|
|
68
|
-
} }), _jsx("span", { style: {
|
|
69
|
-
color: theme.colors.assistantText,
|
|
70
|
-
fontSize: theme.typography.captionSize,
|
|
71
|
-
fontWeight: 600,
|
|
72
|
-
}, children: showConnecting || awaitingChannel ? 'Connecting' : voiceStatusLabel(voiceStatus) }), showConnecting ? (_jsx("span", { style: { color: theme.colors.mutedText, fontSize: theme.typography.captionSize }, children: "\u2026" })) : null] }), statusHint ? (_jsx("p", { style: {
|
|
73
|
-
margin: '4px 0 0',
|
|
74
|
-
color: theme.colors.mutedText,
|
|
75
|
-
fontSize: theme.typography.captionSize - 1,
|
|
76
|
-
}, children: statusHint })) : null] }), _jsx("button", { type: "button", onClick: toggleVoiceMicMute, disabled: showConnecting || awaitingChannel, style: {
|
|
77
|
-
border: 'none',
|
|
78
|
-
background: 'none',
|
|
79
|
-
padding: 8,
|
|
80
|
-
cursor: showConnecting || awaitingChannel ? 'not-allowed' : 'pointer',
|
|
81
|
-
opacity: showConnecting || awaitingChannel ? 0.45 : 1,
|
|
82
|
-
}, "aria-label": isMicMuted ? 'Unmute microphone' : 'Mute microphone', children: isMicMuted ? _jsx(MicOffIcon, {}) : _jsx(MicIcon, { color: theme.colors.assistantText }) })] }), _jsx("button", { type: "button", onClick: returnToTextMode, style: {
|
|
83
|
-
display: 'block',
|
|
84
|
-
margin: `${theme.spacing.sm}px auto 0`,
|
|
85
|
-
border: 'none',
|
|
86
|
-
background: 'none',
|
|
87
|
-
color: theme.colors.primary,
|
|
88
|
-
fontSize: theme.typography.captionSize,
|
|
89
|
-
cursor: 'pointer',
|
|
90
|
-
}, children: "Back to text mode" })] }));
|
|
91
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PresetMessageChips.d.ts","sourceRoot":"","sources":["../../src/components/PresetMessageChips.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,wBAAgB,kBAAkB,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAoC9D"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { useAgentAssistant } from '../context/AgentAssistantContext';
|
|
3
|
-
export function PresetMessageChips() {
|
|
4
|
-
const { presetMessages, selectPreset, theme, interactionMode } = useAgentAssistant();
|
|
5
|
-
if (!presetMessages.length || interactionMode === 'voice') {
|
|
6
|
-
return null;
|
|
7
|
-
}
|
|
8
|
-
return (_jsx("div", { style: {
|
|
9
|
-
display: 'flex',
|
|
10
|
-
flexWrap: 'wrap',
|
|
11
|
-
gap: theme.spacing.sm,
|
|
12
|
-
padding: `${theme.spacing.sm}px ${theme.spacing.md}px`,
|
|
13
|
-
borderBottom: `1px solid ${theme.colors.border}`,
|
|
14
|
-
}, children: presetMessages.map((preset, index) => (_jsx("button", { type: "button", onClick: () => void selectPreset(preset), style: {
|
|
15
|
-
border: `1px solid ${theme.colors.border}`,
|
|
16
|
-
borderRadius: theme.radius.button,
|
|
17
|
-
padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,
|
|
18
|
-
backgroundColor: theme.colors.surface,
|
|
19
|
-
color: theme.colors.assistantText,
|
|
20
|
-
fontSize: theme.typography.captionSize,
|
|
21
|
-
cursor: 'pointer',
|
|
22
|
-
}, children: preset.text }, `${preset.text}-${index}`))) }));
|
|
23
|
-
}
|