Skip to content

Commit 59c0287

Browse files
authored
Merge branch 'NVIDIA:main' into vikalluru/plot-renderer
2 parents c512e86 + 9816cd9 commit 59c0287

File tree

5 files changed

+151
-82
lines changed

5 files changed

+151
-82
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ package-lock.json
2121
.env.test.local
2222
.env.production.local
2323

24+
# environment files
25+
public/__ENV.js
26+
2427
npm-debug.log*
2528
yarn-debug.log*
2629
yarn-error.log*

components/Chat/Chat.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ export const Chat = () => {
477477
type: webSocketMessageTypes.userMessage,
478478
schema_type: sessionStorage.getItem('webSocketSchema') || webSocketSchema,
479479
id: message?.id,
480-
thread_id: selectedConversation.id,
480+
conversation_id: selectedConversation.id,
481481
content: {
482482
messages: chatMessages
483483
},
@@ -518,7 +518,7 @@ export const Chat = () => {
518518
method: 'POST',
519519
headers: {
520520
'Content-Type': 'application/json',
521-
'Thread-Id': selectedConversation?.id || '',
521+
'Conversation-Id': selectedConversation?.id || '',
522522
},
523523
signal: controllerRef.current.signal, // Use ref here
524524
body,

components/Chat/ChatInteractionMessage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ export const InteractionModal = ({ isOpen, interactionMessage, onClose, onSubmit
5858
</button>
5959
</div>
6060
), {
61-
position: 'top-right'
61+
position: 'top-right',
62+
duration: Infinity,
63+
id: 'notification-toast'
6264
})
6365
return null
6466
}

pages/aiq-auth.tsx

Lines changed: 142 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,34 @@ import React, { useState } from 'react';
22
import type { FormEvent } from 'react';
33

44
interface PromptModalProps {
5-
onSubmit: (value: string, domain: string) => void;
5+
onSubmit: (value: string, domain: string, setError: (error: string | null) => void) => void;
66
initialValue: string;
77
initialDomain: string;
8+
responseData: any;
9+
clientError: string | null;
10+
serverError: string | null;
811
}
912

10-
function PromptModal({ onSubmit, initialValue, initialDomain }: PromptModalProps) {
13+
function PromptModal({ onSubmit, initialValue, initialDomain, responseData, clientError, serverError }: PromptModalProps) {
1114
const [value, setValue] = useState(initialValue);
1215
const [domain, setDomain] = useState(initialDomain);
16+
const [error, setError] = useState<string | null>(null);
17+
const [isSubmitting, setIsSubmitting] = useState(false);
1318

1419
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
1520
e.preventDefault();
16-
onSubmit(value, domain);
21+
setError(null);
22+
setIsSubmitting(true);
23+
onSubmit(value, domain, (errorMessage) => {
24+
setError(errorMessage);
25+
setIsSubmitting(false);
26+
});
1727
};
1828

1929
return (
20-
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
21-
<div className="bg-white dark:bg-[#343541] rounded-lg p-6 w-full max-w-md">
22-
<h2 className="text-xl font-semibold mb-4 text-black dark:text-white">Enter Authentication Details</h2>
30+
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4">
31+
<div className="bg-white dark:bg-[#343541] rounded-lg p-8 w-full max-w-2xl max-h-[90vh] overflow-y-auto">
32+
<h2 className="text-2xl font-semibold mb-6 text-black dark:text-white text-center">Enter Authentication Details</h2>
2333
<form onSubmit={handleSubmit} className="space-y-4">
2434
<div>
2535
<label htmlFor="domain" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
@@ -44,18 +54,52 @@ function PromptModal({ onSubmit, initialValue, initialDomain }: PromptModalProps
4454
type="text"
4555
value={value}
4656
onChange={(e) => setValue(e.target.value)}
47-
className="w-full p-2 border border-gray-300 dark:border-gray-600 rounded mb-4 bg-white dark:bg-[#40414F] text-black dark:text-white"
57+
className="w-full p-2 border border-gray-300 dark:border-gray-600 rounded mb-2 bg-white dark:bg-[#40414F] text-black dark:text-white"
4858
placeholder="Enter consent prompt key..."
4959
autoFocus
5060
autoComplete="off"
5161
/>
62+
{error && (
63+
<div className="mb-4 p-2 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded text-sm">
64+
<p className="text-red-700 dark:text-red-300">{error}</p>
65+
</div>
66+
)}
5267
</div>
68+
69+
{/* Status Messages */}
70+
{clientError && (
71+
<div className="mb-4 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
72+
<p className="font-semibold text-red-800 dark:text-red-400 mb-2">Client Error:</p>
73+
<p className="text-red-700 dark:text-red-300">{clientError}</p>
74+
</div>
75+
)}
76+
77+
{serverError && (
78+
<div className="mb-4 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
79+
<p className="font-semibold text-red-800 dark:text-red-400 mb-2">Server Error:</p>
80+
<p className="text-red-700 dark:text-red-300">{serverError}</p>
81+
</div>
82+
)}
83+
84+
85+
86+
{responseData && (serverError || clientError) && (
87+
<div className="mb-4 p-4 bg-gray-800 text-gray-100 rounded-lg font-mono text-sm overflow-x-auto">
88+
<p className="font-semibold mb-2">Response:</p>
89+
<pre className="whitespace-pre-wrap">{JSON.stringify(responseData, null, 2)}</pre>
90+
</div>
91+
)}
92+
5393
<div className="flex justify-end gap-2">
5494
<button
5595
type="submit"
56-
className="px-4 py-2 bg-[#76b900] text-white rounded hover:bg-[#5a9100] focus:outline-none transition-colors duration-200"
96+
disabled={isSubmitting}
97+
className="px-4 py-2 bg-[#76b900] text-white rounded hover:bg-[#5a9100] focus:outline-none transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
5798
>
58-
Send Request
99+
{isSubmitting && (
100+
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
101+
)}
102+
{isSubmitting ? 'Processing...' : 'Send Request'}
59103
</button>
60104
</div>
61105
</form>
@@ -70,13 +114,37 @@ export default function AIQAuthPage() {
70114
const [error, setError] = useState<string | null>(null);
71115
const [responseError, setResponseError] = useState<string | null>(null);
72116
const [responseData, setResponseData] = useState<any>(null);
73-
const [modalKey, setModalKey] = useState(0);
74117

75-
const handleSubmit = async (key: string, domain: string) => {
118+
const [authSuccess, setAuthSuccess] = useState(false);
119+
const [currentPopup, setCurrentPopup] = useState<Window | null>(null);
120+
const [authProviderName, setAuthProviderName] = useState<string | null>(null);
121+
122+
React.useEffect(() => {
123+
const handleMessage = (event: MessageEvent) => {
124+
if (currentPopup && !currentPopup.closed) {
125+
try {
126+
currentPopup.document.title = `Authentication was successfully granted for authentication provider ${authProviderName}`;
127+
} catch (e) {
128+
console.log('Could not update popup title due to cross-origin restrictions');
129+
}
130+
}
131+
132+
setShowPrompt(false);
133+
setAuthSuccess(true);
134+
setIsProcessing(false);
135+
};
136+
137+
window.addEventListener('message', handleMessage);
138+
return () => window.removeEventListener('message', handleMessage);
139+
}, [currentPopup, authProviderName]);
140+
141+
const handleSubmit = async (key: string, domain: string, setModalError: (error: string | null) => void) => {
76142
setIsProcessing(true);
77143
setError(null);
78144
setResponseError(null);
79145
setResponseData(null);
146+
setAuthSuccess(false);
147+
setAuthProviderName(null);
80148

81149
try {
82150
const response = await fetch(`${domain}/auth/prompt-uri`, {
@@ -91,101 +159,97 @@ export default function AIQAuthPage() {
91159

92160
if (contentType && contentType.includes('application/json')) {
93161
const data = await response.json();
94-
setResponseData(data);
95162

96163
if (!response.ok) {
97-
const errorMessage = data.message || data.error || `Error: ${response.status} - ${response.statusText}`;
98-
setResponseError(errorMessage);
164+
setResponseData(data);
165+
const errorMessage = data.detail || data.message || data.error || `Error: ${response.status} - ${response.statusText}`;
166+
setModalError(errorMessage);
167+
setIsProcessing(false);
99168
return;
100169
}
101170

171+
setResponseData(data);
172+
102173
if (data.redirect_url) {
103-
window.location.href = data.redirect_url;
174+
setAuthProviderName(data.auth_provider_name);
175+
const popup = window.open(
176+
data.redirect_url,
177+
'auth-popup',
178+
'width=600,height=700,scrollbars=yes,resizable=yes'
179+
);
180+
setCurrentPopup(popup);
181+
setModalError(null);
104182
return;
105183
}
106184
}
107185

108186
if (!response.ok) {
109187
const errorMessage = `Error: ${response.status} - ${response.statusText}`;
110-
setResponseError(errorMessage);
188+
setModalError(errorMessage);
189+
setIsProcessing(false);
111190
return;
112191
}
113192

114-
setShowPrompt(false);
115-
116193
} catch (error) {
117194
const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
118-
setError(errorMessage);
195+
setModalError(errorMessage);
119196
} finally {
120197
setIsProcessing(false);
121198
}
122199
};
123200

124201
return (
125202
<div className="min-h-screen bg-gray-50 dark:bg-[#343541]">
126-
{showPrompt && !isProcessing && (
127-
<PromptModal
128-
key={modalKey}
129-
onSubmit={handleSubmit}
130-
initialValue=""
131-
initialDomain="http://localhost:8000"
132-
/>
133-
)}
203+
{/* Green Banner */}
204+
<div className="bg-[#76b900] text-white py-4 px-6 text-center">
205+
<h1 className="text-2xl font-bold">NeMo-Agent-Toolkit</h1>
206+
</div>
134207

135-
{isProcessing && (
136-
<div className="fixed inset-0 bg-white dark:bg-[#343541] bg-opacity-75 dark:bg-opacity-75 flex items-center justify-center">
137-
<div className="text-center">
138-
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#76b900] mx-auto mb-4"></div>
139-
<p className="text-gray-600 dark:text-gray-300">Processing Request...</p>
140-
</div>
141-
</div>
142-
)}
143-
144-
<div className="container mx-auto p-6">
145-
<h1 className="text-2xl font-bold mb-4 text-black dark:text-white">Agent IQ Authentication</h1>
146-
147-
{error && (
148-
<div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 mb-4">
149-
<p className="font-semibold text-red-800 dark:text-red-400">Client Error:</p>
150-
<p className="text-red-700 dark:text-red-300">{error}</p>
151-
</div>
152-
)}
153-
154-
{responseError && (
155-
<div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 mb-4">
156-
<p className="font-semibold text-red-800 dark:text-red-400">Server Error:</p>
157-
<p className="text-red-700 dark:text-red-300">{responseError}</p>
158-
</div>
159-
)}
160-
161-
{!showPrompt && !isProcessing && !error && !responseError && (
162-
<div className="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-4 mb-4">
163-
<p className="text-green-700 dark:text-green-300">You are being redirected to your provider's consent screen to authorize access.</p>
164-
</div>
208+
<div className="flex items-center justify-center min-h-[calc(100vh-80px)]">
209+
{showPrompt && !authSuccess && (
210+
<PromptModal
211+
onSubmit={handleSubmit}
212+
initialValue=""
213+
initialDomain="http://localhost:8000"
214+
responseData={responseData}
215+
clientError={error}
216+
serverError={responseError}
217+
/>
165218
)}
219+
</div>
166220

167-
{responseData && (responseError || error) && (
168-
<div className="bg-gray-800 text-gray-100 rounded-lg p-4 mb-4 font-mono text-sm overflow-x-auto">
169-
<p className="font-semibold mb-2">Response:</p>
170-
<pre className="whitespace-pre-wrap">{JSON.stringify(responseData, null, 2)}</pre>
221+
{authSuccess && (
222+
<div className="fixed inset-0 z-[9999] bg-gray-50 dark:bg-[#343541] flex items-center justify-center">
223+
<div className="w-full max-w-md mx-auto p-6">
224+
<div className="bg-white dark:bg-[#343541] rounded-lg shadow-lg p-8 text-center border border-gray-200 dark:border-gray-600">
225+
<div className="mb-6">
226+
<div className="w-16 h-16 bg-green-100 dark:bg-green-900/20 rounded-full flex items-center justify-center mx-auto mb-4">
227+
<svg className="w-8 h-8 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
228+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
229+
</svg>
230+
</div>
231+
<h1 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
232+
Authentication was successfully granted for authentication provider {authProviderName}
233+
</h1>
234+
</div>
235+
236+
<button
237+
onClick={() => {
238+
setShowPrompt(true);
239+
setAuthSuccess(false);
240+
setError(null);
241+
setResponseError(null);
242+
setResponseData(null);
243+
setAuthProviderName(null);
244+
}}
245+
className="w-full mt-3 px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 transition-colors duration-200"
246+
>
247+
Authenticate Again
248+
</button>
249+
</div>
171250
</div>
172-
)}
173-
174-
{!showPrompt && !isProcessing && (
175-
<button
176-
onClick={() => {
177-
setShowPrompt(true);
178-
setError(null);
179-
setResponseError(null);
180-
setResponseData(null);
181-
setModalKey(prev => prev + 1);
182-
}}
183-
className="px-4 py-2 bg-[#76b900] text-white rounded hover:bg-[#5a9100] focus:outline-none transition-colors duration-200"
184-
>
185-
Open Authentication Prompt
186-
</button>
187-
)}
188-
</div>
251+
</div>
252+
)}
189253
</div>
190254
);
191255
}

pages/api/chat.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const handler = async (req: Request): Promise<Response> => {
5656
method: 'POST',
5757
headers: {
5858
'Content-Type': 'application/json',
59-
'Thread-Id': req.headers.get('Thread-Id') || '',
59+
'Conversation-Id': req.headers.get('Conversation-Id') || '',
6060
},
6161
body: JSON.stringify(payload),
6262
});

0 commit comments

Comments
 (0)