Spaces:
Running
Running
| // server.js | |
| // Backend proxy para análisis médico y evitar CORS | |
| require('dotenv').config(); | |
| const express = require('express'); | |
| const cors = require('cors'); | |
| const { Configuration, OpenAIApi } = require('openai'); | |
| const app = express(); | |
| const port = process.env.PORT || 3000; | |
| app.use(cors()); | |
| app.use(express.json()); | |
| app.post('/medical-analyze', async (req, res) => { | |
| try { | |
| const { provider, model, apiKey, text } = req.body; | |
| // Prompts | |
| const systemMessage = 'Eres un médico experto especializado en generar informes clínicos concisos y estructurados.'; | |
| const userPrompt = `Te daré la transcripción detallada de mi conversación con la paciente y tú escribe una descripción detallada de la enfermedad actual y la exploración física de un paciente en contexto clínico, siguiendo estas características:\n | |
| Enfermedad actual:\n- Incluye la edad, el género y el motivo de consulta del paciente. (si no te doy el dato, omite).\n- Detalla evolución de síntomas y su progresión.\n- Describe signos y antecedentes relevantes con lenguaje técnico comprensible.\n | |
| Exploración física:\n- Describe hallazgos objetivos observados en la exploración.\n- Usa términos médicos precisos, sin juicios diagnósticos.\n | |
| Tareas del modelo:\n- Responde 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.\n | |
| Transcripción: ${text}`; | |
| const messages = [ | |
| { role: 'system', content: systemMessage }, | |
| { role: 'user', content: userPrompt } | |
| ]; | |
| let analysis; | |
| if (provider === 'openai') { | |
| const configuration = new Configuration({ apiKey }); | |
| const openai = new OpenAIApi(configuration); | |
| const response = await openai.createChatCompletion({ model, messages, temperature: 0.5 }); | |
| analysis = response.data.choices[0].message.content; | |
| } else if (provider === 'deepseek' || provider === 'gemini') { | |
| // Definir URLs por proveedor | |
| const urls = { deepseek: 'https://api.deepseek.com/v1/chat/completions', gemini: 'https://generativelanguage.googleapis.com/v1/chat/completions' }; | |
| const url = urls[provider]; | |
| const resp = await fetch(url, { | |
| method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ model, messages, temperature: 0.5 }) | |
| }); | |
| if (!resp.ok) throw new Error(`Error ${provider}: ${resp.status}`); | |
| const data = await resp.json(); | |
| analysis = data.choices?.[0]?.message?.content; | |
| } else { | |
| throw new Error('Proveedor no soportado: ' + provider); | |
| } | |
| res.json({ analysis }); | |
| } catch (error) { | |
| console.error('Error /medical-analyze:', error); | |
| res.status(500).json({ error: error.message }); | |
| } | |
| }); | |
| app.listen(port, () => { | |
| console.log(`Backend listening on http://localhost:${port}`); | |
| }); | |