Eco · Flujos y procesos

Resumen mínimo de cómo el contenido se mueve a través del sistema.

Volver a la app

Flujo de alto nivel

[1] Fuente
    ├─ Modo: URL de artículo
    │   • Obtener y parsear el artículo
    │   • Resumir con un LLM
    │   • Construir subtítulo + campos
    └─ Modo: Tema
        • Obtener fuentes (Noticias, Reddit, ArXiv)
        • Rankear y resumir
        • Construir subtítulo + campos

[2] Plantilla
    • Elegir plantilla JSON
    • Editar diapositivas (bloques de texto + superposiciones)
    • Modos de contenido:
        - system     → usa campos del pipeline (título, cuerpo, etc.)
        - fixed      → copy provisto por el diseñador
        - generative → el LLM usa un prompt para generar el texto final

[3] Revisar y generar
    • Ejecutar el pipeline completo
    • Renderizar diapositivas con Pillow
    • (Opcional) subir assets
    • Guardar ejecución en DB local + historial

Pasos en la UI

1 · Fuente

  • - Elegir Artículo o Tema.
  • - Proveer URL o palabra clave + directriz.
  • - Opcional: habilitar motor de tipología.

2 · Plantilla

  • - Seleccionar o crear una plantilla.
  • - Editar diapositivas usando el canvas del diseñador.
  • - Usar modos de contenido por bloque de texto.
  • - Agregar superposiciones de imagen o placeholders.

3 · Revisar y generar

  • - Click en “Generar Publicación”.
  • - Ver eventos de progreso en la línea de tiempo.
  • - Inspeccionar subtítulo, diapositivas y campos estructurados.
  • - Scrollear hacia abajo para ver el historial.

Datos y renderizado

Esquema de plantilla (simplificado)

TemplateContent
  • size: [width, height]
  • slides: Slide[]

Slide
  • text_blocks: TemplateBlock[]
  • overlays: TemplateOverlay[]

TemplateBlock
  • field | system_key
  • content_mode: system | fixed | generative
  • fixed_text | prompt
  • x, y, size, wrap, color, align, z_index

Pipeline de render

LinkToPostPipeline
  → fetch + summarize source
  → build fields (title, body, overlays, image)
  → TemplateEngine.render()
      - creates slides
      - resolves text blocks (system/fixed/generative)
      - applies overlays + logos
      - saves PNGs + metadata

Diagrama mínimo

[Usuario]
   │
   ├─ Paso 1: Fuente (Artículo / Tema)
   │      │
   │      └─ LLM + Typology → { summary, fields }
   │
   ├─ Paso 2: Plantilla
   │      │
   │      └─ Designer → Template JSON (slides, blocks, overlays)
   │
   └─ Paso 3: Revisar y generar
          │
          └─ Pipeline
               • LinkToPostPipeline
               • TemplateEngine (Pillow)
               → PNG slides + caption
               → Guardado en historial

Fuentes y procesos

Fuentes

  • - URLs de artículos desde el formulario de la app.
  • - Vigilancia de temas (keywords) usando:
  • • Adaptador de Google News.
  • • Adaptador de Reddit.
  • • Adaptador de ArXiv.

Procesos núcleo

  • - ArticleParser → limpia el texto del artículo.
  • - LLMOrchestrator → resúmenes y rerank.
  • - LinkToPostPipeline → pipeline completo.
  • - Pipeline de temas → feed multi-fuente.
  • - Motor de tipología → elige plantilla y layout de campos (opcional).

Herramientas de GenAI y render

Herramientas de GenAI

  • - Cliente OpenAI → resúmenes + ranking.
  • - Cliente Gemini LLM → resúmenes (default).
  • - Bloques de texto generativos:
  • • El diseñador escribe un prompt por bloque.
  • • El LLM devuelve el texto final para el canvas.
  • - Cliente de imagen Gemini → fondos / overlays generativos.

Render y almacenamiento

  • - TemplateEngine + Pillow → PNG de diapositivas.
  • - Soporte multi-diapositiva (carruseles).
  • - Filesystem local: static/posts/images/.
  • - Subida opcional a la nube via cliente de storage.
  • - DB local: historial, metadata, campos estructurados.

Demos (input → output)

Estos ejemplos son ejecuciones “pre-hechas” guardadas como JSON en backend/tests/samples/.

ArticleParser

Scrape + clean de un artículo (texto utilizable para LLM / fields).

POST /ingest/article

sample: backend/tests/samples/ingest_article.json

  • - Entrada: una URL.
  • - Salida: { title, text, source_url, metadata } listo para resumir / tipología.
  • - Esto alimenta el paso “Fuente → Artículo” en la app.
Request (JSON)
{
  "url": "https://www.bbc.com/news/science-environment-56837908"
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

LLMOrchestrator · summarize

Resumen corto en español (tono “optimistic”).

POST /llm/summarize

sample: backend/tests/samples/tools_llm_summarize.json

  • - Entrada: texto “crudo” (headline/body) + estilo/idioma.
  • - Salida: summary listo para caption/carrusel.
  • - Se usa en pipelines: Link→Post y Topic pipeline.
Request (JSON)
{
  "text": "AI tools help teachers personalize lessons for every child while saving prep time.",
  "provider": "gemini",
  "target_language": "es",
  "style": "informative y cercano",
  "max_words": 80
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

LLMOrchestrator · rerank

Ranking de candidatos (feed) con criterio editorial.

POST /llm/rerank

sample: backend/tests/samples/tools_llm_rerank.json

  • - Entrada: lista de items + criteria.
  • - Salida: scores + rationales para elegir qué postear.
  • - Se usa en Topic pipeline antes de resumir/render.
Request (JSON)
{
  "provider": "gemini",
  "criteria": "contenido útil para educadores",
  "items": [
    {
      "id": "1",
      "content": {
        "title": "AI lesson planners arrive in classrooms",
        "text": "Teachers experiment with copilots that draft lesson outlines using curriculum data.",
        "source_url": "https://www.edsurge.com/news/2023-10-02-ai-lesson-planners-arrive",
        "image_url": null,
        "language": "en",
        "metadata": {
          "source": "EdSurge"
        }
      }
    },
    {
      "id": "2",
      "content": {
        "title": "Robotics club goes national",
        "text": "Students prepare for robotics competitions in 2024.",
        "source_url": "https://www.bbc.com/news/technology",
        "image_url": null,
        "language": "en",
        "metadata": {
          "source": "BBC"
        }
      }
    }
  ]
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

TopicMapService (ingest multi-fuente)

Recolecta un feed por tema desde Google News + Reddit + ArXiv.

POST /ingest/topic-map

sample: backend/tests/samples/tools_topic_map.json

  • - Entrada: topic + sources.
  • - Salida: results agrupados por fuente (RawContent[]).
  • - Este output es lo que luego se rerankea y se transforma en post.
Request (JSON)
{
  "topic": "ai education",
  "sources": [
    "google_news",
    "reddit",
    "arxiv"
  ]
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Format caption

Traduce + arma caption con finales y hashtags.

POST /format/post

sample: backend/tests/samples/topic_post_format.json

  • - Entrada: RawContent (título/texto/url) + finales + hashtags.
  • - Salida: caption listo para publicar.
  • - Útil cuando querés “postear rápido” sin render.
Request (JSON)
{
  "content": null,
  "finales": [
    "Encontrá más historias en nuestro sitio"
  ],
  "hashtags": [
    "parenting",
    "bienestar",
    "familia"
  ]
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Topic pipeline

Ingest → rerank → summarize → render (end-to-end).

POST /topics/pipeline

sample: backend/tests/samples/tools_topic_pipeline.json

  • - Entrada: topic + guideline + sources + template.
  • - Salida: caption + asset (slides) + ranked (debug).
  • - Esto corresponde al modo “Fuente → Tema” en el estudio.
Request (JSON)
{
  "topic": "educacion con inteligencia artificial",
  "guideline": "tono optimista y conciso",
  "sources": [
    "google_news",
    "reddit",
    "arxiv"
  ],
  "template": "default_square",
  "hashtags": [
    "educacion",
    "IA"
  ],
  "finales": [
    "Descubrí más historias en nuestra comunidad"
  ],
  "llm_provider": "gemini",
  "options": {
    "reddit": {
      "subreddits": [
        "edtech",
        "education"
      ]
    },
    "arxiv": {
      "filters": {
        "categories": [
          "cs.CL"
        ]
      }
    }
  }
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Link → Post (LinkToPostPipeline)

Ingest artículo → resumen/caption → render slides.

POST /posts/link

sample: backend/tests/samples/tools_link_to_post.json

  • - Entrada: URL + topic/guideline + template.
  • - Salida: summary + caption + asset.slides renderizados.
  • - Es el flujo principal para “Artículo → Publicación”.
Request (JSON)
{
  "url": "https://kidshealth.org/en/parents/net-safety.html",
  "topic": "AI y bienestar digital familiar",
  "guideline": "Resumen empático en español para madres y padres",
  "template": "default_square",
  "hashtags": [
    "IA",
    "familia",
    "bienestardigital"
  ],
  "finales": [
    "Seguinos para más ideas"
  ],
  "llm_provider": "gemini"
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Typology engine (auto layout + fields)

Selecciona tipología y genera structured_fields para un layout específico.

POST /posts/link

sample: backend/tests/samples/tools_typology_link2post.json

  • - Entrada: Link→Post + use_typology_engine.
  • - Salida: typology + structured_fields + slides (muchas).
  • - Ideal para formatos como “recap semanal” con highlights.
Request (JSON)
{
  "url": "https://kidshealth.org/en/parents/net-safety.html",
  "topic": "IA en el aula",
  "guideline": "Recap semanal con highlights y CTA",
  "use_typology_engine": true,
  "allowed_typologies": [
    "recap",
    "news"
  ],
  "auto_template": true,
  "template": "recap_grid_square",
  "hashtags": [
    "AI",
    "educacion"
  ],
  "finales": [
    "Compartí este resumen con tu red"
  ],
  "llm_provider": "gemini"
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

TemplateEngine (render)

Renderiza una plantilla + fields → PNG.

POST /assets/image

sample: backend/tests/samples/tools_template_engine.json

  • - Entrada: template + fields (texto + imagen).
  • - Salida: asset (path/size) para previsualizar o publicar.
  • - Se usa internamente en los pipelines y en el diseñador.
Request (JSON)
{
  "template": "default_square",
  "fields": {
    "title": "IA en educación",
    "subtitle": "Consejos reales para docentes y familias",
    "image_url": "https://images.unsplash.com/photo-1503676260728-1c00da094a0b?auto=format&fit=crop&w=1080&q=80"
  },
  "upload": false
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Gemini image client

Genera un fondo/imagen con prompt (para overlays o slides).

POST /assets/gemini-image

sample: backend/tests/samples/tools_gemini_image.json

  • - Entrada: prompt.
  • - Salida: path (imagen local) y metadata del modelo.
  • - Usalo como input para TemplateEngine (image_path).
Request (JSON)
{
  "prompt": "Vibrant futuristic classroom with AI assistants helping students",
  "upload": false
}
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Historial local (DB)

Listado de ejecuciones recientes (para UI / auditoría).

GET /posts/history?limit=5

sample: backend/tests/samples/tools_local_history.json

  • - Salida: array de posts recientes (id, caption, asset_url...).
  • - Esto alimenta “Historial” en la UI (scroll abajo).
Response (JSON) · missing sample
Sample not found. Run backend integration tests to regenerate.

Herramientas disponibles (Backend API)

POST /content/instagram

Genera caption + headlines para Instagram desde URL o texto

POST /content/linkedin

Genera post de LinkedIn desde brief o URL

POST /content/tweet-thread

Genera thread de tweets desde URL o texto

POST /content/newsletter

Genera resúmenes de newsletter para N items

POST /content/headlines

Genera variantes de títulos para cualquier plataforma

POST /carousel/generate

Pipeline completo: scraping → LLM → carousel renderizado

POST /ingest/article

Scrapea un artículo (trafilatura + curl_cffi)

POST /ingest/gnews

Busca noticias en Google News

POST /ingest/twitter

Scrapea tweets por handle o URL (Bird CLI)

POST /ingest/reddit

Busca posts en Reddit por subreddit/query

POST /ingest/arxiv

Busca papers en Arxiv

POST /llm/summarize

Resumen de texto con LLM (claude/gemini/openai/ollama)

POST /llm/rerank

Rankeo de artículos por engagement potencial

POST /llm/review

Revisión de calidad de contenido

GET /assets/list

Lista assets disponibles (logos, fondos, overlays)

GET /monitors/jobs

Lista monitores de noticias configurados

GET /monitors/seen-urls

Noticias consumidas por monitores con metadata

MCP Tools (para agentes)

ingest_gnews

Buscar Google News

ingest_reddit

Buscar Reddit

ingest_arxiv

Buscar Arxiv papers

ingest_article

Scrapear un artículo por URL

ingest_twitter

Scrapear tweets por handle/URL

ingest_topic_map

Multi-source topic map

format_instagram

Generar post de Instagram

format_linkedin

Generar post de LinkedIn

format_tweet_thread

Generar thread de tweets

generate_headlines

Generar variantes de títulos

notion_search

Buscar en Notion workspace

notion_query

Query a Notion data source

notion_create_page

Crear página en Notion

notion_push_draft

Enviar draft eco → Notion

LLM Providers

claude

Claude via proxy local (3456). Sin API key, OAuth.

gemini

Google Gemini. Requiere GEMINI_API_KEY.

openai

GPT-4o/mini. Requiere OPENAI_API_KEY.

anthropic

Anthropic directo. Requiere ANTHROPIC_API_KEY.

ollama

Local (llama3.2). Requiere Ollama corriendo.

Fuentes de contenido

Google News

Via GNewsAdapter — búsqueda por keywords, filtro por idioma/país

RSS Feeds

Via RSSNewsAdapter — cualquier feed RSS

X / Twitter

Via Bird CLI — timeline por handle o tweet individual por URL

Reddit

Via RedditAdapter — búsqueda por subreddit y query

Arxiv

Via ArxivAdapter — papers por categoría o búsqueda

URLs directas

Via ArticleParser (trafilatura + curl_cffi) — cualquier URL web

Notion

Via NotionClient — noticias curadas, swipe files, tareas editoriales