@bytexbyte/nxtlinq-ai-agent-sdk 1.6.29 → 1.6.31
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/components/context/ChatBotContext.d.ts.map +1 -1
- package/dist/components/context/ChatBotContext.js +211 -69
- package/dist/components/types/ChatBotTypes.d.ts +8 -1
- package/dist/components/types/ChatBotTypes.d.ts.map +1 -1
- package/dist/components/ui/ChatBotUI.d.ts.map +1 -1
- package/dist/components/ui/ChatBotUI.js +255 -16
- package/dist/components/ui/MessageList.d.ts.map +1 -1
- package/dist/components/ui/MessageList.js +6 -2
- package/dist/components/ui/styles/isolatedStyles.d.ts +14 -0
- package/dist/components/ui/styles/isolatedStyles.d.ts.map +1 -1
- package/dist/components/ui/styles/isolatedStyles.js +138 -7
- package/dist/core/lib/textToSpeech.js +1 -1
- package/dist/core/lib/useDraggable.d.ts +15 -0
- package/dist/core/lib/useDraggable.d.ts.map +1 -0
- package/dist/core/lib/useDraggable.js +158 -0
- package/dist/core/lib/useResizable.d.ts +16 -0
- package/dist/core/lib/useResizable.d.ts.map +1 -0
- package/dist/core/lib/useResizable.js +180 -0
- package/dist/core/lib/useSpeechToTextFromMic/helper.d.ts.map +1 -1
- package/dist/core/lib/useSpeechToTextFromMic/helper.js +13 -1
- package/dist/core/utils/aitUtils.js +1 -1
- package/dist/core/utils/ethersUtils.d.ts +8 -0
- package/dist/core/utils/ethersUtils.d.ts.map +1 -0
- package/dist/core/utils/ethersUtils.js +19 -0
- package/dist/core/utils/index.d.ts +1 -0
- package/dist/core/utils/index.d.ts.map +1 -1
- package/dist/core/utils/index.js +1 -0
- package/dist/core/utils/walletUtils.d.ts +1 -1
- package/dist/core/utils/walletUtils.d.ts.map +1 -1
- package/dist/core/utils/walletUtils.js +5 -1
- package/dist/types/ait-api.d.ts +6 -0
- package/dist/types/ait-api.d.ts.map +1 -1
- package/package.json +3 -3
- package/umd/nxtlinq-ai-agent.umd.js +212 -92
- package/dist/assets/images/adilasDogHeadTiltDataUri.d.ts +0 -2
- package/dist/assets/images/adilasDogHeadTiltDataUri.d.ts.map +0 -1
- package/dist/assets/images/adilasDogHeadTiltDataUri.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../../src/components/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../../src/components/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAosFlD,CAAC"}
|
|
@@ -9,7 +9,7 @@ import useSessionStorage from '../../core/lib/useSessionStorage';
|
|
|
9
9
|
import { useSpeechToTextFromMic } from '../../core/lib/useSpeechToTextFromMic';
|
|
10
10
|
import textToBuffer, { getDefaultSpeechToken } from '../../core/lib/textToSpeech';
|
|
11
11
|
import metakeepClient from '../../core/metakeepClient';
|
|
12
|
-
import { sleep } from '../../core/utils';
|
|
12
|
+
import { sleep, getEthers } from '../../core/utils';
|
|
13
13
|
import * as walletTextUtils from '../../core/utils/walletTextUtils';
|
|
14
14
|
const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
|
|
15
15
|
const ChatBotContext = React.createContext(undefined);
|
|
@@ -34,7 +34,9 @@ customUsername,
|
|
|
34
34
|
// IDV suggestion banner configuration
|
|
35
35
|
idvBannerDismissSeconds = 86400,
|
|
36
36
|
// 24 hours in seconds
|
|
37
|
-
isStopRecordingOnSend = false,
|
|
37
|
+
isStopRecordingOnSend = false,
|
|
38
|
+
// Custom error message to display in chat
|
|
39
|
+
customError, }) => {
|
|
38
40
|
// Set API hosts immediately based on environment (before any API calls)
|
|
39
41
|
setApiHosts(environment);
|
|
40
42
|
const nxtlinqApi = React.useMemo(() => createNxtlinqApi(apiKey, apiSecret), [apiKey, apiSecret]);
|
|
@@ -121,6 +123,7 @@ isStopRecordingOnSend = false, }) => {
|
|
|
121
123
|
const lastPartialRangeRef = React.useRef(null);
|
|
122
124
|
const lastAutoSentTranscriptRef = React.useRef('');
|
|
123
125
|
const autoSendTimerRef = React.useRef(null);
|
|
126
|
+
const lastCustomErrorRef = React.useRef(undefined);
|
|
124
127
|
function insertPartial(input, partial, caret) {
|
|
125
128
|
let start = caret;
|
|
126
129
|
let end = caret;
|
|
@@ -802,12 +805,15 @@ isStopRecordingOnSend = false, }) => {
|
|
|
802
805
|
return;
|
|
803
806
|
}
|
|
804
807
|
try {
|
|
808
|
+
getEthers();
|
|
805
809
|
const web3Provider = await metakeepClient.ethereum;
|
|
806
810
|
if (!web3Provider) {
|
|
807
811
|
throw new Error('Web3 provider not available');
|
|
808
812
|
}
|
|
809
813
|
await web3Provider.enable();
|
|
810
|
-
|
|
814
|
+
// ethers v6: Use BrowserProvider instead of Web3Provider
|
|
815
|
+
const ethersProvider = new ethers.BrowserProvider(web3Provider);
|
|
816
|
+
// ethers v6: getSigner() and getAddress() are now async
|
|
811
817
|
const userSigner = await ethersProvider.getSigner();
|
|
812
818
|
const userAddress = await userSigner.getAddress();
|
|
813
819
|
localStorage.setItem('walletAddress', userAddress);
|
|
@@ -1544,46 +1550,114 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1544
1550
|
}]);
|
|
1545
1551
|
return;
|
|
1546
1552
|
}
|
|
1547
|
-
|
|
1553
|
+
// Create streaming message for tool execution
|
|
1554
|
+
const streamingMessageId = `streaming-${Date.now()}`;
|
|
1555
|
+
const streamingMessage = {
|
|
1556
|
+
id: streamingMessageId,
|
|
1557
|
+
content: '',
|
|
1558
|
+
role: 'assistant',
|
|
1559
|
+
timestamp: new Date().toISOString(),
|
|
1560
|
+
isStreaming: true,
|
|
1561
|
+
streamingToolName: toolUse.name,
|
|
1562
|
+
streamingStatus: `Starting ${toolUse.name}...`,
|
|
1563
|
+
streamingProgress: 0,
|
|
1564
|
+
streamingSteps: [],
|
|
1565
|
+
metadata: {
|
|
1566
|
+
model: actualModelUsed,
|
|
1567
|
+
permissions: permissions,
|
|
1568
|
+
issuedBy: hitAddress || '',
|
|
1569
|
+
toolUse: toolUse
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
// Add streaming message to chat
|
|
1573
|
+
setMessages(prev => [...prev, streamingMessage]);
|
|
1574
|
+
// Execute tool with streaming updates
|
|
1575
|
+
const toolResult = await onToolUse(toolUse, (update) => {
|
|
1576
|
+
// Update streaming message with progress
|
|
1577
|
+
setMessages(prev => prev.map(msg => msg.id === streamingMessageId
|
|
1578
|
+
? {
|
|
1579
|
+
...msg,
|
|
1580
|
+
content: update.partialResult || msg.content,
|
|
1581
|
+
partialContent: update.partialContent, // Token-level streaming
|
|
1582
|
+
streamingProgress: update.progress,
|
|
1583
|
+
streamingStatus: update.status,
|
|
1584
|
+
streamingSteps: update.steps || msg.streamingSteps
|
|
1585
|
+
}
|
|
1586
|
+
: msg));
|
|
1587
|
+
});
|
|
1548
1588
|
toolMsg = toolResult?.content || `Tool ${toolUse.name} executed successfully`;
|
|
1589
|
+
// Merge AI original reply
|
|
1590
|
+
let replyText = '';
|
|
1591
|
+
if (response.reply) {
|
|
1592
|
+
replyText = Array.isArray(response.reply)
|
|
1593
|
+
? response.reply
|
|
1594
|
+
.map((item) => item.text)
|
|
1595
|
+
.join(' ') || ''
|
|
1596
|
+
: response.reply || '';
|
|
1597
|
+
}
|
|
1598
|
+
else if (response.fullResponse?.output?.message?.content) {
|
|
1599
|
+
replyText = response.fullResponse.output.message.content
|
|
1600
|
+
?.find((item) => item.text)?.text || '';
|
|
1601
|
+
}
|
|
1602
|
+
let finalContent = toolMsg;
|
|
1603
|
+
if (replyText && replyText.trim()) {
|
|
1604
|
+
finalContent += `\n\n${replyText}`;
|
|
1605
|
+
}
|
|
1606
|
+
// Mark streaming as complete with final content
|
|
1607
|
+
setMessages(prev => prev.map(msg => msg.id === streamingMessageId
|
|
1608
|
+
? {
|
|
1609
|
+
...msg,
|
|
1610
|
+
isStreaming: false,
|
|
1611
|
+
streamingProgress: 100,
|
|
1612
|
+
content: finalContent,
|
|
1613
|
+
metadata: {
|
|
1614
|
+
...msg.metadata,
|
|
1615
|
+
model: actualModelUsed,
|
|
1616
|
+
toolUse: toolUse
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
: msg));
|
|
1620
|
+
updateSuggestions(pseudoId, localStorage.getItem('walletAddress') || undefined);
|
|
1621
|
+
// Skip creating a new botResponse since we already updated the streaming message
|
|
1549
1622
|
}
|
|
1550
1623
|
else {
|
|
1551
1624
|
toolMsg = `Tool ${toolUse.name} executed successfully`;
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
.
|
|
1560
|
-
: response.reply || '';
|
|
1561
|
-
}
|
|
1562
|
-
else if (response.fullResponse?.output?.message?.content) {
|
|
1563
|
-
replyText = response.fullResponse.output.message.content
|
|
1564
|
-
?.find((item) => item.text)?.text || '';
|
|
1565
|
-
}
|
|
1566
|
-
let mergedContent = '';
|
|
1567
|
-
if (toolMsg) {
|
|
1568
|
-
mergedContent += toolMsg;
|
|
1569
|
-
}
|
|
1570
|
-
if (replyText && replyText.trim()) {
|
|
1571
|
-
mergedContent += `\n\n${replyText}`;
|
|
1572
|
-
}
|
|
1573
|
-
updateSuggestions(pseudoId, localStorage.getItem('walletAddress') || undefined);
|
|
1574
|
-
botResponse = {
|
|
1575
|
-
id: (Date.now() + 1).toString(),
|
|
1576
|
-
content: mergedContent,
|
|
1577
|
-
role: 'assistant',
|
|
1578
|
-
timestamp: new Date().toISOString(),
|
|
1579
|
-
metadata: {
|
|
1580
|
-
model: actualModelUsed,
|
|
1581
|
-
permissions: permissions,
|
|
1582
|
-
issuedBy: hitAddress || '',
|
|
1583
|
-
toolUse: toolUse
|
|
1625
|
+
// No onToolUse callback - create message without streaming
|
|
1626
|
+
let replyText = '';
|
|
1627
|
+
if (response.reply) {
|
|
1628
|
+
replyText = Array.isArray(response.reply)
|
|
1629
|
+
? response.reply
|
|
1630
|
+
.map((item) => item.text)
|
|
1631
|
+
.join(' ') || ''
|
|
1632
|
+
: response.reply || '';
|
|
1584
1633
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1634
|
+
else if (response.fullResponse?.output?.message?.content) {
|
|
1635
|
+
replyText = response.fullResponse.output.message.content
|
|
1636
|
+
?.find((item) => item.text)?.text || '';
|
|
1637
|
+
}
|
|
1638
|
+
let mergedContent = '';
|
|
1639
|
+
if (toolMsg) {
|
|
1640
|
+
mergedContent += toolMsg;
|
|
1641
|
+
}
|
|
1642
|
+
if (replyText && replyText.trim()) {
|
|
1643
|
+
mergedContent += `\n\n${replyText}`;
|
|
1644
|
+
}
|
|
1645
|
+
updateSuggestions(pseudoId, localStorage.getItem('walletAddress') || undefined);
|
|
1646
|
+
const newBotResponse = {
|
|
1647
|
+
id: (Date.now() + 1).toString(),
|
|
1648
|
+
content: mergedContent,
|
|
1649
|
+
role: 'assistant',
|
|
1650
|
+
timestamp: new Date().toISOString(),
|
|
1651
|
+
metadata: {
|
|
1652
|
+
model: actualModelUsed,
|
|
1653
|
+
permissions: permissions,
|
|
1654
|
+
issuedBy: hitAddress || '',
|
|
1655
|
+
toolUse: toolUse
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
setMessages(prev => [...prev, newBotResponse]);
|
|
1659
|
+
botResponse = newBotResponse;
|
|
1660
|
+
}
|
|
1587
1661
|
}
|
|
1588
1662
|
else if (response.reply) {
|
|
1589
1663
|
const replyText = Array.isArray(response.reply)
|
|
@@ -1592,7 +1666,7 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1592
1666
|
.join(' ') || 'Sorry, I cannot understand your question'
|
|
1593
1667
|
: response.reply || 'Sorry, I cannot understand your question';
|
|
1594
1668
|
updateSuggestions(pseudoId, localStorage.getItem('walletAddress') || undefined);
|
|
1595
|
-
|
|
1669
|
+
const newBotResponse = {
|
|
1596
1670
|
id: (Date.now() + 1).toString(),
|
|
1597
1671
|
content: replyText,
|
|
1598
1672
|
role: 'assistant',
|
|
@@ -1603,12 +1677,13 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1603
1677
|
issuedBy: hitAddress || ''
|
|
1604
1678
|
}
|
|
1605
1679
|
};
|
|
1606
|
-
setMessages(prev => [...prev,
|
|
1680
|
+
setMessages(prev => [...prev, newBotResponse]);
|
|
1681
|
+
botResponse = newBotResponse;
|
|
1607
1682
|
}
|
|
1608
1683
|
else {
|
|
1609
1684
|
const replyText = response.fullResponse?.output?.message?.content
|
|
1610
1685
|
?.find((item) => item.text)?.text || 'Sorry, I cannot understand your question';
|
|
1611
|
-
|
|
1686
|
+
const newBotResponse = {
|
|
1612
1687
|
id: (Date.now() + 1).toString(),
|
|
1613
1688
|
content: replyText,
|
|
1614
1689
|
role: 'assistant',
|
|
@@ -1619,7 +1694,8 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1619
1694
|
issuedBy: hitAddress || ''
|
|
1620
1695
|
}
|
|
1621
1696
|
};
|
|
1622
|
-
setMessages(prev => [...prev,
|
|
1697
|
+
setMessages(prev => [...prev, newBotResponse]);
|
|
1698
|
+
botResponse = newBotResponse;
|
|
1623
1699
|
}
|
|
1624
1700
|
// Execute redirect after all message processing is complete
|
|
1625
1701
|
if (redirectUrl) {
|
|
@@ -1692,14 +1768,22 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1692
1768
|
if (isMicEnabledRef.current) {
|
|
1693
1769
|
await sleep(1000);
|
|
1694
1770
|
clearRecording();
|
|
1695
|
-
// Reset auto-sent transcript ref when clearing recording
|
|
1696
|
-
lastAutoSentTranscriptRef.current = '';
|
|
1697
1771
|
}
|
|
1698
1772
|
}
|
|
1699
1773
|
if (!textInputRef.current)
|
|
1700
1774
|
return;
|
|
1701
1775
|
if (!textInputRef.current.value.trim() || isLoading)
|
|
1702
1776
|
return;
|
|
1777
|
+
// 如果此時有語音自動發送的計時器,優先取消,避免與手動發送同內容時重複送出
|
|
1778
|
+
if (autoSendTimerRef.current) {
|
|
1779
|
+
clearTimeout(autoSendTimerRef.current);
|
|
1780
|
+
autoSendTimerRef.current = null;
|
|
1781
|
+
}
|
|
1782
|
+
// 標記這次手動送出的內容,讓語音自動發送邏輯視為已送出,避免同一段文字再自動發送一次
|
|
1783
|
+
const manualContent = textInputRef.current.value.trim();
|
|
1784
|
+
if (manualContent) {
|
|
1785
|
+
lastAutoSentTranscriptRef.current = manualContent;
|
|
1786
|
+
}
|
|
1703
1787
|
// Stop current speech playback when user sends new message
|
|
1704
1788
|
stopTextToSpeechAndReset();
|
|
1705
1789
|
// Show loading message if AIT is still loading
|
|
@@ -1767,6 +1851,12 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1767
1851
|
setIsTtsProcessing(false);
|
|
1768
1852
|
pendingTtsRef.current = null;
|
|
1769
1853
|
}, [stopTextToSpeech]);
|
|
1854
|
+
// When TTS is disabled during playback, stop immediately
|
|
1855
|
+
React.useEffect(() => {
|
|
1856
|
+
if (!textToSpeechEnabled) {
|
|
1857
|
+
stopTextToSpeechAndReset();
|
|
1858
|
+
}
|
|
1859
|
+
}, [textToSpeechEnabled, stopTextToSpeechAndReset]);
|
|
1770
1860
|
// Play text-to-speech (simplified, no queue)
|
|
1771
1861
|
const playTextToSpeech = React.useCallback(async (text, messageIndex) => {
|
|
1772
1862
|
if (!textToSpeechEnabled || !text.trim())
|
|
@@ -1794,13 +1884,57 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1794
1884
|
console.error('TTS playback failed after retries:', lastError);
|
|
1795
1885
|
setIsTtsProcessing(false);
|
|
1796
1886
|
}, [textToSpeechEnabled, stopTextToSpeech, playTextToSpeechWithRetry]);
|
|
1887
|
+
const retryTtsWithGesture = React.useCallback(async () => {
|
|
1888
|
+
try {
|
|
1889
|
+
setRequiresGesture(false);
|
|
1890
|
+
// Try to resume audio context
|
|
1891
|
+
if (audioCtxRef.current) {
|
|
1892
|
+
try {
|
|
1893
|
+
await audioCtxRef.current.resume();
|
|
1894
|
+
}
|
|
1895
|
+
catch { }
|
|
1896
|
+
}
|
|
1897
|
+
const pending = pendingTtsRef.current;
|
|
1898
|
+
if (pending && textToSpeechEnabled) {
|
|
1899
|
+
setIsTtsProcessing(true);
|
|
1900
|
+
await playTextToSpeech(pending);
|
|
1901
|
+
pendingTtsRef.current = null;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
catch (err) {
|
|
1905
|
+
console.error('Retry TTS with gesture failed:', err);
|
|
1906
|
+
setIsTtsProcessing(false);
|
|
1907
|
+
}
|
|
1908
|
+
}, [textToSpeechEnabled, playTextToSpeech]);
|
|
1909
|
+
// When browser blocks autoplay (requires gesture), retry on next user interaction
|
|
1910
|
+
React.useEffect(() => {
|
|
1911
|
+
if (!requiresGesture || !textToSpeechEnabled || !pendingTtsRef.current)
|
|
1912
|
+
return;
|
|
1913
|
+
const handleUserGesture = () => {
|
|
1914
|
+
retryTtsWithGesture();
|
|
1915
|
+
};
|
|
1916
|
+
window.addEventListener('pointerdown', handleUserGesture, { once: true });
|
|
1917
|
+
return () => window.removeEventListener('pointerdown', handleUserGesture);
|
|
1918
|
+
}, [requiresGesture, textToSpeechEnabled, retryTtsWithGesture]);
|
|
1797
1919
|
// Handle preset message
|
|
1798
1920
|
const handlePresetMessage = (message) => {
|
|
1921
|
+
// If preset is configured as auto-send, avoid duplicate sends when user clicks repeatedly
|
|
1799
1922
|
if (message.autoSend) {
|
|
1923
|
+
const trimmedText = (message.text || '').trim();
|
|
1924
|
+
if (!trimmedText)
|
|
1925
|
+
return;
|
|
1926
|
+
// Prevent sending messages while AI Agent is processing
|
|
1927
|
+
if (isLoading) {
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
// If this exact preset text was just sent (by auto-send / manual / preset), skip to prevent duplicates
|
|
1931
|
+
if (lastAutoSentTranscriptRef.current === trimmedText) {
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1800
1934
|
// For preset messages, we need to add the user message first since sendMessage won't add it on retries
|
|
1801
1935
|
const userMessage = {
|
|
1802
1936
|
id: Date.now().toString(),
|
|
1803
|
-
content:
|
|
1937
|
+
content: trimmedText,
|
|
1804
1938
|
role: 'user',
|
|
1805
1939
|
timestamp: new Date().toISOString(),
|
|
1806
1940
|
metadata: {
|
|
@@ -1810,8 +1944,10 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1810
1944
|
}
|
|
1811
1945
|
};
|
|
1812
1946
|
setMessages(prev => [...prev, userMessage]);
|
|
1947
|
+
// Mark as last sent to guard against rapid re-clicks and other duplicate flows
|
|
1948
|
+
lastAutoSentTranscriptRef.current = trimmedText;
|
|
1813
1949
|
// Pass a flag to indicate this is a preset message so sendMessage won't add user message again
|
|
1814
|
-
sendMessage(
|
|
1950
|
+
sendMessage(trimmedText, 0, true);
|
|
1815
1951
|
}
|
|
1816
1952
|
else {
|
|
1817
1953
|
setInputValue(message.text);
|
|
@@ -1863,7 +1999,8 @@ isStopRecordingOnSend = false, }) => {
|
|
|
1863
1999
|
issuedBy: currentAddress,
|
|
1864
2000
|
};
|
|
1865
2001
|
const metadataStr = stringify(metadata);
|
|
1866
|
-
|
|
2002
|
+
// ethers v6: utils.keccak256 -> keccak256, utils.toUtf8Bytes -> toUtf8Bytes
|
|
2003
|
+
const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr));
|
|
1867
2004
|
const uploadResponse = await nxtlinqApi.metadata.createMetadata(metadata, nxtlinqAITServiceAccessToken || '');
|
|
1868
2005
|
if ('error' in uploadResponse) {
|
|
1869
2006
|
throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
|
|
@@ -2233,6 +2370,31 @@ isStopRecordingOnSend = false, }) => {
|
|
|
2233
2370
|
}
|
|
2234
2371
|
}
|
|
2235
2372
|
}, [hitAddress]);
|
|
2373
|
+
// Handle custom error message display
|
|
2374
|
+
React.useEffect(() => {
|
|
2375
|
+
const trimmedError = customError?.trim();
|
|
2376
|
+
// Only display error if it's a new value (different from last displayed error)
|
|
2377
|
+
if (trimmedError && trimmedError !== lastCustomErrorRef.current) {
|
|
2378
|
+
lastCustomErrorRef.current = trimmedError;
|
|
2379
|
+
const errorMessage = {
|
|
2380
|
+
id: `custom-error-${Date.now()}`,
|
|
2381
|
+
content: trimmedError,
|
|
2382
|
+
role: 'assistant',
|
|
2383
|
+
timestamp: new Date().toISOString(),
|
|
2384
|
+
metadata: {
|
|
2385
|
+
model: getCurrentModel().value,
|
|
2386
|
+
permissions: permissions,
|
|
2387
|
+
issuedBy: hitAddress || ''
|
|
2388
|
+
}
|
|
2389
|
+
};
|
|
2390
|
+
setMessages(prev => [...prev, errorMessage]);
|
|
2391
|
+
onMessage?.(errorMessage);
|
|
2392
|
+
}
|
|
2393
|
+
else if (!trimmedError) {
|
|
2394
|
+
// Reset ref when customError is cleared
|
|
2395
|
+
lastCustomErrorRef.current = undefined;
|
|
2396
|
+
}
|
|
2397
|
+
}, [customError, getCurrentModel, permissions, hitAddress, onMessage]);
|
|
2236
2398
|
React.useEffect(() => {
|
|
2237
2399
|
if (messages.length > 0) {
|
|
2238
2400
|
const lastMessage = messages[messages.length - 1];
|
|
@@ -2337,28 +2499,7 @@ isStopRecordingOnSend = false, }) => {
|
|
|
2337
2499
|
// Speech related functions
|
|
2338
2500
|
playTextToSpeech,
|
|
2339
2501
|
stopTextToSpeech,
|
|
2340
|
-
retryTtsWithGesture
|
|
2341
|
-
try {
|
|
2342
|
-
setRequiresGesture(false);
|
|
2343
|
-
// Try to resume audio context
|
|
2344
|
-
if (audioCtxRef.current) {
|
|
2345
|
-
try {
|
|
2346
|
-
await audioCtxRef.current.resume();
|
|
2347
|
-
}
|
|
2348
|
-
catch { }
|
|
2349
|
-
}
|
|
2350
|
-
const pending = pendingTtsRef.current;
|
|
2351
|
-
if (pending && textToSpeechEnabled) {
|
|
2352
|
-
setIsTtsProcessing(true);
|
|
2353
|
-
await playTextToSpeech(pending);
|
|
2354
|
-
pendingTtsRef.current = null;
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
catch (err) {
|
|
2358
|
-
console.error('Retry TTS with gesture failed:', err);
|
|
2359
|
-
setIsTtsProcessing(false);
|
|
2360
|
-
}
|
|
2361
|
-
},
|
|
2502
|
+
retryTtsWithGesture,
|
|
2362
2503
|
// Additional properties for PermissionForm
|
|
2363
2504
|
onSave: savePermissions,
|
|
2364
2505
|
onConnectWallet: () => connectWallet(false),
|
|
@@ -2390,6 +2531,7 @@ isStopRecordingOnSend = false, }) => {
|
|
|
2390
2531
|
customUsername,
|
|
2391
2532
|
idvBannerDismissSeconds,
|
|
2392
2533
|
isStopRecordingOnSend,
|
|
2534
|
+
customError,
|
|
2393
2535
|
},
|
|
2394
2536
|
nxtlinqApi
|
|
2395
2537
|
};
|
|
@@ -31,7 +31,13 @@ export interface AIModel {
|
|
|
31
31
|
export interface ChatBotProps {
|
|
32
32
|
onMessage?: (message: Message) => void;
|
|
33
33
|
onError?: (error: Error) => void;
|
|
34
|
-
onToolUse?: (toolUse: ToolUse
|
|
34
|
+
onToolUse?: (toolUse: ToolUse, onProgress?: (update: {
|
|
35
|
+
status?: string;
|
|
36
|
+
progress?: number;
|
|
37
|
+
partialResult?: string;
|
|
38
|
+
steps?: string[];
|
|
39
|
+
partialContent?: string;
|
|
40
|
+
}) => void) => Promise<Message | void>;
|
|
35
41
|
presetMessages?: PresetMessage[];
|
|
36
42
|
placeholder?: string;
|
|
37
43
|
className?: string;
|
|
@@ -55,6 +61,7 @@ export interface ChatBotProps {
|
|
|
55
61
|
idvBannerDismissSeconds?: number;
|
|
56
62
|
berifymeMode?: 'built-in' | 'external';
|
|
57
63
|
isStopRecordingOnSend?: boolean;
|
|
64
|
+
customError?: string;
|
|
58
65
|
}
|
|
59
66
|
export interface ChatBotContextType {
|
|
60
67
|
messages: Message[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBotTypes.d.ts","sourceRoot":"","sources":["../../../src/components/types/ChatBotTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"ChatBotTypes.d.ts","sourceRoot":"","sources":["../../../src/components/types/ChatBotTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBotUI.d.ts","sourceRoot":"","sources":["../../../src/components/ui/ChatBotUI.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatBotUI.d.ts","sourceRoot":"","sources":["../../../src/components/ui/ChatBotUI.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA8F/B,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAooB7B,CAAC"}
|