AppConsulta360 / js /analysisModule.js
aarnal80's picture
Update js/analysisModule.js
c62149d verified
// js/analysisModule.js (Revisado y corregido)
export async function analyzeMedical(text) {
if (!text || text.trim() === '') {
console.log("No text provided to analyze.");
return '';
}
// Cargar configuraci贸n de forma segura
const configString = localStorage.getItem('iaConfig');
if (!configString) {
throw new Error('Configuraci贸n IA no encontrada en localStorage. Por favor, configure los proveedores primero.');
}
let cfg;
try {
cfg = JSON.parse(configString);
} catch (e) {
throw new Error('Error al parsear la configuraci贸n IA desde localStorage.');
}
// Validar que la configuraci贸n necesaria existe para evitar errores
if (!cfg || !cfg.llm || !cfg.llm.provider || !cfg.llm.model || !cfg.llm.apiKeys) {
throw new Error('La configuraci贸n del LLM est谩 incompleta o corrupta. Por favor, guarde la configuraci贸n de nuevo.');
}
const provider = cfg.llm.provider;
const model = cfg.llm.model;
const apiKey = cfg.llm.apiKeys[provider];
if (!apiKey) {
throw new Error(`No se encontr贸 la API Key para el proveedor LLM seleccionado: ${provider}.`);
}
// Determinar endpoint seg煤n proveedor
let url;
if (provider === 'openai') {
url = 'https://api.openai.com/v1/chat/completions';
} else if (provider === 'deepseek') {
url = 'https://api.deepseek.com/v1/chat/completions';
} else {
throw new Error(`Proveedor LLM no soportado: ${provider}`);
}
const systemMessage = 'Eres un m茅dico experto especializado en generar informes cl铆nicos breves concisos y estructurados.';
const userPrompt = `Te dar茅 la transcripci贸n detallada de mi conversaci贸n con la paciente y t煤 escribe una descripci贸n breve de la enfermedad actual y la exploraci贸n f铆sica de un paciente en contexto cl铆nico, siguiendo estas caracter铆sticas:\nEnfermedad actual:\n- Incluye la edad, el g茅nero y el motivo de consulta del paciente. (si no te doy alg煤n dato, omite mencionarlo).\n- Detalla brevemente la evoluci贸n de s铆ntomas y su progresi贸n.\n- Describe brevemente los signos y antecedentes relevantes con lenguaje t茅cnico comprensible.\nExploraci贸n f铆sica:\n- Describe brevemente los hallazgos objetivos observados en la exploraci贸n.\n- Usa t茅rminos m茅dicos precisos, sin juicios diagn贸sticos.\nTareas del modelo:\n- Responde de forma concreta en dos p谩rrafos, sin t铆tulos 'Enfermedad actual:' ni 'Exploraci贸n f铆sica:'. \n- El primero para la enfermedad actual.\n- El segundo para la exploraci贸n.\nTranscripci贸n: ${text}`;
let messages;
if (provider === 'openai') {
// Para OpenAI, es com煤n enviar el system prompt como parte del primer mensaje de usuario
messages = [{ role: 'user', content: `${systemMessage}\n\n${userPrompt}` }];
} else {
// Para otros como DeepSeek, el rol 'system' est谩 bien soportado
messages = [
{ role: 'system', content: systemMessage },
{ role: 'user', content: userPrompt }
];
}
const payload = {
model: model,
messages: messages,
temperature: 1
};
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
};
try {
const res = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(payload)
});
if (!res.ok) {
const errorBody = await res.text();
console.error("Error response from API:", errorBody);
throw new Error(`Error en la llamada a la API de an谩lisis: ${res.status} - ${res.statusText}`);
}
const data = await res.json();
return data.choices?.[0]?.message?.content || '';
} catch (error) {
console.error("Fallo al ejecutar la solicitud de an谩lisis:", error);
throw error; // Re-lanza el error para que el c贸digo que llama pueda manejarlo
}
}