/**
* Pria SDK Test Harness Application
* Enhanced version with modern JavaScript patterns and professional UI
*/
class PriaTestHarness {
constructor() {
this.pria = null;
this.waitForPriaTimer = null;
this.uiDisplayed = false;
this.isConnected = false;
// Configuration
this.config = {
displayOptions: {
buttonPositionRight: 'calc(50% - 40px)',
buttonPositionBottom: '80px'
},
instanceConfig: {
publicIdguest: '41407647-248c-4f0e-a317-71fc151ba8fb',
publicId: 'f831501f-b645-481a-9cbb-331509aaf8c1',
pictureUrl: 'https://ca.slack-edge.com/T08Q47N2NUT-U08PZ8CUVDK-d32d2c5679ad-512'
},
userConfig: {
email: 'alex@praxis-ai.com',
profilename: 'Alex Lebegue',
usertype: 1,
userid: 110,
roleid: 123,
rolename: "Course ABC",
partnerid: 1,
partnername: "ABC Global Inc."
},
conversation: {
id: 777,
name: "My Conversation"
}
};
this.init();
}
/**
* Initialize the application
*/
async init() {
try {
await this.loadPriaSDK();
this.bindEventListeners();
this.showToast('Application initialized successfully', 'success');
} catch (error) {
console.error('Failed to initialize application:', error);
this.showToast('Failed to initialize application', 'error');
}
}
/**
* Load the Pria SDK
*/
loadPriaSDK() {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'pria-sdk-web.js';
script.async = true;
script.onload = () => {
console.log('Web SDK Script loaded');
const url = 'https://pria.praxislxp.com';
PriaIntegration.loadSdk(
url,
this.config.displayOptions,
this.config.instanceConfig,
this.config.userConfig
);
this.waitForPriaTimer = setInterval(() => this.waitForPria(), 2000);
resolve();
};
script.onerror = (error) => {
console.error('Failed to load Web SDK:', error);
reject(new Error('Web SDK loading failed'));
};
document.body.appendChild(script);
});
}
/**
* Wait for Pria to be available and set up subscriptions
*/
waitForPria() {
if (!window.pria) {
console.log("Waiting for Pria to load...");
return;
}
// console.log('Pria loaded:', JSON.stringify(window.pria.priaObj, null, 2));
clearInterval(this.waitForPriaTimer);
this.pria = window.pria;
this.isConnected = true;
this.updateConnectionStatus(true);
this.pria.subscribe(this.handlePriaResponse.bind(this));
this.showToast('Connected to Pria SDK', 'success');
}
/**
* Handle responses from Pria
*/
handlePriaResponse(response) {
console.log("Response from Pria:", JSON.stringify(response, null, 2));
this.displayResponse(response);
this.hideLoading();
}
/**
* Bind event listeners to UI elements
*/
bindEventListeners() {
// Message sending
document.getElementById('send-message-btn').addEventListener('click', () => {
this.sendMessage();
});
// Quick actions
document.getElementById('start-conversation-btn').addEventListener('click', () => {
this.startConversation();
});
document.getElementById('stop-conversation-btn').addEventListener('click', () => {
this.stopConversation();
});
document.getElementById('get-assistants-btn').addEventListener('click', () => {
this.getAssistants();
});
document.getElementById('get-conversations-btn').addEventListener('click', () => {
this.getConversations();
});
document.getElementById('get-favorites-btn').addEventListener('click', () => {
this.getFavorites();
});
// Toggle Pria visibility
document.getElementById('toggle-pria-btn').addEventListener('click', () => {
this.togglePriaVisibility();
});
// Clear response
document.getElementById('clear-response-btn').addEventListener('click', () => {
this.clearResponse();
});
// Enter key support for message input
document.getElementById('message-input').addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'Enter') {
this.sendMessage();
}
});
}
/**
* Send a message to Pria
*/
sendMessage() {
if (!this.ensurePriaConnection()) return;
const message = document.getElementById('message-input').value.trim();
const assistantId = document.getElementById('assistant-id-input').value.trim();
if (!message) {
this.showToast('Please enter a message', 'warning');
return;
}
if (!assistantId) {
this.showToast('Please enter an assistant ID', 'warning');
return;
}
this.showLoading();
this.clearResponse();
const request = {
command: 'message.post',
inputs: [message],
assistantId: assistantId,
selectedCourse: {
course_id: this.config.conversation.id,
course_name: this.config.conversation.name
}
};
this.pria.send(request);
this.showPria();
this.showToast('Message sent', 'info');
}
/**
* Start a conversation
*/
startConversation() {
if (!this.ensurePriaConnection()) return;
this.showLoading();
this.clearResponse();
const request = {
command: 'convo.start',
assistantId: '674e9fd3d7e18aa82eb49fda',
selectedCourse: {
course_id: 22345,
course_name: 'Conversational Assist'
}
};
this.pria.send(request);
this.showPria();
this.showToast('Starting conversation', 'info');
}
/**
* Stop a conversation
*/
stopConversation() {
if (!this.ensurePriaConnection()) return;
const request = {
command: 'convo.stop'
};
this.pria.send(request);
this.showToast('Conversation stopped', 'info');
}
/**
* Get list of assistants
*/
getAssistants() {
if (!this.ensurePriaConnection()) return;
this.showLoading();
this.clearResponse();
const request = {
command: 'assistants.list'
};
this.pria.send(request);
this.showToast('Fetching assistants', 'info');
}
/**
* Get list of conversations
*/
getConversations() {
if (!this.ensurePriaConnection()) return;
this.showLoading();
this.clearResponse();
const request = {
command: 'conversations.list'
};
this.pria.send(request);
this.showToast('Fetching conversations', 'info');
}
/**
* Get list of favorites
*/
getFavorites() {
if (!this.ensurePriaConnection()) return;
this.showLoading();
this.clearResponse();
const request = {
command: 'favorites.list'
};
this.pria.send(request);
this.showToast('Fetching favorites', 'info');
}
/**
* Toggle Pria visibility
*/
togglePriaVisibility() {
if (!this.ensurePriaConnection()) return;
this.uiDisplayed = !this.uiDisplayed;
this.pria.display(this.uiDisplayed);
const btn = document.getElementById('toggle-pria-btn');
const icon = btn.querySelector('i');
const text = btn.querySelector('span');
if (this.uiDisplayed) {
icon.className = 'fas fa-eye-slash';
text.textContent = 'Hide Pria';
this.showToast('Pria UI shown', 'info');
} else {
icon.className = 'fas fa-eye';
text.textContent = 'Show Pria';
this.showToast('Pria UI hidden', 'info');
}
}
/**
* Show Pria interface
*/
showPria() {
if (this.pria && !this.uiDisplayed) {
this.pria.display(true)
this.uiDisplayed = true;
}
}
/**
* Display response in the viewer
*/
displayResponse(data) {
const viewer = document.getElementById('response-viewer');
viewer.value = data ? JSON.stringify(data, null, 2) : '';
}
/**
* Clear the response viewer
*/
clearResponse() {
document.getElementById('response-viewer').value = '';
}
/**
* Show loading indicator
*/
showLoading() {
document.getElementById('loading-indicator').classList.remove('hidden');
}
/**
* Hide loading indicator
*/
hideLoading() {
document.getElementById('loading-indicator').classList.add('hidden');
}
/**
* Update connection status indicator
*/
updateConnectionStatus(connected) {
const statusElement = document.getElementById('connection-status');
const dot = statusElement.querySelector('div');
const text = statusElement.querySelector('span');
if (connected) {
dot.className = 'w-3 h-3 bg-green-500 rounded-full';
text.textContent = 'Connected';
text.className = 'text-sm text-green-600';
} else {
dot.className = 'w-3 h-3 bg-red-500 rounded-full animate-pulse';
text.textContent = 'Disconnected';
text.className = 'text-sm text-red-600';
}
}
/**
* Ensure Pria connection exists
*/
ensurePriaConnection() {
if (!this.pria || !this.isConnected) {
this.showToast('Pria SDK not connected', 'error');
return false;
}
return true;
}
/**
* Show toast notification
*/
showToast(message, type = 'info') {
const container = document.getElementById('toast-container');
const toast = document.createElement('div');
const colors = {
success: 'bg-green-500',
error: 'bg-red-500',
warning: 'bg-yellow-500',
info: 'bg-blue-500'
};
const icons = {
success: 'fas fa-check-circle',
error: 'fas fa-exclamation-circle',
warning: 'fas fa-exclamation-triangle',
info: 'fas fa-info-circle'
};
toast.className = `${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg flex items-center space-x-3 transform transition-all duration-300 translate-x-full`;
toast.innerHTML = `
<i class="${icons[type]}"></i>
<span>${message}</span>
`;
container.appendChild(toast);
// Animate in
setTimeout(() => {
toast.classList.remove('translate-x-full');
}, 100);
// Auto remove
setTimeout(() => {
toast.classList.add('translate-x-full');
setTimeout(() => {
if (container.contains(toast)) {
container.removeChild(toast);
}
}, 300);
}, 3000);
}
}
// Initialize the application when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
new PriaTestHarness();
});