Aller au contenu
OmniRoute source

RTK Compression (Français)

RTK prend en charge 3 niveaux d’intensité offrant différents compromis entre l’agressivité de la compression et la sécurité. Le niveau est défini via config.intensity dans la configuration du moteur.

Niveau Seuil de troncature Économie de jetons Risque Idéal pour
minimal 24 lignes par section ~20-40% Très faible Production avec un contexte critique
standard (défaut) 24 lignes par section ~50-70% Faible Sessions quotidiennes de programmation
aggressive 16 lignes par section ~70-90% Moyen Longues sessions, économies maximales

Le seuil de troncature affecte lineFilter.ts :

// Extrait de open-sse/services/compression/engines/rtk/index.ts:329-330
config.intensity === "aggressive" ? 16 : 24,
config.intensity === "aggressive" ? 16 : 24,

Le début et la fin de chaque section sont tous deux préservés ; le contenu intermédiaire est supprimé lorsque la troncature s’applique.

Contenu minimal standard aggressive
Erreurs / traces de pile ✅ préservées ✅ préservées ✅ préservées
Échecs de tests ✅ préservés ✅ préservés ✅ préservés
Erreurs de compilation ✅ préservées ✅ préservées ✅ préservées
Tests réussis (sortie détaillée) ✅ préservés 🟡 condensés 🟡 condensés
Sortie courante (journaux info) 🟡 condensée 🟡 condensée ❌ supprimée
Barres de progression 🟡 condensées ❌ supprimées ❌ supprimées
Bannière / art ASCII 🟡 condensé ❌ supprimé ❌ supprimé
La perte de contexte est-elle catastrophique ?
│
┌───────────┼───────────┐
│ │ │
OUI NON INCERTAIN
│ │ │
▼ │ │
minimal │ │
│ │ │
│ ▼ ▼
│ Quel est le Essayez d’abord `standard`
│ niveau critique (convient à 80 % des
│ du débit ? cas)
│ │
│ ┌────┴────┐
│ │ │
│ FAIBLE ÉLEVÉ
│ │ │
│ ▼ ▼
│ standard aggressive
│ │ │
└──────┴─────────┘

Par combo (dans la configuration du combo) :

{
"combo": "my-coding-combo",
"routing": {/* ... */},
"compression": {
"engine": "rtk",
"intensity": "aggressive"
}
}

Par programmation :

rtkEngine (@omniroute/open-sse/services/compression/engines/rtk) est un CompressionEngine et ne possède aucune méthode updateConfig. Mettez à jour la configuration d’un moteur à l’aide de l’utilitaire du registre :

import { updateEngineConfig } from "@omniroute/open-sse/services/compression/engines/registry";
updateEngineConfig("rtk", { intensity: "aggressive" });

Utilisez la barrière de vérification (voir ci-dessous) pour confirmer que votre filtre est sûr avec l’intensité choisie :

import { runRtkFilterTests } from "omniroute/compression/engines/rtk/verify";
const result = runRtkFilterTests({ intensity: "aggressive" });
if (!result.passed) {
console.error("Échec des filtres avec l’intensité aggressive");
}

Développement de filtres personnalisés (v3.8.16+)

Section intitulée « Développement de filtres personnalisés (v3.8.16+) »

Le répertoire engines/rtk/filters/ contient plus de 49 fichiers JSON de filtres intégrés. Vous pouvez ajouter les vôtres afin de compresser la sortie d’outils personnalisés non couverts par les filtres par défaut.

{
"id": "string", // Obligatoire. Identifiant du filtre (kebab-case, p. ex. « python-traceback »)
"label": "string", // Obligatoire. Nom lisible du filtre
"description": "string", // Facultatif (valeur par défaut : ""). Brève description de l’action du filtre
"category": "git|test|build|shell|docker|package|infra|cloud|generic",
"priority": number, // Facultatif (0-100, valeur par défaut : 50). Ordre d’exécution (plus élevé = en premier)
"match": {
"commands": ["string"], // Noms de commandes à faire correspondre (p. ex. « python », « pytest »)
"patterns": ["string"], // Expressions régulières à faire correspondre à la sortie
"outputTypes": ["string"] // Classes de sortie détectées (p. ex. « test-failure »)
},
"rules": {
"stripAnsi": boolean, // Facultatif (valeur par défaut : false). Supprime les codes de couleur ANSI
"replace": [ // Règles de recherche et de remplacement (valeur par défaut : [])
{ "pattern": "regex", "replacement": "..." }
],
"matchOutput": [ // Interrompt le traitement lorsqu’un motif correspond (valeur par défaut : [])
{
"pattern": "regex",
"message": "short summary",
"unless": "regex" // Ignore si ce motif correspond
}
],
"includePatterns": ["string"], // Lignes à conserver (expressions régulières, valeur par défaut : [])
"dropPatterns": ["string"], // Lignes à supprimer (expressions régulières, valeur par défaut : [])
"collapsePatterns": ["string"], // Lignes à réduire à une seule occurrence (valeur par défaut : [])
"deduplicate": boolean, // Facultatif (valeur par défaut : false). Supprime les lignes en double
"truncateLineAt": number, // Facultatif (valeur par défaut : 0). Tronque les lignes au nombre maximal de caractères
"maxLines": number, // Facultatif (valeur par défaut : 0). Limite stricte du nombre total de lignes
"headLines": number, // Facultatif (valeur par défaut : 20). Conserve les N premières lignes de la sortie correspondante
"tailLines": number, // Facultatif (valeur par défaut : 20). Conserve les N dernières lignes de la sortie correspondante
"onEmpty": "string", // Facultatif (valeur par défaut : ""). Message de repli si toutes les lignes sont filtrées
"filterStderr": boolean // Facultatif (valeur par défaut : false). Filtre également la sortie stderr
},
"preserve": {
"errorPatterns": ["string"], // Motifs devant toujours être conservés (valeur par défaut : [])
"summaryPatterns": ["string"] // Motifs correspondant à la ligne de résumé finale (valeur par défaut : [])
},
"tests": [ // Tests intégrés pour vérification (valeur par défaut : [])
{
"name": "string", // Obligatoire. Nom du test
"input": "sample output", // Obligatoire. Exemple de texte d’entrée
"expected": "expected output", // Obligatoire. Sortie compressée attendue
"command": "optional command" // Facultatif. Contexte de la commande
}
]
}
{
"id": "python-traceback",
"label": "Python Traceback Filter",
"description": "Compresses Python tracebacks to essential file/line locations and error type",
"category": "test",
"priority": 60,
"match": {
"commands": ["python", "python3", "pytest", "uv", "poetry"],
"patterns": ["Traceback \\(most recent call last\\)", "Error", "Exception"],
"outputTypes": ["error-traceback"]
},
"rules": {
"stripAnsi": true,
"includePatterns": [
"Traceback \\(most recent call last\\)",
"^\\s*File \".+\", line \\d+",
"^\\s*[A-Z][a-zA-Z]+Error:",
"^\\s*[A-Z][a-zA-Z]+Exception"
],
"dropPatterns": ["site-packages/", "^\\s+[a-z_]+\\([^)]*\\)$"],
"headLines": 5,
"tailLines": 3,
"maxLines": 25,
"filterStderr": true
},
"preserve": {
"errorPatterns": ["Error:", "Exception:", "Traceback"],
"summaryPatterns": ["^[A-Z][a-zA-Z]+(?:Error|Exception):"]
},
"tests": [
{
"name": "preserves-error-type-and-location",
"input": "Traceback (most recent call last):\n File \"app.py\", line 42, in main\n do_thing()\n File \"lib/utils.py\", line 17, in helper\n return 1 / 0\nZeroDivisionError: division by zero",
"expected": "Traceback (most recent call last):\n File \"app.py\", line 42, in main\n File \"lib/utils.py\", line 17, in helper\nZeroDivisionError: division by zero",
"command": "python app.py"
}
]
}

Placez le fichier dans un emplacement reconnu :

~/.omniroute/rtk/filters/my-filter.json # Niveau utilisateur
<project>/.rtk/filters/my-filter.json # Niveau projet

Les filtres sont chargés automatiquement au démarrage via loadRtkFilters() dans open-sse/services/compression/engines/rtk/filterLoader.ts. Le chargeur recherche les filtres dans les emplacements suivants :

  • Catalogue intégré : open-sse/services/compression/engines/rtk/filters/
  • Répertoire utilisateur : ~/.omniroute/rtk/filters/
  • Répertoire du projet : <project>/.rtk/filters/

Pour charger les filtres par programmation :

import { loadRtkFilters } from "@omniroute/open-sse/services/compression/engines/rtk/filterLoader";
// Options : customFiltersEnabled (charge les filtres utilisateur/projet, activé par défaut),
// trustProjectFilters, refresh.
const filters = loadRtkFilters({ customFiltersEnabled: true });

Les filtres sont validés par rapport au schéma Zod lors du chargement. Un filtre dont la structure est incorrecte ne pourra pas être chargé et une erreur sera consignée :

RTK_FILTER_LOADER: échec de la validation du filtre "my-filter" :
- rules.replace.0.pattern: Expression régulière non valide
- match.commands: ne doit pas être vide

Pour valider tous les filtres installés, appelez runRtkFilterTests(), qui est exportée depuis open-sse/services/compression/engines/rtk/verify.ts.

  1. Incluez toujours tests[] — ils prouvent que votre filtre fonctionne et évitent les régressions
  2. Utilisez matchOutput pour les sorties anticipées — si une seule ligne suffit à résumer la situation, remplacez le bloc entier
  3. Préférez keep à strip — les règles explicites « toujours conserver » sont plus sûres que « toujours supprimer »
  4. Testez les 3 niveaux d’intensité — minimal ne devrait produire aucun effet, tandis que aggressive devrait tout de même préserver les erreurs
  5. Utilisez le champ unless — protégez les sorties anticipées avec une condition « ne pas déclencher si X est présent »

Récupération de la sortie brute et étape de vérification

Section intitulée « Récupération de la sortie brute et étape de vérification »

Lorsque RTK compresse la sortie de manière agressive, vous pouvez récupérer le texte d’origine à des fins de débogage, d’audit ou de relecture.

Fonctionnement de la récupération de la sortie brute

Section intitulée « Fonctionnement de la récupération de la sortie brute »
Sortie d’origine (10K jetons)
│
▼
Compression RTK (avec rawOutput.enabled=true)
│
├─▶ Sortie compressée (2K jetons) ──▶ vers le LLM
│
└─▶ Sortie d’origine (10K jetons) ──▶ stockée dans la BDD
(liée par request_id)

Par requête (dans la configuration combinée) :

{
"compression": {
"engine": "rtk",
"intensity": "aggressive",
"rawOutput": {
"enabled": true,
"maxBytes": 1048576 // Plafond de 1 Mo
}
}
}

Valeur par défaut : rawOutput.enabled: false (économise de l’espace de stockage).

Par requête Plafond de 1 Mo Plafond de 10 Mo
Sortie compressée moyenne ~5 Ko ~5 Ko
Sortie brute stockée ~50-500 Ko ~500 Ko-5 Mo
Avec 1 000 requêtes/jour 50-500 Mo/jour 500 Mo-5 Go/jour

Recommandation : activez uniquement la sortie brute pour les sessions de débogage ou les audits par échantillonnage, et non en permanence.

import { readRtkRawOutput } from "omniroute/compression/engines/rtk/rawOutput";
const raw = readRtkRawOutput(pointerId); // pointerId provenant des statistiques de compression
if (raw) {
console.log("Original output:", raw);
}

Le pointerId est renvoyé dans CompressionStats.rtkRawOutputPointers[] après la compression. Consultez open-sse/services/compression/engines/rtk/rawOutput.ts:102 pour connaître la signature de la fonction.

La vérification des filtres RTK (open-sse/services/compression/engines/rtk/verify.ts) valide tous les filtres par rapport à leurs tests[] et garantit que leur comportement est correct pour les 3 niveaux d’intensité.

Appelez runRtkFilterTests() pour exécuter la vérification :

import { runRtkFilterTests } from "open-sse/services/compression/engines/rtk/verify";
const result = runRtkFilterTests();
console.log(`Passed: ${result.outcomes.filter((o) => o.passed).length}`);
console.log(`Failed: ${result.outcomes.filter((o) => !o.passed).length}`);
if (!result.passed) {
console.error("Filters failed verification");
result.outcomes
.filter((o) => !o.passed)
.forEach((o) => {
console.error(
` - ${o.filterId} / ${o.testName}: expected "${o.expected}", got "${o.actual}"`
);
});
}

Éléments validés :

  1. Chaque filtre se charge et réussit la validation du schéma
  2. Chaque entrée de tests[] produit la sortie attendue
  3. L’intensité minimal est sans effet (elle préserve l’original et applique uniquement les filtres structurels)
  4. L’intensité aggressive préserve les erreurs, les échecs de tests et les traces de pile
  5. La sortie compressée n’est jamais plus volumineuse que l’entrée d’origine
  • Source : open-sse/services/compression/engines/rtk/ (63 fichiers, ~70 Ko)

  • Avant de fusionner une modification de filtre — vérifiez toujours que les tests réussissent

  • Après la mise à niveau du moteur RTK — le schéma peut avoir changé

  • Périodiquement dans le cadre de la surveillance — protège contre la dérive des jeux de données de test

  • Lors de l’ajout d’une nouvelle famille d’outils/commandes — prouve que le nouveau filtre fonctionne



Code source d’OmniRoute (a58000c7685f)

HagiCode

HagiCode est un espace de développement agentique qui associe workflows structurés, exécution multi-agent et vues Hero Dungeon.

Transformez vos idées en logiciels utiles grâce à un workflow agentique plus intelligent, rapide et agréable.

Interface principale de HagiCode en thème clair
  • SmartDes workflows structurés transforment une intention en parcours exécutable, de l’idée à la livraison.
  • EfficientLes workflows multi-agents font avancer recherche, réalisation et revue en parallèle.
  • FunHero Dungeon rend les longues sessions de code plus visuelles et collaboratives.
Visiter HagiCode