/**
* Service class to handle communication with the TinAI backend API.
*/
class Api {
static MODELS = {};
#endpoint = 'api.php'
constructor() {
this.load_models();
}
async load_models() {
try {
const response = await fetch('models.json');
Api.MODELS = await response.json();
console.log('Models:', Api.MODELS);
} catch (error) {
console.error('Failed to load models.json:', error);
}
}
/**
* Formats the query and context into a data object for the API request.
* @param {string} query - The user's input string.
* @param {Array} context - The conversational history/context.
* @param {string} verbosity - The level of verbosity requested (minimal, standard, verbose).
* @param {string} model_key - The key for the selected model.
* @param {object} meta_context - meta context
* @param {boolean} debug - Whether to enable debug mode in the response.
* @returns {Object} The formatted data object.
*/
format_data(query = '', context = [], verbosity = 'standard', model_key = 'basic', meta_context = {}, debug = false){
return {
"context":context,
"debug":debug,
"query":query,
"verbosity":verbosity,
"model_key": model_key,
"meta_context": meta_context,
};
}
/**
* Sends a POST request to the API endpoint.
* @param {Object} data - The payload to send.
* @param {Function} on_success - Callback executed on successful response.
* @param {Function} on_failure - Callback executed on request or parsing error.
* @param {string} function_name - The API function to call (appended as GET param).
* @returns {Promise<void>}
*/
async post(data, on_success, on_failure, function_name = 'chat'){
if(data && data['model_key'] && data['model_key'].startsWith('ds')){
function_name = 'chatds';
}
try {
const url = `${this.#endpoint}?function=${function_name}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (response.status === 401) {
console.warn('Session expired. Redirecting to login page.');
window.location.reload();
return;
}
const text = await response.clone().text();
if (text.trim().startsWith('<')) {
console.warn('HTML Response detected:', text);
}
const response_object = await response.json();
console.log('Response:', response_object);
on_success(response_object);
} catch (error) {
console.error('Error:', error);
on_failure(error);
}
}
/**
* Retrieves the current user's ID from the backend.
* @returns {Promise<string|null>} The user ID or null on failure.
*/
async get_user_id() {
return new Promise((resolve, reject) => {
this.post({}, (response) => {
if (response && response.user_id) {
resolve(response.user_id);
} else {
console.error('User ID not found in response');
resolve(null); // Resolve with null instead of rejecting
}
}, (error) => {
console.error('Failed to get user ID:', error);
resolve(null); // Resolve with null on failure
}, 'get_user_id');
});
}
}
export default Api;