No description
  • Python 50.5%
  • TypeScript 40.4%
  • HTML 9.1%
Find a file
alfenec 123953d97f FEneC × NotebookLM v0.2 : greffe chat (résultats structurés, injection composer auto + fallback copie)
gateway : artifacts structurés mock (quantities/validation/mesh/figures),
endpoint GET /api/v1/jobs/{id}/result, HTML cohérent, CORS paramétrable par env
extension : URL API publique par défaut, bouton Envoyer au chat (panel→background→content),
auto-injection du content script (scripting), injection composer NotebookLM
(shadow DOM + insertText) avec fallback presse-papier, capture sélection retirée
sécurité : clé API hors repo (.env gitignoré)
docs : checklist gate-a-test
2026-09-03 19:05:47 +02:00
docs FEneC × NotebookLM v0.2 : greffe chat (résultats structurés, injection composer auto + fallback copie) 2026-09-03 19:05:47 +02:00
extension FEneC × NotebookLM v0.2 : greffe chat (résultats structurés, injection composer auto + fallback copie) 2026-09-03 19:05:47 +02:00
gateway FEneC × NotebookLM v0.2 : greffe chat (résultats structurés, injection composer auto + fallback copie) 2026-09-03 19:05:47 +02:00
scripts FEneC × NotebookLM : extension Chromium MV3 + gateway FastAPI (jobs async, clé API, dedup recettes, backend mock/homelab) 2026-09-01 19:06:58 +00:00
.gitignore FEneC × NotebookLM v0.2 : greffe chat (résultats structurés, injection composer auto + fallback copie) 2026-09-03 19:05:47 +02:00
README.md FEneC × NotebookLM : extension Chromium MV3 + gateway FastAPI (jobs async, clé API, dedup recettes, backend mock/homelab) 2026-09-01 19:06:58 +00:00

FEneC × NotebookLM — Extension Chromium

Ajoute la couche validation physique (simulation par éléments finis) au panneau de NotebookLM — le "chaînon manquant" : NotebookLM explique, FEneC calcule.

Rendu v1 : iframe-widget. Le panneau charge une result_url tokenisée servie par le gateway FEneC (page compatible framage via CSP frame-ancestors). On teste A ; si les gates passent, on garde. Replis documentés : B (rendu natif), C (texte + figures backend).

Architecture

extension/   Chromium MV3 (TypeScript + Vite + @crxjs/vite-plugin)
  src/background.ts      service worker (icône → side panel, menu contextuel)
  src/content.ts         détection NotebookLM + capture de sélection
  src/sidepanel.html|ts  panneau (drop zone, capture, status, iframe résultat)
  src/lib/api.ts         client HTTP (clé API, jobs, polling)
gateway/     FastAPI — surface publique unique, recette interne isolée
  app/main.py            endpoints + CORS
  app/auth.py            clés API (header X-API-Key)
  app/pipeline.py        jobs async + dédoublonnage recettes (flywheel)
  app/backends.py        MockBackend (défaut) / HomelabBackend (env)
  app/render.py          page résultat (framable, tokenisée)

Quickstart

Gateway (local)

cd gateway
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
FENEC_API_KEYS=dev-key FENEC_MOCK_DELAY=2 .venv/bin/uvicorn app.main:app --port 8000

Tests : FENEC_API_KEYS=test-key FENEC_MOCK_DELAY=0 .venv/bin/python -m pytest tests -q

Extension

cd extension
npm install
npm run dev        # serveur dev Vite (HMR)
npm run build      # → dist/ (charger "unpacked" via chrome://extensions)

Test manuel : charger extension/dist en mode "Extension non empaquetée", ouvrir https://notebooklm.google.com, cliquer l'icône FEneC → le side panel s'ouvre. Saisir la clé API dans le panneau (bouton Enregistrer), puis : sélectionner un texte dans NotebookLM → "Capturer la sélection", ou déposer un fichier (image/PDF).

Contrat API

Méthode Route Body Réponse
POST /api/v1/simulate text | image_b64+filename (multipart) {job_id, status, result_url?}
GET /api/v1/jobs/{id} {job_id, status, result_url?, error?}
GET /sim/result/{id}?token=… HTML résultat (framable, tokenisé)

Auth : header X-API-Key. Jobs asynchrones (solve 30-120 s) → poll jobs/{id} toutes les 2 s.

Variables d'environnement (gateway)

Variable Défaut Rôle
FENEC_API_KEYS dev-key clés autorisées (CSV)
FENEC_MOCK_DELAY 2.0 délai du mock (0 = synchrone)
FENEC_BACKEND mock mock | homelab
FENEC_SOLVE_URL endpoint solve homelab (requis si homelab)
FENEC_OCR_URL endpoint OCR (requis si images)

Intégration homelab (M6)

HomelabBackend appelle :

  1. OCR si image : POST {FENEC_OCR_URL}/process {image_b64}{text} (ex. ocr-runner.fenec.svc.cluster.local).
  2. Solve : POST {FENEC_SOLVE_URL}/api/v1/solve {text, filename} → réponse JSON {html?: string, figures?: [url]}. html est servi tel quel dans la page résultat.

Le réseau homelab restreint l'accès à ocr-runner (NetworkPolicy → n8n uniquement) : à ouvrir vers le gateway au déploiement. Les services internes sont en ClusterIP — le gateway est déployé dans le cluster (ArgoCD) pour y accéder via service DNS.

Rendu — gates à valider (M5)

  • La page /sim/result/{id}?token=… se charge dans l'iframe du side panel (pas de X-Frame-Options, CSP frame-ancestors OK)
  • URL tokenisée : sans token → 403
  • Chargement < 2 s, lisible à 320-400 px
  • Dédoublonnage recettes : un même énoncé déjà résolu → résultat instantané

Sécurité

  • Aucun secret dans l'extension (clés API côté serveur uniquement ; la clé utilisateur vit dans chrome.storage.local).
  • Gateway : clé API, rate-limit à poser en production, cap fichier 10 Mo, URL résultats tokenisées.
  • OCR/solve = 100 % dans la stack FEneC ; seul l'énoncé/text sélectionné quitte la page.