champ-chatbot / static /services /state-manager.js
qyle's picture
gemini ecologits monkey patch
307e4f5 verified
// services/state-manager.js - Central state management
import { Utils } from '../utils.js';
export const StateManager = {
// Session data
sessionId: Utils.generateSessionId(),
// User profile
profile: {
ageGroup: '',
gender: '',
roles: [],
participantId: ''
},
// Consent
consentGranted: false,
// Language
currentLang: (() => {
const browserLang = navigator.language.split('-')[0];
const defaultLang = ['en', 'fr'].includes(browserLang) ? browserLang : 'en';
return localStorage.getItem('preferredLang') || defaultLang;
})(),
// Chat data - stores messages and conversation IDs for each model
modelChats: {
"champ": {
messages: [],
conversation_id: Utils.generateConversationId()
},
// "qwen": {
// messages: [],
// conversation_id: Utils.generateConversationId()
// },
"openai": {
messages: [],
conversation_id: Utils.generateConversationId()
},
"google-conservative": {
messages: [],
conversation_id: Utils.generateConversationId()
},
"google-creative": {
messages: [],
conversation_id: Utils.generateConversationId()
}
},
// File upload state
sessionFiles: [],
// Font size
fontSize: 1, // 1rem = browser default
/**
* Update user profile
* @param {Object} profileData - Profile data object
*/
updateProfile(profileData) {
this.profile = { ...this.profile, ...profileData };
},
/**
* Set consent status
* @param {boolean} granted - Whether consent is granted
*/
setConsent(granted) {
this.consentGranted = granted;
},
/**
* Set current language and save to localStorage
* @param {string} lang - Language code ('en' or 'fr')
*/
setLanguage(lang) {
this.currentLang = lang;
localStorage.setItem('preferredLang', lang);
},
/**
* Add a message to the current model's chat
* @param {string} modelType - The model type
* @param {Object} message - Message object with role, content, and kgCO2eq
*/
addMessage(modelType, message) {
this.modelChats[modelType].messages.push(message);
},
/**
* Get messages for a specific model
* @param {string} modelType - The model type
* @returns {Array} Array of messages
*/
getMessages(modelType) {
return this.modelChats[modelType].messages;
},
/**
* Get conversation ID for a specific model
* @param {string} modelType - The model type
* @returns {string} Conversation ID
*/
getConversationId(modelType) {
return this.modelChats[modelType].conversation_id;
},
/**
* Clear conversation for a specific model
* @param {string} modelType - The model type
*/
clearConversation(modelType) {
this.modelChats[modelType].messages = [];
this.modelChats[modelType].conversation_id = Utils.generateConversationId();
},
/**
* Add file to session
* @param {File} file - File object
*/
addFile(file) {
this.sessionFiles.push(file);
},
/**
* Remove file from session
* @param {File} file - File object to remove
*/
removeFile(file) {
this.sessionFiles = this.sessionFiles.filter(f => f !== file);
},
/**
* Get all session files
* @returns {Array} Array of files
*/
getFiles() {
return this.sessionFiles;
},
/**
* Set font size
* @param {number} size - Font size in rem
*/
setFontSize(size) {
this.fontSize = size;
},
/**
* Get total carbon emissions for a specific model type
* @param {string} modelType - The model type (e.g., 'champ', 'qwen', 'openai')
* @returns {number} Total kgCO2eq for this model
*/
getTotalEmissions(modelType) {
const chat = this.modelChats[modelType];
if (!chat || !chat.messages) return 0;
return chat.messages.reduce((total, message) => {
return total + (message.gwpKgcoeq || 0);
}, 0);
},
/**
* Get total carbon emissions across all models
* @returns {number} Total kgCO2eq across all models
*/
getAllEmissions() {
return Object.keys(this.modelChats).reduce((total, modelType) => {
return total + this.getTotalEmissions(modelType);
}, 0);
},
/**
* Get emissions breakdown by model
* @returns {Object} Object with model types as keys and emissions as values
*/
getEmissionsBreakdown() {
const breakdown = {};
Object.keys(this.modelChats).forEach(modelType => {
breakdown[modelType] = this.getTotalEmissions(modelType);
});
return breakdown;
},
};