Dinoer

Architecture

Pourquoi Dinoer est conçu de cette manière : ce qu'il garantit, ce qu'il refuse et quelles sont ses limites – limites déjà réduites sur la base de preuves réelles.

Comment se déroule une campagne de recherche

manifest.json
     │  campagne.py
     ▼
SearXNG  ── requêtes
     ▼
récupération HTTP simple  ──►  navigateur réel (seulement si la page ne suffit pas)
     ▼
collecte.jsonl  +  operations.jsonl
     ▼
OpenCode  ── classement, puis rapport
     ▼
rapport_<timestamp>.md
  1. Le manifeste est un fichier JSON de cibles : une query pour SearXNG, une url fixe, un produit (trouver l’unique page qui est réellement la page du produit) ou une table_reference (une liste de domaines de confiance pour un sujet). Seuls l’identifiant de la campagne et les cibles sont obligatoires.
  2. Découverte. Une cible query part vers l’instance SearXNG que vous avez configurée. Cette instance interroge à son tour d’autres moteurs de recherche, ce que Dinoer ne contrôle pas.
  3. Collecte. Chaque page est récupérée par une simple requête HTTP, une fois son robots.txt lu. Seule une page qui ne suffit pas passe à un navigateur réel, un processus Playwright par appel. Une cible qui échoue n’arrête pas les autres.
  4. Le corpus. Un collecte.jsonl par campagne, une ligne par extraction réussie, et operations.jsonl, qui consigne chaque tentative, réussie ou non.
  5. Le rapport. Les pages sont classées (par plongements locaux quand vous donnez un sujet), tronquées à un budget de taille, puis remises à OpenCode, qui écrit le corps de rapport_<timestamp>.md. La liste des sources est ajoutée par Dinoer lui-même ; le modèle ne l’écrit jamais.

shot.py et rpa.py sont différents : des appels indépendants, chacun avec son propre processus, qui se terminent dès qu’ils ont répondu. Pourquoi →

Qu’est-ce qui sort de votre machine, et par quelle porte ?

QuoiOù ça vaQui décideDans le code
Requêtes de découvertel’instance SearXNG que vous avez configurée, qui interroge à son tour d’autres moteursvous, avec DINOER_SEARXNG_URLlib/searxng.py
Requêtes de pageschaque site directement, son robots.txt est lu en premierles cibles dans votre manifestelib/fetch_leger.py, rpa.py
Texte collectéle modèle d’OpenCode, hébergé par défaut, pour le rapport, pour l’extraction ciblée et pour choisir une page produit (les 1500 premiers caractères de chaque candidat)vous, avec DINOER_OPENCODE_MODELlib/modeles.py, lib/synthese.py, lib/extraction.py, lib/selection_candidats.py
Un sujet, pour un tableau de référencele modèle d’OpenCode, le sujet uniquement, lorsqu’aucun tableau n’existe pour luila cible table_referencelib/tables_reference.py
Embeddingsvotre Ollama local, http://localhost:11434: le texte reste sur la machine sauf si vous pointez DINOER_OLLAMA_URL ailleursvouslib/vector.py
Une notificationun serveur ntfy, https://ntfy.sh sauf si vous en configurez un autre : l’identifiant de la campagne et le nombre de sources, jamais le chemin local du rapport. Uniquement lorsqu’un topic ntfy est définivous, avec ntfy_topic, DINOER_NTFY_TOPIC, DINOER_NTFY_URLcampagne.py, lib/ntfy.py
Vos identifiantsnulle part : résolus à l’intérieur du processus Playwright, à partir du répertoire chiffré—lib/repertoire_chiffre.py

Source : le code de la version 1.0.1, lu le 25 septembre 2026. Les modèles opencode/ sont hébergés : ce fournisseur répond à opencode.ai/zen (d’après opencode models --verbose, OpenCode 1.18.32). Ce que le modèle a ensuite le droit de faire avec le web est décrit sur la page de confiance, avec la limite qu’elle ne couvre pas.

Dans le détail