Files
OmniRoute/docs/i18n/fr/docs/frameworks/CLOUD_AGENT.md
Diego Rodrigues de Sa e Souza 8feea123bb feat(docs): mirror every docs/ page in all 65 locales (#14106)
* feat(docs): mirror every docs/ page in all 65 locales

Extends the documentation mirrors from the 22-page core set (#13940) to
every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors
(6,208 new), language bars rewritten for the full locale list, state
adopted so the blocking drift gate now covers all 152 pages.

run-translation.mjs: an oversized block made only of table rows or list
items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is
cut at item boundaries and rejoined without a blank line — the single
16-40 KB request outlived the backend socket for verbose scripts. 48
older mirrors whose tables had lost rows were retranslated with --force.

* docs(i18n): refresh mirrors for the sources the base changed since the branch cut

Section-level retranslation of the 29 docs (and README.md) whose source
or mirrors moved on release/v3.8.51 during the run, then state adoption;
the drift gate is green again on the merged tree.
2026-09-18 13:16:46 -03:00

22 KiB
Raw Blame History

Cloud Agents (Français)

🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


Source de vérité : src/lib/cloudAgent/ et src/app/api/v1/agents/tasks/ Dernière mise à jour : 2026-06-28 — v3.8.40 (actualisation du frontmatter ; 4 agents, dont cursor-cloud)

OmniRoute orchestre des agents de codage tiers hébergés dans le cloud (Codex Cloud, Cursor, Devin, Jules) sous forme de tâches de longue durée. Chaque agent est encapsulé derrière une interface uniforme afin que les clients puissent envoyer un prompt + lURL dun dépôt et recevoir les résultats sans avoir à gérer les API propres à chaque fournisseur.

Une tâche Cloud Agent nest pas une complétion de chat classique. Il sagit dune unité de travail durable et en plusieurs étapes, qui peut prendre de quelques minutes à plusieurs heures, produire une Pull Request comme artefact et prendre en charge les messages de suivi ainsi que, chez certains fournisseurs, des étapes dapprobation du plan.

Cycle de vie d’une tâche Cloud Agent

Source : diagrams/cloud-agent-flow.mmd

Agents pris en charge

ID du fournisseur Classe Source URL de base en amont Approbation du plan
jules JulesAgent src/lib/cloudAgent/agents/jules.ts https://jules.googleapis.com/v1alpha Oui
devin DevinAgent src/lib/cloudAgent/agents/devin.ts https://api.devin.ai/v1 Oui
codex-cloud CodexCloudAgent src/lib/cloudAgent/agents/codex.ts https://api.openai.com/v1/codex/cloud Non (automatique)
cursor-cloud CursorCloudAgent src/lib/cloudAgent/agents/cursor.ts https://api.cursor.com/v0 Non (automatique)

Registre : src/lib/cloudAgent/registry.ts — exporte getAgent(providerId), getAvailableAgents() et isCloudAgentProvider(providerId). Le registre est un simple Record<string, CloudAgentBase> en mémoire, alimenté lors du chargement du module.

Architecture

Client (tableau de bord / CLI / API)
  → POST /api/v1/agents/tasks (authentification de gestion requise)
    → validation avec CreateCloudAgentTaskSchema (Zod)
    → registry.getAgent(providerId)
    → getCloudAgentCredentials(providerId)
      └─ récupère les données depuis getProviderConnections({ provider, isActive: true })
         (apiKey en premier, avec repli sur accessToken)
    → agent.createTask({ prompt, source, options }, credentials)
      └─ requête HTTP POST vers lAPI du fournisseur en amont
      └─ renvoie CloudAgentTask avec un id interne + externalId
    → insertCloudAgentTask(...) dans cloud_agent_tasks (SQLite)

Interrogation périodique (synchronisation différée lors de la lecture) :
  GET /api/v1/agents/tasks/[id]
    → getCloudAgentTaskById(id)
    → agent.getStatus(externalId, credentials)  // actualise le statut + les activités
    → updateCloudAgentTask(...) avec le nouveau statut, le résultat et completed_at
    → renvoie la tâche sérialisée

Interactions :
  POST /api/v1/agents/tasks/[id]  corps : { action: "approve" | "message" | "cancel" }
    → agent.approvePlan(externalId, credentials)        pour "approve"
    → agent.sendMessage(externalId, message, credentials) pour "message"
    → le statut passe à "cancelled"                     pour "cancel" (local uniquement)

La synchronisation est différée : le statut est actualisé depuis le service en amont à chaque appel à GET /tasks/[id]. Il nexiste aucun processus dinterrogation périodique en arrière-plan. Les tableaux de bord qui ont besoin dun état à jour doivent interroger le point de terminaison GET à un intervalle raisonnable.

Interface CloudAgentBase

Source : src/lib/cloudAgent/baseAgent.ts

export interface AgentCredentials {
  apiKey: string;
  baseUrl?: string;
}

export interface CreateTaskParams {
  prompt: string;
  source: CloudAgentSource;
  options: {
    autoCreatePr?: boolean;
    planApprovalRequired?: boolean;
    environment?: Record<string, string>;
  };
}

export interface GetStatusResult {
  status: CloudAgentStatus;
  externalId?: string;
  result?: CloudAgentResult;
  activities: CloudAgentActivity[];
  error?: string;
}

export abstract class CloudAgentBase {
  abstract readonly providerId: string;
  abstract readonly baseUrl: string;

  abstract createTask(p: CreateTaskParams, c: AgentCredentials): Promise<CloudAgentTask>;
  abstract getStatus(externalId: string, c: AgentCredentials): Promise<GetStatusResult>;
  abstract approvePlan(externalId: string, c: AgentCredentials): Promise<void>;
  abstract sendMessage(
    externalId: string,
    message: string,
    c: AgentCredentials
  ): Promise<CloudAgentActivity>;
  abstract listSources(
    c: AgentCredentials
  ): Promise<{ name: string; url: string; branch?: string }[]>;

  protected mapStatus(raw: string): CloudAgentStatus; // chaîne en amont heuristique → énumération
  protected generateTaskId(): string; // `task_<ts>_<rand>`
  protected generateActivityId(): string; // `act_<ts>_<rand>`
}

CodexCloudAgent.approvePlan lève intentionnellement une exception — Codex Cloud génère automatiquement les plans et ne comporte aucune étape d'approbation. CodexCloudAgent.listSources renvoie [].

CursorCloudAgent pilote les agents Background / Cloud de Cursor via son API REST officielle (api.cursor.com/v0) avec une clé d'API d'utilisateur ou de compte de service — l'alternative propriétaire plus sûre à la réutilisation de la session OAuth de l'IDE Cursor (fournisseur cursor, qui comporte un avertissement de risque de bannissement). Il s'agit d'un adaptateur REST simple (sans dépendance native @cursor/sdk). approvePlan lève une exception (les agents Cursor fonctionnent de manière autonome) ; listSources répertorie les dépôts accessibles avec la clé. Cursor renvoie des énumérations de statut en majuscules (CREATING/RUNNING/FINISHED/ERROR), explicitement mappées vers le CloudAgentStatus partagé. baseUrl peut être remplacée pour chaque identifiant afin que la version/le chemin de l'API puisse être corrigé sans modifier le code.

Types du domaine

Source : src/lib/cloudAgent/types.ts

export const CLOUD_AGENT_STATUS = {
  QUEUED: "queued",
  RUNNING: "running",
  AWAITING_APPROVAL: "awaiting_approval",
  COMPLETED: "completed",
  FAILED: "failed",
  CANCELLED: "cancelled",
} as const;

export interface CloudAgentSource {
  repoName: string;
  repoUrl: string; // doit être une URL valide
  branch?: string;
}

export interface CloudAgentResult {
  prUrl?: string;
  prNumber?: number;
  commitMessage?: string;
  diffUrl?: string;
  summary?: string;
  duration?: number; // secondes, entier positif
  cost?: number; // nombre à virgule flottante positif
}

export interface CloudAgentActivity {
  id: string;
  type: "plan" | "command" | "code_change" | "message" | "error" | "completion";
  content: string;
  timestamp: string; // ISO 8601
  metadata?: Record<string, unknown>;
}

export interface CloudAgentTask {
  id: string; // identifiant interne `task_...`
  providerId: "jules" | "devin" | "codex-cloud" | "cursor-cloud";
  externalId?: string; // identifiant du fournisseur en amont
  status: CloudAgentStatus;
  prompt: string; // 1..10000 caractères
  source: CloudAgentSource;
  options: {
    autoCreatePr?: boolean;
    planApprovalRequired?: boolean;
    environment?: Record<string, string>;
  };
  result?: CloudAgentResult;
  activities: CloudAgentActivity[];
  error?: string;
  createdAt: string;
  updatedAt: string;
  completedAt?: string;
}

Les schémas de validation (CreateCloudAgentTaskSchema, UpdateCloudAgentTaskSchema) sont exportés avec les types et sont utilisés par les gestionnaires de routes.

Base de données

Source : src/lib/cloudAgent/db.ts — la table est créée de manière différée via createCloudAgentTaskTable() (également appelée depuis src/lib/cloudAgent/index.ts lors de limportation du module).

CREATE TABLE IF NOT EXISTS cloud_agent_tasks (
  id           TEXT PRIMARY KEY,
  provider_id  TEXT NOT NULL,
  external_id  TEXT,
  status       TEXT NOT NULL DEFAULT 'queued',
  prompt       TEXT NOT NULL,
  source       TEXT NOT NULL,             -- JSON
  options      TEXT DEFAULT '{}',         -- JSON
  result       TEXT,                       -- JSON
  activities   TEXT DEFAULT '[]',          -- JSON
  error        TEXT,
  created_at   TEXT NOT NULL DEFAULT (datetime('now')),
  updated_at   TEXT NOT NULL DEFAULT (datetime('now')),
  completed_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_cloud_agent_tasks_provider ON cloud_agent_tasks(provider_id);
CREATE INDEX IF NOT EXISTS idx_cloud_agent_tasks_status   ON cloud_agent_tasks(status);
CREATE INDEX IF NOT EXISTS idx_cloud_agent_tasks_created  ON cloud_agent_tasks(created_at DESC);

updateCloudAgentTask applique une liste blanche de colonnes afin dempêcher les injections SQL : status, prompt, source, options, result, activities, error, completed_at. Toute autre clé dans la mise à jour partielle est ignorée silencieusement.

API REST — Cycle de vie des tâches

Authentification : Tous les points de terminaison /api/v1/agents/tasks* nécessitent une authentification de gestion (requireCloudAgentManagementAuth encapsule requireManagementAuth provenant de src/lib/api/requireManagementAuth). Cette règle est appliquée depuis le commit 588a0333 (« fix(auth): exiger lauthentification de gestion pour les API dagents et de délai de récupération »).

Méthode Chemin Objectif
OPTIONS /api/v1/agents/tasks Requête préliminaire CORS
GET /api/v1/agents/tasks Répertorier les tâches (filtres : provider, status, limit≤500)
POST /api/v1/agents/tasks Créer une tâche (transmise au fournisseur en amont + persistée)
DELETE /api/v1/agents/tasks?id=... Supprimer une tâche selon lidentifiant de requête (sans lannuler en amont)
OPTIONS /api/v1/agents/tasks/[id] Requête préliminaire CORS
GET /api/v1/agents/tasks/[id] Lire la tâche + synchroniser de manière différée son statut depuis le fournisseur en amont
POST /api/v1/agents/tasks/[id] Action : approve / message / cancel
DELETE /api/v1/agents/tasks/[id] Supprimer une tâche selon lidentifiant du chemin

Créer une tâche

curl -X POST http://localhost:20128/api/v1/agents/tasks \
  -H "Cookie: auth_token=..." \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "devin",
    "prompt": "Fix the bug in src/foo.ts where the parser returns null",
    "source": {
      "repoName": "user/repo",
      "repoUrl": "https://github.com/user/repo",
      "branch": "main"
    },
    "options": {
      "autoCreatePr": true,
      "planApprovalRequired": false
    }
  }'

Réponse 201 :

{
  "data": {
    "id": "task_1731512345678_abc123def",
    "providerId": "devin",
    "externalId": "session_xyz",
    "status": "queued",
    "prompt": "...",
    "source": { "repoName": "user/repo", "repoUrl": "...", "branch": "main" },
    "options": { "autoCreatePr": true },
    "createdAt": "2026-05-13T12:34:56.789Z"
  }
}

Approuver un plan

curl -X POST http://localhost:20128/api/v1/agents/tasks/<id> \
  -H "Cookie: auth_token=..." \
  -H "Content-Type: application/json" \
  -d '{"action":"approve"}'

Envoyer un message de suivi

curl -X POST http://localhost:20128/api/v1/agents/tasks/<id> \
  -d '{"action":"message","message":"Also add a unit test for the parser"}'

Annuler (statut local uniquement)

curl -X POST http://localhost:20128/api/v1/agents/tasks/<id> \
  -d '{"action":"cancel"}'

cancel définit status sur "cancelled" dans la base de données locale, mais nappelle pas le fournisseur en amont — aucune RPC dinterruption nexiste dans CloudAgentBase. Pour arrêter la facturation en amont, mettez fin à la tâche dans la propre console du fournisseur.

API REST — infrastructure des fournisseurs cloud

Ces points de terminaison auxiliaires sous src/app/api/cloud/ sont utilisés par les clients distants (la CLI, lapplication Electron ou les workers de synchronisation) pour lire les métadonnées de connexion des fournisseurs et résoudre les alias de modèles. Ils sont authentifiés avec une clé API standard (via validateApiKey), et non avec lauthentification dadministration utilisée par les points de terminaison des tâches.

Méthode Chemin Objectif
POST /api/cloud/auth Valider la clé API et renvoyer les métadonnées de connexion masquées ainsi que les alias de modèles
PUT /api/cloud/credentials/update Actualiser accessToken / refreshToken / expiresAt
POST /api/cloud/model/resolve Résoudre un alias de modèle en { provider, model }
GET /api/cloud/models/alias Répertorier tous les alias de modèles
PUT /api/cloud/models/alias Définir un alias de modèle (et le synchroniser automatiquement avec le cloud si cette option est activée)

/api/cloud/auth ne renvoie jamais les valeurs brutes de apiKey / accessToken / refreshToken. Il renvoie hasApiKey, hasAccessToken, hasRefreshToken ainsi quun aperçu masqué (maskedApiKey : les 4 premiers caractères + **** + les 4 derniers).

Résolution des identifiants

getCloudAgentCredentials(providerId) dans src/lib/cloudAgent/api.ts :

  1. Charge les connexions actives du fournisseur via getProviderConnections({ provider: providerId, isActive: true }).
  2. Pour chaque connexion, donne la priorité à apiKey (sans espaces superflus). Utilise accessToken à défaut.
  3. Renvoie le premier jeton non vide sous la forme { apiKey: token }.
  4. Renvoie null si aucun jeton utilisable nest trouvé — lAPI répond avec le code 400 et "Aucun identifiant actif configuré pour le fournisseur dagent cloud : <id>".

Cela signifie que les agents cloud réutilisent la même table de connexions de fournisseurs que les fournisseurs LLM classiques. Pour activer Jules, créez une connexion active avec provider: "jules" et une valeur apiKey renseignée.

Tableau de bord

Source : src/app/(dashboard)/dashboard/cloud-agents/page.tsx

Une page React "use client" qui :

  • Répertorie les tâches (interrogées périodiquement via GET /api/v1/agents/tasks).
  • Soumet de nouvelles tâches au moyen dun formulaire correspondant à CreateCloudAgentTaskSchema.
  • Affiche des badges détat (queued, running, awaiting_approval, completed, failed, cancelled) et restitue la chronologie activities[].
  • Affiche result.prUrl / commitMessage / summary lorsque status === "completed".

Intégration avec A2A

Les agents cloud peuvent être exposés en tant que compétences A2A en enregistrant une compétence A2A qui délègue son gestionnaire tasks/send à getAgent(...).createTask(...) et traduit les événements détat des tâches A2A vers le protocole JSON-RPC 2.0. Consultez A2A-SERVER.md.

Ajout dun nouvel agent cloud

  1. Créez src/lib/cloudAgent/agents/<name>.ts en étendant CloudAgentBase.
  2. Implémentez createTask, getStatus, approvePlan (ou levez une exception si non applicable), sendMessage, listSources. Utilisez this.mapStatus(...) pour normaliser les états.
  3. Enregistrez-le dans src/lib/cloudAgent/registry.ts sous un providerId stable.
  4. Étendez lunion de littéraux providerId dans src/lib/cloudAgent/types.ts (CloudAgentTask.providerId et CreateCloudAgentTaskSchema).
  5. Ajoutez le fournisseur à src/shared/constants/providers.ts sil nécessite un enregistrement de connexion. Les fournisseurs basés sur OAuth nécessitent également src/lib/oauth/providers/.
  6. Ajoutez des tests sous tests/unit/cloud-agent-*.test.ts.
  7. Mettez à jour ce document et la constante CLOUD_AGENTS du tableau de bord.

Configuration

Variable denvironnement Rôle
DATA_DIR Emplacement de la base de données SQLite contenant cloud_agent_tasks
JWT_SECRET Requis pour lauthentification de gestion sur les points de terminaison des tâches
API_KEY_SECRET Requis pour chiffrer au repos les identifiants de connexion aux fournisseurs

Il nexiste actuellement aucune variable denvironnement spécifique à Cloud-Agent — chaque secret réside dans la table provider_connections.

Voir aussi