Aller au contenu
omni

Mode serveur

ai serve expose le routeur sous forme d'API compatible OpenAI. Il utilise les mêmes connexions, clés, comptes, cooldowns et fallbacks que le CLI.

ai serve                       # http://127.0.0.1:8080/v1
ai serve --host 0.0.0.0 --port 9000 --max-concurrent 4 --timeout 600
ai serve keys [list | add NAME | remove NAME]

API d'administration

Désactivée par défaut. Configure un serveur en marche sans accès au shell.

ai serve admin-keys add ops                    # clé dédiée, affichée une seule fois
ai serve --enable-admin
curl -H "Authorization: Bearer omni-admin-..." http://127.0.0.1:8080/admin/health
Route Rôle
GET/PUT /admin/config Modèles, ordre de fallback (fallback_order) et routing
GET/POST /admin/keys, DELETE /admin/keys/{id} Clés des fournisseurs. L'id est openrouter ou openrouter.work
GET /admin/accounts Comptes, connexion et cooldown
GET/POST /admin/api-keys, DELETE /admin/api-keys/{nom} Clés des clients de /v1
GET /admin/health État du serveur
POST /admin/accounts/{compte}/login Démarre la connexion par abonnement : renvoie le lien et l'id de la tentative
POST /admin/accounts/{compte}/login/complete Termine la connexion
DELETE /admin/accounts/{compte}/login Annule, avec l'id dans X-Omni-Login-Attempt
  • Clés séparées : une clé de /v1 n'ouvre jamais /admin, et inversement. Sans clé d'administration, --enable-admin ne démarre pas.
  • Réseau : depuis l'extérieur de cette machine, HTTPS via un proxy inverse est exigé, et il doit définir X-Forwarded-Proto. --admin-allow-http désactive ce contrôle. Il évite seulement une exposition par erreur : quiconque atteint le port directement peut falsifier l'en-tête, donc gardez le port ouvert uniquement pour le proxy. Sous Docker, le port publié compte comme un accès externe.
  • Secrets : les réponses n'affichent que la fin des clés des fournisseurs. L'exception est la clé client tout juste créée, affichée une seule fois.
  • Champs protégés : le mode de permission, les chemins des binaires et config_dir renvoient 403.
  • Attention : cette clé peut activer les modèles payants (openrouter_paid) et remplacer les clés des fournisseurs. Sous Docker, utilisez SMART_AI_ADMIN=1.

Connexion par l'API. {compte} vaut primary et les autres comptes Claude, codex, cursor, grok, ou codex.NOM pour un compte supplémentaire. Une tentative dure 10 minutes et chaque compte en accepte une à la fois (409).

Outil Comment terminer
Claude Code Ouvrez le lien et envoyez {"attempt_id": "...", "code": "..."} avec le code obtenu
Codex, Grok Ouvrez le lien, saisissez le user_code et envoyez {"attempt_id": "..."}. La réponse est 202 jusqu'à la fin
Cursor Ouvrez le lien et envoyez {"attempt_id": "..."}. La réponse est 202 jusqu'à la fin

Antigravity et les outils à clé seule renvoient 400. Les codes et jetons n'apparaissent ni dans les réponses ni dans les logs. L'exception est user_code, qui doit être saisi dans le navigateur.

Écriture en parallèle

Dans les modes d'écriture, les requêtes s'exécutent en parallèle, jusqu'à --max-concurrent, sans toucher au dossier d'origine.

Dossier avec git Dossier sans git
Où il travaille Worktree sur une branche omni/<id>, depuis le dernier commit Copie du dossier, jusqu'à 1 Go
Résultat Commit sur la branche, indiquée dans X-Omni-Branch. Le merge vous revient Copie dans ~/.local/share/smart-ai/runs/, indiquée dans X-Omni-Copy
Continuer Envoyez X-Omni-Branch à la requête suivante Envoyez X-Omni-Copy à la requête suivante
Nettoyage Le worktree part à la fin. La branche reste jusqu'à sa suppression La copie reste jusqu'à sa suppression
  • Sans modification : une nouvelle branche ou copie est supprimée et l'en-tête est absent. En streaming, l'en-tête part au début et peut désigner quelque chose de supprimé.
  • Échec ou timeout : le travail fait est conservé, et l'en-tête accompagne la réponse d'erreur. Après un plantage du serveur, les modifications sont enregistrées au démarrage suivant.
  • Concurrence : deux requêtes sur la même branche ou copie reçoivent 409. Seules les branches omni/ peuvent être continuées.
  • File d'attente : au-delà de la limite, la requête attend jusqu'à --queue-wait secondes (60), avec jusqu'à --queue-size en file (16). Ensuite seulement, elle reçoit 429.
  • Limites : les modifications non validées et les fichiers ignorés par git, comme node_modules, ne sont pas dans le worktree. L'isolation couvre les fichiers : ports, bases de données et autres services utilisés par les commandes peuvent encore entrer en conflit, et une commande peut écrire hors du dossier. La mémoire compte aussi : chaque requête est un processus de CLI. Les commandes git du serveur lui-même n'exécutent ni les hooks ni core.fsmonitor du dépôt. Les filtres git, comme ceux de Git LFS, restent exécutés : ne servez que des dépôts de confiance.
ai serve work --workdir DOSSIER                # liste
ai serve work remove ID --workdir DOSSIER      # affiche ; avec --yes, supprime
ai serve work prune --older-than 30 --workdir DOSSIER  # aussi --merged ; avec --yes, supprime

Sans --yes, rien n'est supprimé. La commande n'atteint que les branches omni/ et les copies d'Omni. Un élément en cours d'utilisation, ou une copie modifiée il y a moins de 15 minutes, est conservé.

En tant que service

ai serve --install-service [--host H] [--port P] [--mode M] [--workdir DOSSIER]
ai serve --service-status
ai serve --uninstall-service

Démarre tout seul et redémarre en cas d'échec, avec launchd sur macOS et systemd utilisateur sur Linux. Sous Windows, dans les conteneurs et sous WSL sans systemd, la commande le signale et n'installe rien ; lancez ai serve manuellement.

  • Secrets : le fichier du service ne contient aucune clé. Sans clé enregistrée, l'installation en crée une et l'affiche une seule fois. Hors de 127.0.0.1, une clé enregistrée est exigée d'abord.
  • Environnement : seuls PATH et les dossiers d'Omni parviennent au service. Les clés présentes uniquement dans votre shell n'y parviennent pas : enregistrez-les avec ai --key. L'installation les liste, ainsi que les CLI introuvables.
  • Dossier et mode : par défaut plan, dans ~/.local/share/smart-ai/serve. --mode yolo et l'écrasement d'un fichier non généré par Omni exigent --yes.
  • Logs : ~/.cache/smart-ai/serve.log, avec rotation, et serve.out.log, vidé à chaque installation.
  • Linux : pour démarrer au boot sans session ouverte, lancez loginctl enable-linger $USER. L'installation le signale, mais ne le fait pas pour vous.
  • Mise à jour : ai --update redémarre le service. Sur les installations sans git, réinstallez le service ensuite.

Utiliser l'API

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="omni-...")
client.chat.completions.create(model="omni-auto", messages=[{"role": "user", "content": "Olá"}])

Au premier démarrage, le serveur crée une clé et ne l'affiche qu'une fois. Seul son hachage est conservé. Dans un conteneur, vous pouvez aussi définir SMART_AI_SERVER_KEY. Il n'existe pas de mode sans authentification.

Route Rôle
POST /v1/chat/completions Réponse complète ou streaming (SSE)
GET /v1/models omni-auto, qui utilise le routeur, et omni/<outil> pour chaque outil configuré
En-tête de réponse Signification
X-Omni-Provider Outil qui a répondu
X-Omni-Usage reported (fourni par le fournisseur) ou estimated (estimé). Absent en streaming
X-Omni-Ignored-Params Paramètres reçus et ignorés

Sécurité :

  • Par défaut, les outils s'exécutent en mode plan, dans un dossier temporaire, quelle que soit la valeur de SMART_AI_MODE.
  • Pour créer, modifier et lancer des commandes : ai serve --mode edits|auto|yolo --workdir DOSSIER. Le dossier est obligatoire et rien ne demande d'approbation. Chaque requête travaille isolée. Qui détient la clé peut modifier le dossier et, avec des commandes, atteindre les connexions des comptes.
  • La lecture seule n'empêche pas de lire les fichiers. Toute personne disposant de la clé peut demander à un outil de lire des fichiers de cette machine. Les MCP configurés peuvent aussi être disponibles. Traitez la clé comme un accès à votre compte.
  • La valeur par défaut est 127.0.0.1. Pour l'exposer sur un réseau, utilisez --host et HTTPS avec un proxy inverse.
  • Au-delà de la limite de connexions (128 ou plus selon le système), la réponse est 503. Le début de chaque demande doit arriver en 30 secondes maximum. En exposition publique, utilisez aussi les limites par origine du proxy.
  • Partager une instance revient à partager les mêmes comptes et abonnements. Vérifiez les conditions de chaque fournisseur.

Limitations :

  • Quand le mode du serveur refuse une action et que l'outil se termine en erreur, comme Grok, la réponse est 403 action_not_allowed.
  • temperature ne s'applique qu'à OpenRouter, DeepSeek et Grok via l'API. Les CLI l'ignorent, et elle apparaît dans X-Omni-Ignored-Params.
  • max_tokens est approximatif sur les CLI (environ 4 caractères par token).
  • usage est estimé lorsque le fournisseur ne le communique pas.
  • Chaque demande peut consommer beaucoup de quota, car les CLI d'agent chargent leur propre contexte. Sur Codex, un simple « OK » a utilisé environ 19 000 tokens en entrée.
  • Sur les CLI, le streaming livre la réponse d'un seul coup, à la fin. Seul OpenRouter envoie des morceaux pendant la génération, sauf si des données personnelles ont été masquées.
  • Le fallback est transparent jusqu'au premier morceau de la réponse. Si le fournisseur échoue ensuite, le client reçoit une erreur.
  • tools/function calling uniquement sur les fournisseurs d'API (OpenRouter, DeepSeek et Grok avec une clé). Le serveur n'exécute jamais les outils : l'appel revient à votre code. Les autres modèles renvoient 400, car les CLI d'agent ne peuvent pas rendre l'appel, sauf avec --tool-emulation. Avec omni-auto, l'ordre est OpenRouter, DeepSeek et Grok. Sur OpenRouter, sans openrouter_paid, uniquement les modèles gratuits. En streaming, l'appel arrive d'un seul coup, à la fin. Des arguments hors du schéma font essayer le fournisseur suivant ; seul le cœur de JSON Schema est vérifié (type, required, enum, properties, items, additionalProperties). functions (ancien format) renvoie 400.
  • Expérimental : ai serve --tool-emulation (SMART_AI_TOOL_EMULATION=1 sous Docker) émule tools sur Claude Code et le CLI Grok, avec leurs propres outils désactivés. Le modèle écrit l'appel en JSON, le serveur le vérifie et réessaie une fois, ce qui consomme plus de quota. Cela ne s'applique que sans fournisseur d'API. Codex et Cursor sont exclus, car leurs outils ne peuvent pas être désactivés. Le modèle peut se tromper plus souvent qu'en mode natif, les données personnelles ne sont pas masquées, et le contenu du client peut imiter le format.
  • Les images renvoient une erreur 400.
  • Le prompt parvient aux outils comme argument de ligne de commande : il est donc visible dans la liste des processus de la machine. La limite est de 100 Ko par demande.
  • Les profils Claude hérités, qui échangent le fichier d'identifiants, limitent le serveur à une demande à la fois.

Ce texte provient du README du projet. Voir l'original sur GitHub