Settings gains a second service button next to restart: stop every managed local model server and exit the gateway process (nothing is respawned; in Docker the restart policy decides). The SPA replaces itself with a static "gateway is off" screen since the API is gone. The restart button is relabeled "Restart everything" to say what it always did — the gateway re-execs itself and managed servers come back with it. Translated in all seven languages.
654 lines
38 KiB
JavaScript
Vendored
654 lines
38 KiB
JavaScript
Vendored
// French (fr) — same keys as en.js; missing keys fall back to English.
|
||
export default {
|
||
// brand / common
|
||
"brand.sub": "Gateway",
|
||
"common.loading": "Chargement…",
|
||
"common.save": "Enregistrer",
|
||
"common.saving": "Enregistrement…",
|
||
"common.cancel": "Annuler",
|
||
"common.add": "Ajouter",
|
||
"common.edit": "Modifier",
|
||
"common.delete": "Supprimer",
|
||
"common.close": "Fermer",
|
||
"common.test": "Tester",
|
||
"common.copy": "Copier",
|
||
"common.copied": "Copié",
|
||
"common.confirm": "Confirmer",
|
||
"common.none": "aucun",
|
||
"common.saved": "Enregistré",
|
||
"common.error": "Erreur",
|
||
"common.ok": "OK",
|
||
"common.refresh": "Actualiser",
|
||
"common.actions": "Actions",
|
||
"common.optional": "optionnel",
|
||
"common.search": "Rechercher",
|
||
"common.all": "tous",
|
||
|
||
// nav
|
||
"nav.dashboard": "Tableau de bord",
|
||
"nav.models": "Modèles",
|
||
"nav.routing": "Routage",
|
||
"nav.protocols": "Protocoles",
|
||
"nav.keys": "Clés API",
|
||
"nav.playground": "Bac à sable",
|
||
"nav.settings": "Paramètres",
|
||
"nav.foot": "Gateway · v{v}",
|
||
"nav.billing": "Clé routeur & facturation",
|
||
|
||
// topbar / status
|
||
"status.router": "Routeur",
|
||
"status.gateway": "Gateway",
|
||
"status.online": "en ligne",
|
||
"status.offline": "hors ligne",
|
||
"status.checking": "vérification…",
|
||
"status.noKey": "pas de clé",
|
||
"theme.toggle": "Thème",
|
||
"logout": "Déconnexion",
|
||
|
||
// login
|
||
"login.title": "allaigate Gateway",
|
||
"login.subtitle": "Saisissez le jeton administrateur pour gérer cette passerelle.",
|
||
"login.token": "Jeton admin",
|
||
"login.tokenPlaceholder": "coller le jeton admin",
|
||
"login.submit": "Ouvrir la console",
|
||
"login.hint": "Le jeton est affiché dans le log de la passerelle au démarrage, ou défini via [admin].token_env.",
|
||
"login.failed": "Jeton admin invalide.",
|
||
|
||
// dashboard
|
||
"dash.title": "Tableau de bord",
|
||
"dash.subtitle": "Trafic en direct, coûts et analyses de routage pour votre pool de modèles.",
|
||
"dash.range": "Période",
|
||
"dash.range.1h": "1h",
|
||
"dash.range.24h": "24h",
|
||
"dash.range.7d": "7j",
|
||
"dash.kpi.requests": "Requêtes",
|
||
"dash.kpi.tokens": "Tokens",
|
||
"dash.kpi.cost": "Coût",
|
||
"dash.kpi.latency": "Latence moy.",
|
||
"dash.kpi.success": "Taux de succès",
|
||
"dash.kpi.failovers": "Basculements",
|
||
"dash.series.title": "Requêtes dans le temps",
|
||
"dash.series.cost": "Coûts dans le temps",
|
||
"dash.series.empty": "Aucun trafic sur cette période.",
|
||
"dash.breakdown.title": "Répartition",
|
||
"dash.groupby.model": "par modèle",
|
||
"dash.groupby.tier": "par niveau",
|
||
"dash.groupby.label": "par tâche",
|
||
"dash.groupby.account": "par compte",
|
||
"dash.recent.title": "Requêtes récentes",
|
||
"dash.recent.empty": "Aucune requête enregistrée. Essayez le Bac à sable.",
|
||
"dash.col.time": "Heure",
|
||
"dash.col.model": "Modèle",
|
||
"dash.col.tier": "Niveau",
|
||
"dash.col.task": "Tâche",
|
||
"dash.col.tokens": "Tokens",
|
||
"dash.col.cost": "Coût",
|
||
"dash.col.latency": "Latence",
|
||
"dash.col.outcome": "Résultat",
|
||
"dash.col.requests": "Requêtes",
|
||
"dash.col.errors": "Erreurs",
|
||
"dash.health.title": "Santé",
|
||
"dash.health.reachable": "accessible",
|
||
"dash.health.unreachable": "inaccessible",
|
||
"dash.health.getKey": "Obtenir une clé routeur",
|
||
|
||
// models
|
||
"models.title": "Modèles",
|
||
"models.subtitle": "Votre pool de modèles — combinez modèles locaux économiques et API cloud.",
|
||
"models.add": "Ajouter un modèle",
|
||
"models.empty": "Aucun modèle. Ajoutez votre premier modèle pour commencer.",
|
||
"models.col.id": "ID",
|
||
"models.col.provider": "Fournisseur",
|
||
"models.col.model": "Modèle",
|
||
"models.col.tier": "Niveau de coût",
|
||
"models.col.key": "Clé",
|
||
"models.col.caps": "Capacités",
|
||
"models.col.price": "Prix (entrée/sortie)",
|
||
"models.probe": "Sonder",
|
||
"models.probe.ok": "Accessible ({ms} ms)",
|
||
"models.probe.fail": "Échec : {err}",
|
||
"models.form.addTitle": "Ajouter un modèle",
|
||
"models.form.editTitle": "Modifier le modèle",
|
||
"models.form.id": "ID",
|
||
"models.form.idHint": "Identifiant unique utilisé dans le routage, ex. local-qwen",
|
||
"models.form.provider": "Fournisseur",
|
||
"models.form.baseUrl": "URL de base",
|
||
"models.form.model": "Nom du modèle",
|
||
"models.form.kind": "Type",
|
||
"models.form.costTier": "Niveau de coût",
|
||
"models.form.priceIn": "Prix entrée ($/1M)",
|
||
"models.form.priceOut": "Prix sortie ($/1M)",
|
||
"models.form.apiKeyEnv": "Nom de la var. d'env. pour la clé",
|
||
"models.form.apiKeyEnvHint": "Nom de la variable d'env. ou du secret contenant la clé de ce fournisseur.",
|
||
"models.form.caps": "Capacités",
|
||
"models.form.secret": "Valeur secrète",
|
||
"models.form.secretStored": "stocké",
|
||
"models.form.secretEnv": "depuis l'env.",
|
||
"models.form.secretMissing": "non défini",
|
||
"models.form.secretPlaceholder": "définir ou remplacer la clé (écriture seule)",
|
||
"models.deleteConfirm": "Supprimer le modèle \"{id}\" ?",
|
||
|
||
// routing
|
||
"routing.title": "Routage",
|
||
"routing.subtitle": "Associez les niveaux de complexité à une liste ordonnée de modèles (priorité = repli).",
|
||
"routing.default": "Modèle par défaut",
|
||
"routing.defaultHint": "Utilisé lorsque le routeur est inaccessible.",
|
||
"routing.tiers": "Niveaux",
|
||
"routing.tierHint": "Glissez les puces pour réordonner ; le premier est préféré, les autres sont des replis.",
|
||
"routing.addModel": "+ ajouter",
|
||
"routing.addTier": "Ajouter un niveau",
|
||
"routing.tierName": "Nom du niveau",
|
||
"routing.policy": "Politique",
|
||
"routing.policy.mode": "Mode",
|
||
"routing.policy.fixed": "Table fixe",
|
||
"routing.policy.costAware": "Sensible au coût",
|
||
"routing.policy.maxCost": "Coût max par requête ($)",
|
||
"routing.policy.minClass": "Classe minimale par niveau",
|
||
"routing.empty": "Aucun modèle disponible — ajoutez des modèles d'abord.",
|
||
|
||
// protocols
|
||
"protocols.title": "Protocoles",
|
||
"protocols.subtitle": "Activez uniquement les surfaces API entrantes nécessaires. Les bascules s'appliquent en direct.",
|
||
"protocols.implemented": "implémenté",
|
||
"protocols.planned": "planifié",
|
||
"protocols.openai_chat": "OpenAI Chat Completions",
|
||
"protocols.openai_chat.d": "POST /v1/chat/completions — compatible avec OpenAI SDK, LangChain, crewAI.",
|
||
"protocols.openai_completions": "OpenAI Completions (héritage)",
|
||
"protocols.openai_completions.d": "POST /v1/completions — intégrations héritées.",
|
||
"protocols.openai_embeddings": "OpenAI Embeddings",
|
||
"protocols.openai_embeddings.d": "POST /v1/embeddings — pipelines RAG.",
|
||
"protocols.openai_models": "OpenAI Models",
|
||
"protocols.openai_models.d": "GET /v1/models — découverte automatique des clients.",
|
||
"protocols.anthropic_messages": "Anthropic Messages",
|
||
"protocols.anthropic_messages.d": "POST /v1/messages — agents natifs Claude.",
|
||
"protocols.mcp": "MCP (Model Context Protocol)",
|
||
"protocols.mcp.d": "JSON-RPC / SSE — orchestrateurs natifs MCP.",
|
||
"protocols.native_passthrough": "Passage natif",
|
||
"protocols.native_passthrough.d": "POST /route — accès direct à la décision de routage.",
|
||
|
||
// keys
|
||
"keys.title": "Clés API",
|
||
"keys.subtitle": "Clés de passerelle virtuelles pour vos agents. Les clés fournisseurs ne quittent jamais la passerelle.",
|
||
"keys.add": "Nouvelle clé",
|
||
"keys.empty": "Aucune clé configurée — la passerelle est en mode ouvert (sans auth).",
|
||
"keys.openMode": "Mode ouvert : toute requête est acceptée (aucune clé requise).",
|
||
"keys.col.key": "Clé",
|
||
"keys.col.account": "Compte",
|
||
"keys.col.rate": "Débit / min",
|
||
"keys.col.models": "Modèles autorisés",
|
||
"keys.form.title": "Nouvelle clé API",
|
||
"keys.form.account": "Compte",
|
||
"keys.form.rate": "Limite de débit / min",
|
||
"keys.form.allow": "Modèles autorisés",
|
||
"keys.form.allowHint": "Laisser vide pour autoriser tous les modèles.",
|
||
"keys.form.custom": "Clé personnalisée (optionnel)",
|
||
"keys.form.customHint": "Laisser vide pour générer automatiquement sk-gw-…",
|
||
"keys.created": "Clé créée — copiez-la maintenant, elle ne sera plus affichée :",
|
||
"keys.revoke": "Révoquer",
|
||
"keys.revokeConfirm": "Révoquer cette clé ?",
|
||
"keys.allowAll": "tous",
|
||
|
||
// playground
|
||
"pg.title": "Bac à sable",
|
||
"pg.subtitle": "Envoyez une invite via le pipeline en direct et inspectez la décision de routage.",
|
||
"pg.system": "Invite système",
|
||
"pg.systemPlaceholder": "message système optionnel",
|
||
"pg.prompt": "Invite",
|
||
"pg.promptPlaceholder": "Posez une question…",
|
||
"pg.mode": "Mode",
|
||
"pg.mode.auto": "Auto (routage)",
|
||
"pg.mode.pinned": "Modèle épinglé",
|
||
"pg.profile": "Profil",
|
||
"pg.model": "Modèle",
|
||
"pg.temp": "Température",
|
||
"pg.maxTokens": "Tokens max",
|
||
"pg.send": "Envoyer",
|
||
"pg.stream": "Streaming",
|
||
"pg.sending": "Envoi…",
|
||
"pg.answer": "Réponse",
|
||
"pg.empty": "La réponse et la décision de routage s'afficheront ici.",
|
||
"pg.decision": "Décision de routage",
|
||
"pg.task": "Tâche",
|
||
"pg.tier": "Niveau",
|
||
"pg.score": "Complexité",
|
||
"pg.selected": "Modèle sélectionné",
|
||
"pg.source": "Source du routage",
|
||
"pg.cost": "Coût",
|
||
"pg.latency": "Latence",
|
||
"pg.tokens": "Tokens (entrée/sortie)",
|
||
"pg.failover": "Basculement",
|
||
"pg.error": "Requête échouée",
|
||
|
||
// settings
|
||
"settings.title": "Paramètres",
|
||
"settings.subtitle": "Connexion passerelle, entrée de routage, fiabilité et observabilité.",
|
||
"settings.router": "Connexion routeur",
|
||
"settings.router.url": "URL du routeur",
|
||
"settings.router.keyEnv": "Nom de l'env. pour la clé du routeur",
|
||
"settings.router.timeout": "Délai d'expiration (ms)",
|
||
"settings.router.verifyTls": "Vérifier le certificat TLS",
|
||
"settings.router.taxonomy": "ID de taxonomie",
|
||
"settings.router.getKey": "Obtenir ou recharger une clé routeur sur",
|
||
"settings.router.secret": "Clé routeur (valeur)",
|
||
"settings.router.test": "Tester le routeur",
|
||
"router.probe.ok": "Routeur OK ({ms} ms)",
|
||
"router.probe.noKey": "La clé routeur n'est pas définie",
|
||
"router.probe.auth": "Clé rejetée — invalide ou révoquée",
|
||
"router.probe.payment": "Paiement requis — forfait expiré ou quota épuisé",
|
||
"router.probe.quota": "Limite de débit dépassée",
|
||
"router.probe.timeout": "Délai du routeur dépassé",
|
||
"router.probe.unreachable": "Routeur inaccessible",
|
||
"router.probe.error": "Erreur du routeur",
|
||
"router.usage": "Consommation",
|
||
"settings.route": "Entrée de routage",
|
||
"settings.route.strategy": "Stratégie de texte",
|
||
"settings.route.maxChars": "Caractères max",
|
||
"settings.route.cacheTtl": "TTL du cache",
|
||
"settings.route.profile": "Profil par défaut",
|
||
"settings.breaker": "Disjoncteur",
|
||
"settings.breaker.threshold": "Seuil d'erreur",
|
||
"settings.breaker.cooldown": "Temporisation",
|
||
"settings.log": "Journalisation",
|
||
"settings.log.level": "Niveau de log",
|
||
"settings.log.bodies": "Journaliser les corps de messages (confidentialité désactivée)",
|
||
"settings.telemetry": "Télémétrie",
|
||
"settings.telemetry.metrics": "Exposer Prometheus /metrics",
|
||
"settings.cortiq": "Métadonnées de réponse",
|
||
"settings.cortiq.echo": "Inclure le bloc de routage cortiq dans les réponses",
|
||
"settings.stats": "Statistiques",
|
||
"settings.stats.enabled": "Enregistrer les statistiques de requêtes",
|
||
"settings.stats.file": "Fichier de stats (JSONL)",
|
||
"settings.stats.retention": "Rétention",
|
||
"settings.listen": "Adresse d'écoute",
|
||
"settings.export": "Exporter la config",
|
||
"settings.import": "Importer la config",
|
||
"settings.needsRestart": "Enregistré. Certains changements (adresse d'écoute) nécessitent un redémarrage.",
|
||
|
||
// toasts / misc
|
||
"toast.saved": "Modifications enregistrées",
|
||
"toast.deleted": "Supprimé",
|
||
"toast.probing": "Sondage…",
|
||
"toast.imported": "Config importée",
|
||
"dash.cache": "Cache sémantique",
|
||
"dash.cache.hitRate": "Taux de succès",
|
||
"dash.cache.hits": "Succès",
|
||
"dash.cache.saved": "Économisé",
|
||
"dash.cache.disabled": "Le cache sémantique est désactivé — activez-le dans les Paramètres.",
|
||
"settings.cache": "Cache sémantique",
|
||
"settings.cache.enabled": "Activer le cache sémantique",
|
||
"settings.cache.threshold": "Seuil de similarité",
|
||
"settings.cache.ttl": "TTL d'entrée",
|
||
"settings.cache.embed": "Modèle d'embeddings",
|
||
"settings.cache.note": "Les paramètres du cache prennent effet après un redémarrage.",
|
||
|
||
// ── translated from en.js (previously falling back to English) ──
|
||
// nav
|
||
"nav.import": "Importer un modèle",
|
||
|
||
// dash
|
||
"dash.clear": "Effacer les journaux",
|
||
"dash.clearConfirm": "Effacer toutes les statistiques et les journaux enregistrés ? Action irréversible.",
|
||
"dash.cleared": "Journaux effacés",
|
||
|
||
// models
|
||
"models.form.idOrModel": "Saisissez un identifiant ou un nom de modèle",
|
||
"models.form.apiKey": "Clé API",
|
||
"models.form.apiKeyPlaceholder": "collez votre clé API",
|
||
"models.form.apiKeyNotNeeded": "non requise (serveur local)",
|
||
"models.form.apiKeyHint": "Stockée de façon sécurisée sur la passerelle ; elle n'est plus affichée ensuite.",
|
||
"models.form.keyStored": "Une clé est enregistrée — laissez vide pour la conserver, ou collez-en une nouvelle.",
|
||
"models.form.keyFromEnv": "Une clé issue d'une variable d'environnement est utilisée.",
|
||
"models.form.paramsTitle": "Paramètres de génération et de raisonnement (O(1), MTP, température)",
|
||
"models.form.temperature": "Température",
|
||
"models.form.temperatureHint": "Température de génération (0.0 = déterministe, 1.0+ = créatif).",
|
||
"models.form.topP": "Top-P (échantillonnage nucleus)",
|
||
"models.form.topPHint": "Seuil d'échantillonnage (0.0 .. 1.0).",
|
||
"models.form.maxTokens": "Tokens max.",
|
||
"models.form.maxTokensHint": "Nombre maximal de tokens générés.",
|
||
"models.form.thinkBudget": "Mode raisonnement / budget de réflexion",
|
||
"models.form.thinkBudgetHint": "Budget de tokens de raisonnement (0 = désactivé, N > 0 = maximum de tokens de raisonnement).",
|
||
"models.form.systemPrompt": "Prompt système par défaut",
|
||
"models.form.systemPromptHint": "Ajouté automatiquement si la requête ne contient pas de prompt système.",
|
||
"models.form.systemPromptPlaceholder": "Vous êtes un assistant utile…",
|
||
"models.form.testKey": "Tester et charger les modèles",
|
||
"models.form.testing": "vérification…",
|
||
"models.form.foundModels": "{n} modèles chargés",
|
||
"models.form.modelPlaceholder": "tapez pour rechercher…",
|
||
"models.form.modelHint": "Cliquez sur « Tester et charger les modèles » pour récupérer la liste liée à votre clé, puis choisissez-en un.",
|
||
"models.managed": "géré",
|
||
"models.managedHint": "Fourni par le serveur CMF géré (Paramètres → Modèles locaux). Configurez-le là-bas.",
|
||
|
||
// settings
|
||
"settings.router.enabled": "Utiliser le routeur (désactivé = modèles locaux uniquement)",
|
||
"settings.cmf": "Modèles locaux (CMF)",
|
||
"settings.cmf.localOnly": "Utiliser uniquement les modèles locaux",
|
||
"settings.cmf.manage": "Lancer un serveur de modèle local",
|
||
"settings.cmf.autoInstall": "Installer cortiq automatiquement (crates.io)",
|
||
"settings.cmf.autoUpdate": "Mettre cortiq à jour automatiquement",
|
||
"settings.cmf.model": "Chemin du modèle .cmf local",
|
||
"settings.cmf.port": "Port du serveur local",
|
||
"settings.cmf.modelId": "Identifiant du modèle dans le pool",
|
||
"settings.cmf.note": "Sert un .cmf local via cortiq (github.com/infosave2007/cmf). Fonctionne même quand le routeur est indisponible.",
|
||
"settings.cmf.threads": "Threads de travail",
|
||
"settings.cmf.gpu": "Utiliser le GPU (Metal / wgpu)",
|
||
"settings.cmf.speedNote": "Les threads parallélisent les matvecs de décodage (~3× plus rapide ; 0 = valeur par défaut du runtime). Le déport GPU aide surtout au prefill des longs prompts — le décodage est limité par la bande passante mémoire, donc sur Apple Silicon l'effet est à peu près neutre.",
|
||
"settings.cmf.pick": "choisir un modèle",
|
||
"settings.cmf.models": "Modèles locaux",
|
||
"settings.cmf.modelsHelp": "Chaque ligne est un modèle que la passerelle exécute (son propre cortiq serve sur son propre port) et enregistre dans le pool. Ajoutez-en autant que vous avez de fichiers .cmf et de ports libres.",
|
||
"settings.cmf.rowHint": "id · fichier .cmf · port · threads · GPU. Les changements prennent effet au redémarrage ; supprimer une ligne arrête ce serveur.",
|
||
"settings.cmf.addServer": "+ Ajouter un modèle local",
|
||
"settings.cmf.checkPort": "Vérifier le port",
|
||
"settings.cmf.portFree": "port libre",
|
||
"settings.cmf.portBusy": "port occupé",
|
||
"settings.cmf.useSuggested": "utiliser {port}",
|
||
"settings.cmf.serving": "{model} servi sur :{port}",
|
||
"settings.cmf.intro": "Exécutez des modèles en local avec le moteur cortiq — fonctionne même hors ligne ou quand le routeur est en panne.",
|
||
"settings.cmf.runtime": "Runtime cortiq",
|
||
"settings.cmf.runtimeHelp": "L'outil en ligne de commande `cortiq` qui charge et exécute les modèles .cmf. Installez-le une fois avant de démarrer un serveur local.",
|
||
"settings.cmf.install": "Installer cortiq",
|
||
"settings.cmf.reinstall": "Réinstaller / mettre à jour",
|
||
"settings.cmf.installing": "installation… (compilation, quelques minutes)",
|
||
"settings.cmf.installedOk": "cortiq installé",
|
||
"settings.cmf.notInstalled": "non installé",
|
||
"settings.cmf.addModel": "Ajouter un modèle",
|
||
"settings.cmf.addModelHelp": "Les modèles se téléchargent et se convertissent dans l'onglet Importer (HuggingFace → .cmf). Faites ensuite pointer le serveur local vers le fichier .cmf ci-dessous.",
|
||
"settings.cmf.importNote": "Pas encore de modèle ? Importez-en un :",
|
||
"settings.cmf.importLink": "Ouvrir Importer",
|
||
"settings.cmf.modelHelp": "Chemin du fichier .cmf à servir (par ex. models/qwen.cmf), produit par l'onglet Importer. Plusieurs modèles pour des tâches différentes ? Importez-les et changez ce chemin.",
|
||
"settings.cmf.portHelp": "Port TCP sur lequel écoute le serveur de modèle local (8081 par défaut). À changer seulement en cas de conflit avec un autre service.",
|
||
"settings.cmf.threadsHelp": "Nombre de cœurs CPU utilisés pour la génération. Plus = plus rapide (~3× par rapport à un seul cœur) ; 0 laisse le runtime décider.",
|
||
"settings.cmf.gpuHelp": "Déporter les calculs matriciels sur le GPU (Metal/wgpu). Sur Apple Silicon, cela accélère surtout les longs prompts — le décodage est limité par la bande passante mémoire.",
|
||
"settings.cmf.localOnlyHelp": "Router chaque requête vers le modèle local, en ignorant le routeur et tous les fournisseurs cloud.",
|
||
"settings.cmf.manageHelp": "Au démarrage, la passerelle lance `cortiq serve` pour le .cmf ci-dessous et y route les requêtes. Nécessite cortiq installé (étape 1). Prend effet au redémarrage.",
|
||
"settings.cmf.autoInstallHelp": "Si cortiq est absent au démarrage, l'installer automatiquement depuis crates.io.",
|
||
"settings.cmf.autoUpdateHelp": "Au démarrage, mettre cortiq à niveau vers la dernière version si elle est plus récente.",
|
||
"settings.router.enabledHelp": "Laisser le routeur cortiq classer chaque requête (type de tâche + complexité) et choisir un modèle. Désactivé = utiliser uniquement la table de routage locale.",
|
||
"settings.router.verifyTlsHelp": "Vérifier le certificat TLS du routeur. À désactiver uniquement pour un certificat auto-signé ou lié à une IP.",
|
||
"settings.telemetry.metricsHelp": "Exposer les métriques Prometheus sur GET /metrics.",
|
||
"settings.cortiq.echoHelp": "Ajouter un champ `cortiq` (tâche, modèle, coût) au corps de chaque réponse. Les en-têtes de réponse sont toujours envoyés.",
|
||
"settings.stats.enabledHelp": "Enregistrer les requêtes récentes pour alimenter le tableau de bord et les graphiques.",
|
||
"settings.cache.enabledHelp": "Cache sémantique : renvoyer une réponse enregistrée quand un nouveau prompt ressemble beaucoup à un précédent, en évitant l'appel au modèle. Nécessite un modèle d'embedding dans le pool.",
|
||
"settings.log.bodiesHelp": "Journaliser le corps complet des messages de requête et de réponse. Désactivé par défaut pour la confidentialité.",
|
||
"settings.router.saveKey": "Enregistrer la clé",
|
||
"settings.router.keySaved": "Clé du routeur enregistrée",
|
||
"settings.router.keyEmpty": "Collez d'abord la clé",
|
||
"settings.router.secretHelp": "Collez la clé reçue par e-mail depuis api.allaigate.com, puis cliquez sur Enregistrer la clé. Ce n'est PAS une valeur de « Clés API » — celles-ci servent aux clients qui appellent votre passerelle.",
|
||
"settings.router.keyStoredMask": "•••••••••••• — clé enregistrée (recollez-en une pour la remplacer)",
|
||
"settings.route.strategyHelp": "Texte envoyé au routeur pour la classification : last_user = uniquement le dernier message utilisateur ; last_user_plus_system = dernier message utilisateur + prompt système ; concat_all = toute la conversation.",
|
||
"settings.route.maxCharsHelp": "Nombre maximal de caractères de ce texte envoyés au routeur (au-delà, il est tronqué). Plus = classification plus précise, mais appels au routeur plus lents et plus coûteux.",
|
||
"settings.route.cacheTtlHelp": "Durée de mise en cache d'une décision de routage pour une requête identique avant de réinterroger le routeur (par ex. 60s, 5m).",
|
||
"settings.route.profileHelp": "Profil de routage par défaut quand la requête n'en précise aucun : cost-saver (le moins cher), balanced ou quality-first (meilleur modèle). Influence le modèle choisi par le routeur.",
|
||
|
||
// import
|
||
"import.subtitle": "Cherchez sur HuggingFace, convertissez en .cmf local et servez-le.",
|
||
"import.searchPlaceholder": "Rechercher des modèles HuggingFace (par ex. qwen3, llama)…",
|
||
"import.searching": "Recherche…",
|
||
"import.noResults": "Aucun modèle trouvé.",
|
||
"import.configure": "Configurer la conversion",
|
||
"import.outName": "Nom de sortie",
|
||
"import.outNameHint": "Nom du fichier .cmf (lettres, chiffres, - et _).",
|
||
"import.quant": "Quantification",
|
||
"import.convert": "Convertir et charger",
|
||
"import.converting": "Conversion",
|
||
"import.started": "Conversion lancée",
|
||
"import.failed": "Échec de la conversion — voir le journal.",
|
||
"import.register": "Enregistrer comme modèle local",
|
||
"import.registered": "Enregistré sous « {id} ». Lancez cortiq-server pour le servir.",
|
||
"import.jobs": "Téléchargements et conversions",
|
||
"import.cancel": "Annuler",
|
||
"import.cancelling": "Annulation — nettoyage du fichier incomplet…",
|
||
"import.delete": "Supprimer",
|
||
"import.deleteConfirm": "Supprimer ce modèle et son fichier .cmf converti du disque ?",
|
||
"import.deleted": "Supprimé avec ses fichiers",
|
||
"import.state.running": "en cours",
|
||
"import.state.done": "terminé",
|
||
"import.state.error": "erreur",
|
||
"import.state.cancelled": "annulé",
|
||
"import.featuredTitle": "Modèles .cmf prêts à l'emploi",
|
||
"import.featuredSub": "Modèles .cmf déjà convertis du compte infosave sur HuggingFace — la liste est lue en direct, les nouveaux modèles apparaissent d'eux-mêmes.",
|
||
"import.readyCmfBadge": ".cmf prêt",
|
||
"import.directDownload": "Télécharger",
|
||
"import.q.q8_2f": "8 bits à deux champs (𝒲×θ) — recommandé : meilleur rapport qualité/taille.",
|
||
"import.q.q8_row": "8 bits par ligne — simple et robuste.",
|
||
"import.q.q4": "4 bits par bloc — le plus compact, qualité moindre.",
|
||
"import.q.q4_tiled": "4 bits en tuiles (Q4_TILED) — 1,66× plus rapide sur GPU Metal.",
|
||
"import.q.vbit": "Variable 3–8 bits — budget de bits par expert.",
|
||
"import.q.q1t": "Ternaire 1,58 bit (Q1T) — BitNet b1.58 avec valeurs aberrantes éparses.",
|
||
"import.q.q1s": "1 bit épars (Q1S) — base 1 bit avec valeurs aberrantes holographiques.",
|
||
"import.q.q1p": "1 bit PTQ (Q1P) — 1 bit avec diffusion d'erreur.",
|
||
"import.q.q1": "1 bit (Q1) — format purement binaire.",
|
||
"import.q.f16": "16 bits — sans quantification.",
|
||
"import.q.f32": "32 bits — pleine précision (fichier volumineux).",
|
||
"import.adv.title": "Paramètres avancés",
|
||
"import.adv.auto": "auto",
|
||
"import.adv.linearCore": "Cœur linéaire",
|
||
"import.adv.linearHint": "Comment les couches d'attention linéaire sont reportées ou fusionnées.",
|
||
"import.adv.nphase": "vmf_phase phases/tête",
|
||
"import.adv.vbitShape": "Forme du budget VBIT",
|
||
"import.adv.meanBits": "Bits moyens VBIT",
|
||
"import.adv.shard": "Taille max. des shards (Go)",
|
||
"import.adv.noShard": "pas de découpage",
|
||
"import.adv.skipMtp": "ignorer la tête MTP",
|
||
"import.adv.o1": "Attention O(1)",
|
||
"import.adv.o1Hint": "Attention en flux à mémoire constante : le cache KV est libéré après le prefill, la mémoire ne croît donc pas avec de longs contextes. Les poids restent identiques octet pour octet — seule une indication de chargement est enregistrée ; vous pouvez revenir en arrière à tout moment (servir avec --o1 off). Validé sur Qwen3-0.6B : toutes couches ≈ ×1,18 de perplexité.",
|
||
"import.adv.o1Off": "désactivé — attention exacte (par défaut)",
|
||
"import.adv.o1All": "all — convertir chaque couche softmax",
|
||
"import.adv.o1Deep": "deep N — seulement les N couches les plus profondes",
|
||
"import.adv.o1Custom": "personnalisé — liste explicite de couches",
|
||
"import.adv.o1DeepN": "N couches profondes",
|
||
"import.adv.o1Layers": "Couches (séparées par des virgules)",
|
||
"import.adv.o1mHint": "budget de landmarks (32 par défaut)",
|
||
"import.adv.o1windowHint": "largeur de la fenêtre exacte (128 par défaut)",
|
||
"import.adv.o1sinkHint": "clés sink exactes permanentes (4 par défaut)",
|
||
|
||
// onboarding
|
||
"onboarding.title": "Configuration initiale",
|
||
"onboarding.welcome": "Bienvenue dans Cortiq Gateway",
|
||
"onboarding.welcomeSub": "Choisissez votre langue — vous pourrez la changer à tout moment dans l'en-tête.",
|
||
"onboarding.next": "Suivant",
|
||
"onboarding.back": "Retour",
|
||
"onboarding.skip": "Passer pour l'instant",
|
||
"onboarding.skipSetup": "Passer",
|
||
"onboarding.finish": "Terminer la configuration",
|
||
"onboarding.featuredTitle": "Modèles prêts à l'emploi (en un clic)",
|
||
"onboarding.featuredSub": "Ce sont des modèles .cmf déjà convertis, publiés par infosave sur HuggingFace — il suffit de les télécharger, aucune conversion nécessaire. Choisissez-en un ou plusieurs pour démarrer immédiatement.",
|
||
"onboarding.download": "Télécharger",
|
||
"onboarding.hfTitle": "N'importe quel modèle HuggingFace — conversion automatique",
|
||
"onboarding.hfSub": "Cherchez un modèle, choisissez une quantification, et nous le convertissons automatiquement en .cmf. Aucune modification manuelle de la configuration.",
|
||
"onboarding.noJobs": "Aucun téléchargement pour l'instant.",
|
||
"onboarding.doneTitle": "Tout est prêt",
|
||
"onboarding.doneSub": "Les modèles téléchargés seront enregistrés automatiquement. Vous pourrez en ajouter d'autres dans Importer ou Modèles.",
|
||
"onboarding.doneHint": "« Terminer la configuration » connecte chaque téléchargement achevé comme modèle local, démarre son serveur .cmf et y dirige le routage. Tout cela reste modifiable ensuite dans Modèles.",
|
||
"onboarding.willRegister": "Seront connectés comme modèles locaux",
|
||
"onboarding.nothingToRegister": "Aucun téléchargement terminé — rien à connecter. Revenez à l'étape précédente pour choisir un modèle.",
|
||
"onboarding.registeredN": "{n} modèle(s) connecté(s) : {ids}",
|
||
"onboarding.runtimeMissing": "Le runtime cortiq n'est pas installé — installez-le dans Paramètres → Modèles locaux pour les servir.",
|
||
"onboarding.downloaded": "téléchargé",
|
||
"onboarding.update": "Mettre à jour",
|
||
"onboarding.deleteFile": "Supprimer le fichier .cmf du disque",
|
||
"onboarding.confirmDelete": "Supprimer « {id} » ? Le fichier .cmf sera retiré du disque.",
|
||
"onboarding.unregistered": "Également désenregistré : {ids}",
|
||
|
||
// playground: media generation + streaming metrics
|
||
"pg.tab.chat": "Chat",
|
||
"pg.tab.image": "Image",
|
||
"pg.tab.video": "Vidéo",
|
||
"pg.generate": "Générer",
|
||
"pg.generating": "Génération…",
|
||
"pg.genFailed": "Échec de la génération — voir le journal.",
|
||
"pg.result": "Résultat",
|
||
"pg.genMetrics": "Métriques de génération",
|
||
"pg.imagePromptPlaceholder": "un renard roux dans la neige au coucher du soleil, photoréaliste, fourrure détaillée",
|
||
"pg.videoPromptPlaceholder": "un corgi en toque de chef fait sauter une crêpe, grésillements et aboiement joyeux",
|
||
"pg.imageEmpty": "L'image générée apparaîtra ici.",
|
||
"pg.videoEmpty": "Le clip généré (avec le son) apparaîtra ici.",
|
||
"pg.width": "Largeur",
|
||
"pg.height": "Hauteur",
|
||
"pg.steps": "Étapes",
|
||
"pg.seed": "Seed",
|
||
"pg.randomSeed": "Seed aléatoire",
|
||
"pg.cfgHint": "Force du guidance ; ≤ 1 désactive le CFG et divise le travail par deux.",
|
||
"pg.frames": "Images",
|
||
"pg.framesHint": "À 24 fps ; arrondi à la grille du modèle.",
|
||
"pg.quality": "Qualité JPEG",
|
||
"pg.videoSizeHint": "Multiples de 32 ; le petit côté entraîné est 768.",
|
||
"pg.videoStepsHint": "La LoRA Turbo est entraînée pour 4 étapes.",
|
||
"pg.firstFrame": "Première image (optionnel)",
|
||
"pg.lastFrame": "Dernière image (optionnel)",
|
||
"pg.keyframeHint": "Transforme la génération en keyframe-to-video.",
|
||
"pg.resolution": "Résolution",
|
||
"pg.genTime": "Temps de génération",
|
||
"pg.timePerStep": "Par étape",
|
||
"pg.timePerFrame": "Par image",
|
||
"pg.fileSize": "Taille du fichier",
|
||
"pg.duration": "Durée",
|
||
"pg.play": "Lire",
|
||
"pg.noMediaModels": "Pas encore de modèle {kind} local. Téléchargez-en un (par ex. de la collection infosave) dans Importer :",
|
||
"pg.tokSpeed": "Vitesse",
|
||
"pg.ttft": "Premier token",
|
||
|
||
// ops: logs, system, notices, gallery, chat, snippets, bench
|
||
"nav.logs": "Journaux",
|
||
"logs.subtitle": "Journal récent de la passerelle — ce que montrerait le terminal.",
|
||
"logs.filterPlaceholder": "filtrer…",
|
||
"logs.pause": "Pause",
|
||
"logs.resume": "Reprendre",
|
||
"logs.empty": "Rien ne correspond.",
|
||
"notice.openAdmin": "La console est ouverte sans jeton et accessible depuis d'autres machines. Définissez un jeton si cette machine n'est pas privée.",
|
||
"notice.update": "Mise à jour disponible : v{v}.",
|
||
"dash.sys.title": "Système",
|
||
"dash.sys.cores": "cœurs",
|
||
"dash.sys.disk": "Disque (modèles)",
|
||
"dash.sys.free": "libre",
|
||
"dash.sys.gateway": "passerelle",
|
||
"fit.disk": "espace disque insuffisant",
|
||
"fit.diskTitle": "Le téléchargement dépasse l'espace libre du disque des modèles.",
|
||
"fit.ram": "risque de ne pas tenir en RAM",
|
||
"fit.ramTitle": "Le modèle approche ou dépasse la RAM de cette machine — il pourrait ne pas tourner.",
|
||
"pg.eta": "restant",
|
||
"pg.min": "min",
|
||
"pg.queued": "En file d'attente — position {n}. Démarre dès la fin de la génération en cours.",
|
||
"pg.gallery": "Générations récentes",
|
||
"pg.galDeleteConfirm": "Supprimer cette génération et ses fichiers ?",
|
||
"pg.clearChat": "Effacer",
|
||
"keys.snip.title": "Connecter votre application",
|
||
"keys.snip.hint": "Collez un de ces exemples dans votre projet — seul le espace réservé de la clé est à remplacer.",
|
||
"keys.snip.withKey": "Les exemples ci-dessous incluent la clé que vous venez de créer.",
|
||
"keys.snip.openMode": "Aucune clé API configurée — la passerelle accepte n'importe quelle valeur.",
|
||
"keys.snip.keyPh": "votre clé API",
|
||
"settings.restart": "Tout redémarrer",
|
||
"settings.restartConfirm": "Redémarrer la passerelle et tous les serveurs de modèles locaux ? Les requêtes en cours seront interrompues.",
|
||
"settings.restarting": "Redémarrage — la page se recharge dès que la passerelle revient…",
|
||
"settings.shutdown": "Tout arrêter et éteindre",
|
||
"settings.shutdownConfirm": "Arrêter tous les serveurs de modèles locaux et éteindre la passerelle ? L'API et ce panneau ne répondront plus tant que vous n'aurez pas relancé la passerelle.",
|
||
"settings.shutdownDone": "La passerelle est éteinte.",
|
||
"settings.shutdownHint": "Tous les serveurs de modèles locaux sont arrêtés et le processus est terminé. Relancez la passerelle sur le serveur pour retrouver le panneau.",
|
||
"bench.title": "Vitesse des modèles locaux",
|
||
"bench.hint": "Exécute `cortiq bench` sur cette machine — de vrais tok/s, un modèle à la fois.",
|
||
"bench.run": "Mesurer",
|
||
"bench.running": "mesure…",
|
||
"bench.failed": "échec",
|
||
"bench.none": "Pas encore de modèles de chat .cmf locaux.",
|
||
|
||
// task-based routing
|
||
"task.chitchat": "Bavardage",
|
||
"task.code": "Code",
|
||
"task.creative-writing": "Écriture créative",
|
||
"task.extraction": "Extraction de données",
|
||
"task.math": "Mathématiques",
|
||
"task.qa": "Questions-réponses",
|
||
"task.summarization": "Résumé",
|
||
"task.translation": "Traduction",
|
||
"routing.tasks.title": "Routage par tâche",
|
||
"routing.tasks.hint": "Les modèles d'une règle passent en premier pour leur tâche ; la chaîne par complexité reste en secours. Vide = complexité seule.",
|
||
"routing.tasks.inherit": "par complexité (aucune règle)",
|
||
"routing.tasks.share": "{p}% des requêtes (7 j)",
|
||
"routing.tasks.fromRouter": "étiquettes reçues du routeur",
|
||
"routing.tasks.builtin": "routeur injoignable — jeu d'étiquettes intégré",
|
||
"routing.tasks.addCustom": "Ajouter une tâche",
|
||
"routing.tasks.addPlaceholder": "étiquette personnalisée…",
|
||
|
||
// benchmark view
|
||
"nav.benchmark": "Benchmark",
|
||
"bm.title": "Benchmark",
|
||
"bm.subtitle": "Sondes de qualité et de vitesse via le pipeline en direct : réponses vérifiées par mots-clés, boucles détectées, tok/s et temps du premier token par modèle.",
|
||
"bm.models": "Modèles à tester",
|
||
"bm.quickMode": "Test rapide",
|
||
"bm.quickHint": "Le sous-ensemble rapide aux réponses courtes — environ une minute par modèle local.",
|
||
"bm.suiteInfo": "Suite intégrée : {q} tests rapides / {f} complets, plus les vôtres.",
|
||
"bm.run": "Lancer",
|
||
"bm.pickModel": "Choisissez au moins un modèle.",
|
||
"bm.testOf": "test {i} sur {n}",
|
||
"bm.results": "Résultats",
|
||
"bm.quick": "rapide",
|
||
"bm.test": "Test",
|
||
"bm.cellHint": "Cliquez sur une cellule pour voir la réponse complète.",
|
||
"bm.history": "Exécutions précédentes (stockées dans ce navigateur)",
|
||
"bm.custom": "Tests personnalisés",
|
||
"bm.customHint": "Prompt + mots-clés séparés par des virgules que la réponse doit contenir (| pour les synonymes). Stockés dans ce navigateur.",
|
||
"bm.promptPh": "prompt…",
|
||
"bm.checkPh": "mots-clés, séparés par des virgules",
|
||
"bm.addTest": "Ajouter un test",
|
||
"bm.emptyAnswer": "réponse vide",
|
||
"bm.loopDetected": "boucle détectée",
|
||
|
||
// benchmark: routing mode, cost, live
|
||
"bm.mode.routing": "Routage intelligent",
|
||
"bm.mode.models": "Modèles individuels",
|
||
"bm.mode.routingDesc": "La fonctionnalité clé du produit à l'épreuve : chaque sonde passe par cortiq-auto — vous voyez quelle tâche le routeur a détectée, quel modèle il a choisi, si cela correspond aux attentes et combien cela a coûté.",
|
||
"bm.mode.modelsDesc": "La même suite épinglée aux modèles choisis — comparez leur qualité, vitesse et coût en direct, sans passer par le routeur.",
|
||
"bm.answersOk": "réponses correctes",
|
||
"bm.classAcc": "classification des tâches",
|
||
"bm.modelDist": "Requêtes envoyées vers",
|
||
"bm.expectedLbl": "attendu :",
|
||
"bm.answer": "Réponse",
|
||
"bm.liveRunning": "en cours…",
|
||
"bm.spent": "dépensé",
|
||
"bm.verdict": "🏁 Terminé : réponses {p}, dépensé {s}",
|
||
"bm.clearHistory": "Tout effacer",
|
||
|
||
// harness auto-setup (API keys view)
|
||
"keys.h.claude": "Claude Code — collez dans le terminal (la passerelle parle nativement le protocole Anthropic) :",
|
||
"keys.h.codex": "Codex — ajoute le fournisseur à ~/.codex/config.toml et démarre :",
|
||
"keys.h.opencode": "OpenCode — écrit ~/.config/opencode/opencode.json (écrase !) et démarre :",
|
||
"keys.h.continue": "Continue (VS Code / JetBrains) — ajoute le modèle à ~/.continue/config.yaml :",
|
||
"keys.h.cline1": "Cline (VS Code) — dans les réglages de l'extension, choisissez :",
|
||
"keys.h.cline2": "Réglages → API Provider → OpenAI Compatible, puis collez les valeurs ci-dessus.",
|
||
"keys.h.note": "cortiq-auto = routage intelligent : le routeur choisit le modèle à chaque requête. Pour en fixer un, indiquez son nom exact. Sous Windows, lancez les scripts dans Git Bash / WSL ou définissez les mêmes variables via l'environnement système.",
|
||
"keys.h.protoOff": "Le protocole Anthropic (/v1/messages) est désactivé — Claude Code ne pourra pas se connecter.",
|
||
"keys.h.enableProto": "Activer",
|
||
"keys.h.st.installed": "Installé sur la machine de la passerelle",
|
||
"keys.h.st.configured": "Déjà configuré pour cette passerelle",
|
||
"keys.h.st.notFound": "Introuvable sur la machine de la passerelle",
|
||
"bm.degraded": "routeur dégradé",
|
||
"bm.routerDegraded": "Le routeur n'a pas répondu à temps — la requête a suivi la chaîne de secours ; la classification n'est pas comptée.",
|
||
"bm.cutByCap": "budget épuisé en raisonnement — pas de réponse",
|
||
"shell.uiStale": "La passerelle a été mise à jour — cette page utilise une ancienne interface.",
|
||
"shell.reload": "Recharger",
|
||
"keys.col.requests": "Requêtes",
|
||
"keys.col.tokens": "Tokens in/out",
|
||
"keys.col.costAll": "$ au total",
|
||
"routing.tasks.tier": "Complexité",
|
||
"routing.tasks.tierAuto": "Auto (routeur)",
|
||
"routing.tasks.tierHint": "Quel modèle sert cette tâche à quelle complexité ; « toute » mène à tous les niveaux. L'ordre = ordre de repli. Un verdict high escalade toujours au-dessus des entrées « toute ».",
|
||
"routing.tasks.tierAny": "toute complexité",
|
||
"routing.tasks.addModel": "modèle",
|
||
"routing.bands.enable": "Mes limites de complexité",
|
||
"routing.bands.hint": "Faites glisser les poignées : où finit low et où commence high — elles se poussent l'une l'autre, les chiffres se mettent à jour en direct. Le score continu du routeur est re-découpé avec VOS limites ; décoché = les bandes du routeur.",
|
||
"tier.low": "facile",
|
||
"tier.medium": "moyen",
|
||
"tier.high": "difficile",
|
||
"bm.scoreHint": "Le score de complexité continu du routeur (0..1) — les curseurs de limites de la page Routage le découpent en niveaux.",
|
||
"settings.cache.noEmbed": "Le cache est activé mais n'a AUCUN modèle d'embedding — il ne fait rien. Ajoutez au pool un modèle avec kind = \"embedding\" (p. ex. OpenAI text-embedding) ou choisissez-en un ci-dessous.",
|
||
"settings.cache.entries": "entrées",
|
||
"settings.cache.hits": "hits",
|
||
"settings.cache.saved": "économisé",
|
||
"keys.form.budget": "Budget mensuel, $ (0 = illimité)",
|
||
"keys.form.budgetHint": "Quand les dépenses du mois dépassent le plafond, les requêtes sont rejetées avec 429 insufficient_quota.",
|
||
"keys.budgetOf": "budget {b}/mois",
|
||
"dash.kpi.orBalance": "Solde OpenRouter",
|
||
"keys.h.install": "Installer :",
|
||
"keys.snip.keyInputPh": "collez votre clé API",
|
||
"keys.snip.apply": "Insérer la clé",
|
||
};
|