Saltar a contenido

Lector, referencias y citas

Los dominios del frontend features/reader/ y features/literature/, estrictamente tipados, gestionan sus respectivas páginas, componentes locales, estado y pruebas. Cada uno expone una entrada pública de carga diferida para cargar de forma independiente la lectura de feeds y la búsqueda bibliográfica. Los estilos de Literatura conservan su orden de cascada dentro de la feature. Los adaptadores compartidos de peticiones, la integración Zotero, la configuración de proveedores y el renderizado de citas no se duplican en estos dominios.

Las rutas, el almacenamiento, el análisis y las fuentes del Reader viven ahora en backend/domains/reader/; los repositorios, la búsqueda, la sincronización y el almacenamiento bibliográfico, en backend/domains/literature/. Los módulos anteriores permanecen como fachadas compatibles.

El análisis del Reader dependiente del vault, el acceso a resultados, la reanudación, la cancelación, la recuperación de contenido de artículos y la generación de pódcast pasan por un único control de vault activo. Si falta el contexto, se devuelve una respuesta recuperable de servicio no disponible antes de crear trabajos o hilos; las rutas válidas del vault y los payloads existentes no cambian. La generación de pódcast consume directamente el generador canónico tipado de sesiones de base de datos y lo cierra en el bloque finally existente; no hay conversiones de tipos ni factorías de sesiones duplicadas entre la orquestación del Reader y la persistencia.

Las rutas HTTP, los modelos canónicos y los servicios de revisión sistemática están tipados estrictamente. El recuento PRISMA, las transiciones de cribado, la evidencia de acceso abierto y las exportaciones CSV/JSON/Markdown/SVG viven en el dominio puro review_logic.py; las funciones históricas siguen como fachadas.

Portadas automáticas y plantillas de recursos

La creación desde una fuente carga las plantillas de la tabla antes de comparar el tipo Zotero detectado, incluidas sus etiquetas traducidas. La plantilla correspondiente aporta contenido y valores iniciales; los metadatos importados tienen prioridad, pero se conserva una portada existente de la plantilla. Sin coincidencia se usa la plantilla predeterminada. Los registros nuevos no heredan los indicadores de plantilla.

La consulta ISBN conserva la portada de la edición de Open Library. Las consultas DOI y web usan la imagen declarada por el editor mediante la consulta existente de URL públicas. La portada es opcional y no condiciona los metadatos. Si el PDF subido no tiene portada propuesta ni de plantilla, el navegador genera un JPEG acotado de la primera página y lo guarda en Assets/Covers antes de crear el recurso. El PDF original sigue adjunto. Los errores al generar o subir la portada no impiden la creación. Las portadas en línea son URL externas; las generadas del PDF son archivos locales. El enriquecimiento muestra una vista previa y no preselecciona sustituir una portada existente.

Un único aviso de progreso permanece visible después de cerrar el diálogo de búsqueda. Indica la preparación, la subida del PDF, la generación de la portada, el guardado y la apertura al empezar cada etapa. El mismo aviso confirma el éxito cuando se ha abierto el registro, o muestra un error si falla la creación. Las importaciones por identificador muestran solo las etapas aplicables.

Responsabilidad

Este dominio combina la lectura de feeds y boletines con un gestor de referencias compatible con Zotero, renderizado de citas CSL, importación por identificador o desde la web, lectura de PDF/EPUB y anotaciones que pueden convertirse en evidencia citable.

Ingesta de referencias

Crossref, Open Library, arXiv, PubMed y los metadatos HTML tienen normalizadores tipados separados en backend/domains/vault/citations/normalizers/. Conservan los payloads canónicos de Zotero y el comportamiento de función pura, mientras backend/services/lookup_normalizers.py sigue siendo la fachada compatible.

Las referencias se incorporan mediante DOI, ISBN, arXiv, PMID, BibTeX, RIS, archivos o URL web. Los resolutores de identificadores y el servidor de traducción de Zotero producen metadatos específicos del proveedor. Los normalizadores los mapean al esquema de referencias configurado, generan una clave de cita estable, deduplican candidatos y escriben un registro del vault.

backend/services/references_io.py es el límite tipado y determinista de BibTeX/RIS. Sus pequeños ayudantes de análisis, normalización, mapeo de campos y serialización preservan el orden, el escape, la resolución del tipo y el contrato público de importación/exportación, sin persistencia ni red ocultas. El deduplicador puro de importaciones utiliza estructuras explícitas de metadatos e índices de identificadores; conserva la prioridad clave de cita, DOI, ISBN y título normalizado. Las entradas creadas antes en la misma importación se añaden de forma idempotente a esos mismos índices. Las entradas del catálogo CSL y el mapeador declarativo de Zotero a Recursos exponen contratos serializables explícitos y conservan los campos adicionales arbitrarios del proveedor en la frontera JSON externa. Los resaltados de citas gestionados de Brain utilizan el mapeo tipado de SQLAlchemy; la única excepción sin tipado está localizada en el adaptador opcional pypdfium2, que no publica un marcador py.typed.

La orquestación de consulta, que es solo de lectura, reside en el dominio de citas, mantiene la prioridad DOI → arXiv → PMID → ISBN → URL y hace pasar las URL del usuario por el descargador protegido contra SSRF antes de sugerir cualquier campo. La tabla de Recursos designada se lee desde una única configuración canónica; solo los vaults heredados que nunca se hayan configurado pueden adoptar automáticamente la primera tabla con Citation Key, bajo el mismo bloqueo que Ajustes.

Translation-server es un sidecar opcional. La ejecución nativa puede funcionar sin él; los resolutores específicos de identificadores y las referencias existentes siguen funcionando. Los fallos de traducción web devuelven errores que permiten actuar, no un registro vacío presentado como correcto.

citations/pdf_fallback.py deriva un registro citable de los metadatos PDF cuando falla la resolución de identificadores. citations/web_capture.py selecciona y mapea resultados Zotero, y platform/translation_server.py gestiona el transporte HTTP.

Descubrimiento académico federado

El plugin integrado de Recursos gestiona la configuración de repositorios, mientras /api/vault/reference-table sigue siendo la única fuente de verdad de la tabla de Recursos de destino. /literature ejecuta cada conector seleccionado de forma independiente y transmite resultados parciales; los límites de cuota y los fallos de proveedor se atribuyen a su fuente sin descartar los resultados válidos de las demás.

backend/domains/literature/connectors/ gestiona el transporte HTTPS acotado, la auditoría de solicitudes, la normalización canónica, OAI-PMH y JSON personalizado, los grafos de citas y los adaptadores por familia de proveedores. backend/services/academic_connectors.py es solo una fachada de compatibilidad. El puerto tipado resuelve los colaboradores de la fachada en cada llamada para que pruebas e integraciones puedan sustituir transporte, validación, parsers y dispatch sin duplicar estado mutable.

El adaptador de Dimensions trata dimensions_api_key como una clave API. Cada búsqueda envía primero { "key": "..." } a https://app.dimensions.ai/api/auth mediante POST, valida el token recibido y envía la consulta DSL en UTF-8 a /api/dsl/v2 con Authorization: JWT <token>. El token se obtiene para cada búsqueda y no se guarda. Se requiere una suscripción con acceso a la API habilitado.

El transporte POST compartido conserva la validación HTTPS, los tiempos de espera, los límites de tamaño y los errores seguros de credenciales y cuota. Rechaza las redirecciones para no reenviar la clave ni el token. La auditoría registra el método HTTP real sin incluir cuerpos de petición ni cabeceras de autorización. Los tokens ausentes o inválidos y los errores de consulta se comunican como fallos del conector. backend/tests/test_dimensions_connector.py verifica el flujo y sus errores con respuestas HTTP simuladas; la validación real requiere una clave API habilitada.

AcademicWork es el contrato canónico de los conectores. Las fusiones deterministas utilizan, por orden, DOI normalizado, PMID o PMCID, identificador arXiv sin versión, ISBN-13 y título normalizado junto con el año y el apellido del primer autor. Una coincidencia aproximada de títulos solo genera un aviso. Los trabajos fusionados conservan cada aparición en las fuentes, las ubicaciones de acceso abierto, los recuentos de citas de cada proveedor, la procedencia de campos y las variantes en conflicto.

La vista previa es de solo lectura. Adjuntar el texto completo es una acción manual independiente, ofrecida únicamente para ubicaciones de acceso abierto verificadas. La importación convierte el trabajo fusionado mediante el mapeador compartido de Recursos compatible con Zotero y repite la comprobación de identidad dentro de un bloqueo atómico. Si ya existe un registro de Recursos coincidente, la API lo devuelve en lugar de crear un duplicado.

El adaptador de importación restringe todos los objetos anidados del proveedor —publicación, identificadores, fechas, ubicaciones de acceso abierto y campos adicionales de Zotero— mediante un único límite de mapeo antes de convertirlos. Los payloads de autores siguen siendo intencionalmente heterogéneos solo en el punto de integración con Zotero; las claves deterministas de trabajos, la inyección de claves de cita, la pertenencia a cuadernos y la reutilización de duplicados conservan su comportamiento.

Revisiones bibliográficas

El estado de las revisiones sistemáticas se almacena en cuatro tablas del vault gestionadas de forma idempotente: Literature Reviews, Literature Activities, Literature Candidates y Literature Decisions, esta última solo admite adiciones. Las estrategias de búsqueda, las consultas exactas a proveedores, los errores parciales, las operaciones de IA, las decisiones de cribado y las exportaciones siguen siendo auditables y se sincronizan con el vault principal.

El cribado por un único revisor y el cribado ciego con dos revisores comparten el mismo modelo de fases. En modo ciego, la decisión de cada revisor se oculta hasta que ambos la envían; los conflictos pasan a un consenso explícito. La IA puede proponer consultas editables, reordenar, cribar o sintetizar los metadatos recuperados, pero no puede excluir candidatos ni atribuir evidencia más allá del título, resumen o texto completo realmente proporcionados. La alternativa basada en solapamiento de tokens y el reordenador opcional con embeddings locales utilizan la misma estructura tipada de clasificación, conservando la puntuación y el orden por posición original en ambas implementaciones.

Los índices OAI y el estado temporal de búsqueda pueden reconstruirse y residen bajo LOCAL_DATA; los protocolos, historiales, candidatos, decisiones y artefactos de auditoría permanecen en el vault principal. Las credenciales de repositorios utilizan el Keychain nativo o el entorno de despliegue y nunca se escriben en el vault ni en el estado de plugins. Las filas OAI filtradas conservan la lista canónica tipada de trabajos del conector sin conversiones de tipos posteriores. El OCR opcional de PDF y el análisis de EPUB limitan sus únicas excepciones de tipado a los imports concretos de pypdfium2 y ebooklib, cuyos paquetes no publican py.typed; los objetos dinámicos no salen del adaptador de documentos.

Ruta de citación

flowchart LR
    Record["Página de referencia"] --> CSL["Normalización de elementos CSL"]
    CSL --> Citeproc["Motor citeproc + estilo seleccionado"]
    Citeproc --> Text["Citación en texto"]
    Citeproc --> Bibliography["Bibliografía"]
    Annotation["Anotación PDF"] --> Evidence["Cita/evidencia persistente"]
    Evidence --> Record

Los valores CSL se derivan del frontmatter de las referencias mediante mapeos de campos explícitos. Las listas de nombres, fechas, tipos de elementos, escapes de BibTeX/LaTeX y metadatos extra de Zotero requieren normalización. El esquema fijado protege los tipos y campos compatibles frente a cambios del proyecto de origen.

backend/domains/vault/citations/exporting.py gestiona la limpieza del Markdown, el subconjunto de citas, los marcadores de bibliografía, la ejecución de Pandoc y el empaquetado de la descarga. La ruta de compatibilidad conserva su firma pública e inyecta los puertos de archivos, CSL y procesos.

Lector y anotaciones

El lector Zotero incluido muestra contenido PDF y EPUB. Gnosi posee el puente que localiza archivos, sirve rangos de bytes seguros, recibe anotaciones y enlaza la evidencia seleccionada de nuevo a registros de Vault. Las filas de anotación incluyen URI de origen, página, tipo, geometría, texto, comentario, etiquetas, clave administrada estable y marcas de tiempo.

Los endpoints de archivos validan el confinamiento de rutas y gestionan la hidratación de archivos en la nube. Los identificadores persistentes de anotaciones evitan duplicar una cita generada cada vez que se reabre un documento.

El procesamiento conserva todas las citas en las notas y selecciona un subconjunto para resaltar en el PDF. Una heurística local compara cada cita completa con el título y el cuerpo de su nota, dando preferencia a la evidencia principal. Se resalta como máximo el 15% del texto de cada página, con un máximo de dos citas sin solapamientos y de pasajes distintos. Son límites, no cuotas obligatorias; las citas largas o poco adecuadas permanecen en las notas sin resaltado. La geometría de todas las citas se valida independientemente de esta selección visual. Sincronizar de nuevo elimina solo los resaltados obsoletos gestionados por el recurso y conserva las anotaciones manuales y las de otros recursos.

Las propiedades de archivo abren los adjuntos PDF y EPUB en el lector interno mediante la acción compartida de apertura. Las rutas relativas al vault se convierten en URL de activos servidos; los enlaces locales y los URL externos de documentos usan la misma ruta del lector. Si ningún panel gestiona el evento de apertura, se navega a la página del lector. Abrir un adjunto no modifica el valor guardado de la propiedad. Los activos del lector se compilan con el script existente y no se incluyen en el control de versiones.

Fuentes y boletines informativos

Los modelos del Reader almacenan fuentes, artículos, estado de lectura, contenido completo extraído y una cuenta de boletines. La ingesta de feeds utiliza savepoints de transacción para que una entrada malformada no revierta todo el lote. Los extractos y la extracción del texto completo son procesos separados; truncar durante la ingesta no debe descartar permanentemente contenido recuperable de la fuente.

La lista mantiene visibles los artículos leídos y no leídos. Las flechas arriba y abajo mueven el foco entre artículos y desplazan la lista para mostrar la fila seleccionada. Cuando el foco permanece en una fila durante 500 ms, el lector abre el artículo y lo marca como leído. Mover el foco, cambiar de fuente o salir de la lista cancela la apertura pendiente; un clic abre el artículo de inmediato. Los cambios del estado de lectura conservan el artículo seleccionado y la posición de la lista. El cuerpo se carga bajo demanda, y una respuesta tardía de una selección anterior no puede sustituir el cuerpo actual.

La acción manual de marcar como leído se sustituye por Añadir a Recursos cuando el complemento Recursos está activado. La acción espera el cuerpo completo del artículo y comprueba /api/vault/reference-table; si no hay destino configurado, muestra un error que indica cómo resolverlo sin crear ningún registro. El guardado llama a /api/vault/literature/imports con el título, la fecha de publicación, el nombre de la fuente, la URL original y el texto del cuerpo. El importador existente resuelve la tabla designada y gestiona la persistencia; el lector no introduce una segunda configuración de tabla ni una vía separada de escritura de registros.

Las noticias utilizan newspaper-article, mapeado a newspaperArticle de Zotero. Si no hay un identificador bibliográfico más fuerte, la deduplicación de noticias utiliza la URL HTTP(S) original sin el fragmento antes de considerar título, año y autor. La clave guardada permite reutilizar el recurso existente en importaciones repetidas aunque el artículo tenga otro identificador local en el lector. El botón impide guardados simultáneos, informa del éxito y permite reintentar después de un error.

Invariantes

  • Las claves de citación permanecen estables a menos que el usuario cambie explícitamente los datos de identidad.
  • La importación se deduplica mediante identificadores autoritativos y metadatos normalizados.
  • Un fallo de fuente federada no puede invalidar los resultados ya devueltos por otras fuentes.
  • La similitud difusa nunca fusiona las obras académicas automáticamente.
  • Las métricas de citas permanecen separadas por proveedor y nunca se suman.
  • Las sugerencias de IA nunca se convierten en decisiones finales de cribado sin una acción humana.
  • Las rutas de archivos del lector no pueden escapar de las raíces permitidas.
  • La identidad del documento y la geometría de página de una anotación sobreviven a los reinicios.
  • El código interno del lector incluido como dependencia se considera código del proyecto de origen; las modificaciones locales de integración son explícitas y reproducibles.
  • Las contraseñas de configuraciones heredadas de boletines se tratan como secretos incluso si un modelo antiguo sigue exponiendo un campo de compatibilidad.

Enfoque de verificación

Ejecute las pruebas de claves de cita, PubMed, tipos de elementos, estilos CSL, escapes BibTeX, entrada y salida de referencias, anotaciones, confinamiento de rutas, deduplicación de importaciones y savepoints de feeds. Añada pruebas de normalización de conectores, tokens y marcas de eliminación OAI, SSRF/XML, errores parciales, ocultación de decisiones entre revisores, importación concurrente y recuentos PRISMA. La validación en el navegador debe abrir un documento de prueba real y completar un ciclo de creación y lectura de una cita o anotación; después debe realizar una búsqueda bibliográfica progresiva, inspeccionar la procedencia e importar un resultado deduplicado.

Procesamiento de fuentes completas y tiempos de espera

El procesamiento conserva la capacidad de contexto del modelo seleccionado y envía las fuentes completas cuando caben. El límite de contexto y el tiempo de ejecución son independientes. Las peticiones de más de 96.000 bytes UTF-8 disponen de hasta 900 segundos por intento y 1.920 segundos en total; las fases menores mantienen 240 segundos por petición y 360 en total. Se mantienen cinco intentos y un máximo de 120 segundos de espera entre intentos. El umbral solo cambia el tiempo, nunca el contenido ni la fragmentación.

Los errores de tiempo de espera guardan un mensaje útil, traducido en el diálogo y las notificaciones. La lectura dirigida copia los planes guardados al nuevo trabajo antes de contactar con el proveedor, conservando el progreso si vuelve a fallar. Las llamadas estructuradas respetan el mismo límite de contexto que las demás lecturas.

Archivos del lector PDF

El lector PDF integrado necesita todos los archivos generados de Zotero en frontend/public/zotero-reader. Hay que ejecutar bash scripts/runtime/build-zotero-reader.sh antes de compilar una copia nueva. Vite comprueba los archivos de entrada y salida, incluidos el motor PDF, el worker, el visor y el idioma alternativo. El empaquetado de escritorio utiliza el mismo validador. Las actualizaciones solo de la interfaz también deben copiar este directorio; si falta el host, la espera se agota antes de abrir el documento. Tanto el CI de la interfaz como las releases preparan estos archivos.

Cuando la evidencia de una cita tiene vacía la dirección de la fuente, se utiliza el documento adjunto del recurso. Las direcciones locales de los adjuntos y las rutas HTTP del vault activo comparten la misma pestaña del lector y la identidad de las anotaciones. El lector carga los resaltados existentes de ambas formas de URI, elimina duplicados según el identificador de la base de datos y guarda las anotaciones nuevas con el URI canónico del adjunto. Las anotaciones generadas y manuales siguen disponibles sin volver a procesar la fuente; los documentos de otros vaults y las direcciones externas mantienen identidades separadas.

Asignación de campos a las notas generadas

Cada fuente selecciona assignment_field_ids independientemente de index_field_ids. Si la lista no existe, se conserva el comportamiento anterior basado en índices; una lista vacía desactiva las asignaciones. Las reglas admiten ai, source, fixed y empty. Solo se pueden asignar campos editables. Los valores de IA siguen esquemas tipados y los valores categóricos deben pertenecer a las opciones existentes. La copia y los valores fijos conservan cero y falso; las reglas vacías borran el valor al reprocesar, mientras que eliminar una regla conserva los metadatos existentes.

El resolvedor compartido backend/domains/llm_wiki/options.py consulta config.catalog_ref del vault activo antes de las opciones locales, de modo que la configuración y el procesamiento utilizan los mismos valores categóricos. Un agent_id antiguo vacío selecciona el agente principal. El editor espera que las reglas de copia y valor fijo estén completas antes de guardar. Las pruebas de regresión incluyen backend/tests/test_llm_wiki_field_assignments.py y backend/tests/test_llm_wiki_processing_domain_contract.py.

Apartados de las fuentes y paratexto

El procesamiento excluye de las notas las portadas, los metadatos editoriales, las citas iniciales y los prólogos o prefacios, salvo petición explícita del usuario. La cobertura registra estos pasajes y se conservan como contexto.

El Brain conserva Position (Posición) numérica y añade una relación única Section (Apartado) con una tabla gestionada de apartados de las fuentes. Los encabezados originales conservan su jerarquía, texto e identidades distintas aunque no estén numerados o repitan título. Cada apartado pertenece a una fuente y un documento de entrada; los selectores rechazan apartados de otras fuentes. Los filtros de igualdad seleccionan un apartado; los de inclusión también sus descendientes. Las páginas y marcas de tiempo permanecen en las citas. El audio y el vídeo utilizan los capítulos originales disponibles; no se inventan capítulos.

La actualización del esquema conserva las notas y no inicia procesamiento. El reprocesamiento explícito asigna apartados y marca los desaparecidos como antiguos, conservando las relaciones históricas. La aplicación deriva las asignaciones de segmentos verificados, también al reanudar un punto revisado.

Evidencia PDF estable y búsqueda de citas

La extracción PDF se guarda localmente con el SHA-256 de todos los bytes del archivo, la versión del extractor y una suma de comprobación del texto ordenado y sus localizadores. La estimación y el procesamiento comparten la extracción: repetir el OCR no invalida la lectura guardada de un PDF sin cambios. Las solicitudes simultáneas comparten una sola extracción. Los bytes modificados, las entradas corruptas, el OCR fallido y los archivos que cambian durante la extracción no pueden reutilizar ni publicar esta caché. La falta de OCR en páginas con imágenes es un error explícito; las páginas en blanco son válidas. Los recursos nativos se cierran incluso ante errores. La caché conserva la evidencia, pero no certifica la precisión del OCR.

La geometría de citas indexa los caracteres nativos una sola vez por página y sincronización. Los índices no se comparten entre archivos ni sobreviven a la sincronización. Se mantienen las comprobaciones de la cita completa, las letras exactas y la ambigüedad; solo se elimina la lectura repetida de los caracteres.

Si PDFium devuelve un glifo desconocido U+FFFE, un segundo decodificador PDF puede recuperarlo solo si toda la página normalizada tiene la misma longitud y todos los demás caracteres coinciden. El valor no se deduce de la cita solicitada; cualquier otra diferencia impide la recuperación. Se conservan los índices de geometría nativos originales.