-
-
+ <>
+
+
+
+
+
+ {[
+ 'did:nv:6004fbe1fc4508f45fae98009854199811e5c803e035c04b21d48ac8625b3035',
+ 'did:nv:f4f4d59075832a43d29cc5396f6dc95e575a9673425543bd18e6fd01c3fd19e0',
+ isHtmlCodeEnabled && 'html',
+ ]
+ .filter(Boolean)
+ .map((option, index) =>
+ option === 'html' ? (
+
+ ) : (
+
+ )
+ )}
-
- )}
-
-
-
-
-
-
- {thread
- .filter((item) => item.message)
- .map(({ author, message, queryResponse }, index) => (
- -
-
-
- {author === 'user' ? 'You' : 'Agent'}
-
-
- {message}
- {queryResponse?.creditsUsed > 0 && (
-
-
-
- Credits used: {queryResponse.creditsUsed}
-
-
- )}
-
-
-
- ))}
-
-
+
-
{
- messageRef.current?.focus();
- }}
- >
-
-
+ {showHtmlCodeModal && (
+
{
+ setShowHtmlCodeModal(false);
+ }}
+ >
+
+
+
+
+
+ )}
+ >
);
};
diff --git a/agent-widget/src/react/agent/agent.tsx b/agent-widget/src/react/agent/agent.tsx
deleted file mode 100644
index 9aa52ce..0000000
--- a/agent-widget/src/react/agent/agent.tsx
+++ /dev/null
@@ -1,310 +0,0 @@
-import React, { useEffect, useMemo, useRef, useState } from 'react';
-import './agent.scss';
-import { Modal } from '../modal/modal';
-import { useSearchParams } from '../../../node_modules/react-router-dom/dist/index';
-
-const getHtmlCode = (
- did: string
-) => `
-`;
-
-const InjectScript = React.memo(({ script }: { script: string }) => {
- const divRef = useRef
(null);
-
- useEffect(() => {
- if (divRef.current === null) {
- return;
- }
-
- const doc = document.createRange().createContextualFragment(script);
- divRef.current.innerHTML = '';
- divRef.current.appendChild(doc);
- }, [script]);
-
- return ;
-});
-
-export const Agent = () => {
- const [searchParams, setSearchParams] = useSearchParams();
-
- const [did, setDid] = useState(searchParams.get('did'));
-
- const [thread, setThread] = useState([]);
-
- const [query, setQuery] = useState('');
-
- const [isHtmlCodeEnabled] = useState(true);
-
- const [agentData, setAgentData] = useState<
- InitAgentEvent['data']['data'] | null
- >(null);
-
- const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
-
- const [mustTopUp, setMustTopUp] = useState(false);
-
- const [showHtmlCodeModal, setShowHtmlCodeModal] = useState(false);
-
- const [textareaWidgetHtmlCode, setTextareaWidgetHtmlCode] = useState('');
-
- const [widgetHtmlCode, setWidgetHtmlCode] = useState('');
-
- const messageRef = useRef(null);
-
- const threadEndRef = useRef(null);
-
- const loadWidget = () => {
- setAgentData(null);
-
- setMustTopUp(false);
-
- setShowHtmlCodeModal(false);
-
- setThread([]);
-
- if (isHtmlCodeEnabled) {
- setSearchParams({ html: encodeURIComponent(textareaWidgetHtmlCode) });
- } else if (did) {
- setSearchParams({ did });
- }
- };
-
- const resetQuery = () => {
- setQuery('');
- messageRef.current?.focus();
- };
-
- const handleAgentEvents = (
- e:
- | InitAgentEvent
- | QueryResponseEvent
- | AssistantResponseEvent
- | StatusEvent
- ) => {
- switch (e.data.type) {
- case 'nvm-agent:init-agent': {
- setAgentData(e.data.data as InitAgentEvent['data']['data']);
- break;
- }
- case 'nvm-agent:query-response': {
- setThread((prev) => {
- const lastMessage = prev.at(-1);
-
- if (lastMessage?.messageType === 'query') {
- prev.pop();
- }
-
- return [...prev, e.data.data as AssistantThread];
- });
- break;
- }
- case 'nvm-agent:assistant-response': {
- setThread((prev) => [...prev, e.data.data as AssistantThread]);
- setIsWaitingForResponse(false);
- break;
- }
- case 'nvm-agent:status': {
- if (e.data.data === 'top-up') {
- setMustTopUp(true);
- }
- break;
- }
- }
- };
-
- const submitQuery = () => {
- setIsWaitingForResponse(true);
-
- window.postMessage(
- {
- type: 'nvm-agent:query',
- data: {
- query,
- threadId: thread.at(-1)?.queryResponse?.threadId,
- },
- },
- '*'
- );
-
- resetQuery();
- };
-
- const isQueryingDisabled = useMemo(
- () => !agentData || isWaitingForResponse || mustTopUp,
- [agentData, isWaitingForResponse, mustTopUp]
- );
-
- const textAreaPlaceholder = useMemo(() => {
- if (!agentData) {
- return 'Login or purchase the assistant';
- }
-
- if (!mustTopUp && isWaitingForResponse) {
- return 'Waiting for the response...';
- }
-
- if (mustTopUp) {
- return 'Top up to continue';
- }
-
- return 'Enter your message';
- }, [agentData, isWaitingForResponse, mustTopUp]);
-
- useEffect(() => {
- threadEndRef.current?.scrollIntoView({
- behavior: 'smooth',
- block: 'nearest',
- });
- }, [thread]);
-
- useEffect(() => {
- const did = searchParams.get('did');
- const encodedHtml = searchParams.get('html');
-
- if (encodedHtml) {
- const decodedHtml = decodeURIComponent(encodedHtml);
-
- setWidgetHtmlCode(decodedHtml);
- setTextareaWidgetHtmlCode(decodedHtml);
- return;
- }
-
- if (did) {
- const decodedDid = decodeURIComponent(did);
- const htmlCode = getHtmlCode(decodedDid);
-
- setWidgetHtmlCode(htmlCode);
- setTextareaWidgetHtmlCode(htmlCode);
- }
- }, [searchParams]);
-
- useEffect(() => {
- window.addEventListener('message', handleAgentEvents, false);
- }, []);
-
- return (
- <>
-
-
-
-
-
- {[
- 'did:nv:6004fbe1fc4508f45fae98009854199811e5c803e035c04b21d48ac8625b3035',
- 'did:nv:f4f4d59075832a43d29cc5396f6dc95e575a9673425543bd18e6fd01c3fd19e0',
- isHtmlCodeEnabled && 'html',
- ]
- .filter(Boolean)
- .map((option, index) =>
- option === 'html' ? (
-
- ) : (
-
- )
- )}
-
-
-
-
-
-
- {thread
- .filter((item) => item.message)
- .map(({ author, message, queryResponse }, index) => (
- -
-
-
- {author === 'user' ? 'You' : 'Agent'}
-
-
- {message}
- {queryResponse?.creditsUsed > 0 && (
-
-
-
- Credits used: {queryResponse.creditsUsed}
-
-
- )}
-
-
-
- ))}
- {mustTopUp && Top up to continue
}
-
-
-
-
{
- messageRef.current?.focus();
- }}
- >
-
-
-
- {showHtmlCodeModal && (
- {
- setShowHtmlCodeModal(false);
- }}
- >
-
-
-
-
-
- )}
- >
- );
-};