Implementar un método para obtener text/event-stream de un LLm usando React Native

Tiempo de lectura: 2 minutos

Hoy vamos a aprender cómo podemos obtener un stream de datos de un LLm usando React Native.

Desayuno - Pexels

Por defecto React Native no permite obtener un text/event-stream usando librerías como Axios o Fetch.

Para obtenerlo vamos a usar la librería react-native-sse que maneja event source.

npm install react-native-sse

Una vez instalada vamos a implementar nuestro código.

Tenemos que tener un servidor que nos devuelva una respuesta en text/event-stream por ejemplo un servidor de llama o openAI.

Primero vamos a crear la llamada:

 public obtenerStreamDeDatos(obj: ObjetoEnviar, setStreamData: React.Dispatch<React.SetStateAction<string>>): Promise<void>{
        const url = BaseURL + `/endpoint`;

        // Usamos react-native-sse para abrir una conexión SSE
        const eventSource = new EventSource(url, {
            withCredentials: true,
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'text/event-stream',
            },
            method: 'POST',
            body: JSON.stringify(obj),
        });

        // Escuchar eventos enviados por el servidor
        eventSource.addEventListener('message', (event: any) => {
            const chunk = event.data;
            // Procesamos el chunk recibido del servidor
            console.log('Data received from stream:', chunk);

            try {
                const jsonResponse = JSON.parse(chunk);
                if (jsonResponse.response) {
                    console.log('Respuesta del servidor:', jsonResponse.response);
                    if (!chunk.includes("[END OF STREAM]")) {
                        setStreamData((prevData) => prevData + jsonResponse.response);
                    }
                }

                // Condición para cerrar la conexión
                if (chunk.includes("[END OF STREAM]")) {
                    console.log("Cerrando conexión...");
                    eventSource.close(); // Cerrar la conexión cuando se encuentra el [END OF STREAM]
                  resolve(); // Resolvemos la promesa cuando se cierra la conexión
                }

            } catch (error) {
                console.warn('No es un JSON válido, se ignora:', chunk);
            }
        });

        // Manejo de errores
        eventSource.addEventListener('error', (err) => {
            console.error('Error al recibir datos del servidor:', err);
            eventSource.close(); // Cerrar la conexión en caso de error
            reject(err); // Rechazar la promesa en caso de error
        });
    }

Con este código enviaremos un objeto al servidor o lo que necesitemos enviar (puedes adaptarlo cómo necesites).

Indica el endpoint y la baseurl: const url = BaseURL + /endpoint;

Lo importante es cómo lo va a devolver, se le pasa una función setStream dónde añadirá el stream de datos en tiempo real. Además validará la respuesta para controlar que se devuelve bien.

Ahora vamos a implementar la vista dónde obtendremos el texto en tiempo real:

    const [streamData, setStreamData] = useState<string>(''); // Estado para almacenar los datos del stream


 const seleccionarMision = () => {

               obtenerStreamDeDatos(mision, setStreamData).then(() => {
                //Fin del stream
            }).catch((error: any) => {
                console.error('Error al obtener stream:', error);
            });
            }
        }
    };


return (
        <View style={styles.container}>
            {streamData && <Text style={styles.sub_texto}>{"Stream Data: " + streamData}</Text>}
        </View>
    )

Recuerda realizar los imports y adaptar tu código cómo necesites.

Y con esto ya tenemos nuestro Stream de datos listo.

Esto nos puede servir para implementar chatbots, chats en tiempo real con la IA etc…

Deja un comentario