{"meta":{"title":"Orientation et mise en file d'attente","intro":"Deux modes d’interaction permettent aux utilisateurs d’envoyer des messages alors que l’agent est déjà en cours d’exécution : pilotage redirige l’agent en cours de tour, et mise en file d’attente place les messages en tampon pour un traitement séquentiel une fois le tour en cours terminé.","product":"GitHub Copilot","breadcrumbs":[{"href":"/fr/copilot","title":"GitHub Copilot"},{"href":"/fr/copilot/how-tos","title":"Procédures"},{"href":"/fr/copilot/how-tos/copilot-sdk","title":"Kit de développement logiciel (SDK) Copilot"},{"href":"/fr/copilot/how-tos/copilot-sdk/features","title":"Fonctionnalités"},{"href":"/fr/copilot/how-tos/copilot-sdk/features/steering-and-queueing","title":"Direction et file d’attente"}],"documentType":"article"},"body":"# Orientation et mise en file d'attente\n\nDeux modes d’interaction permettent aux utilisateurs d’envoyer des messages alors que l’agent est déjà en cours d’exécution : pilotage redirige l’agent en cours de tour, et mise en file d’attente place les messages en tampon pour un traitement séquentiel une fois le tour en cours terminé.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n## Overview\n\nLorsqu’une session traite activement un tour, les messages entrants peuvent être remis dans l’un des deux modes via le `mode` champ sur `MessageOptions`:\n\n| Mode                                 | Behavior                                                            | Cas d’utilisation                                                       |\n| ------------------------------------ | ------------------------------------------------------------------- | ----------------------------------------------------------------------- |\n| `\"immediate\"` (direction)            | Injecté dans le tour **actuel** du LLM                              | « En fait, ne créez pas ce fichier , utilisez une approche différente » |\n| `\"enqueue\"` (mise en file d’attente) | Mis en file d’attente et traité **une fois** le tour actuel terminé | « Après cela, corrigez également les tests »                            |\n\n![Diagramme : diagramme de séquence montrant le processus décrit.](/assets/images/help/copilot/copilot-sdk/features-steering-and-queueing-diagram-0.png)\n\n## Direction (mode immédiat)\n\nLe pilotage envoie un message qui est injecté directement dans le tour actuel de l’assistant. Il est utile pour corriger la trajectoire sans interrompre l'échange ; l'agent voit le message en temps réel et ajuste sa réponse en conséquence.\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nawait client.start();\n\nconst session = await client.createSession({\n    model: \"gpt-5.4\",\n    onPermissionRequest: async () => ({ kind: \"approve-once\" }),\n});\n\n// Start a long-running task\nconst msgId = await session.send({\n    prompt: \"Refactor the authentication module to use sessions\",\n});\n\n// While the agent is working, steer it\nawait session.send({\n    prompt: \"Actually, use JWT tokens instead of sessions\",\n    mode: \"immediate\",\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient, PermissionDecisionApproveOnce\n\nasync def main():\n    client = CopilotClient()\n    await client.start()\n\n    session = await client.create_session(\n        on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),\n        model=\"gpt-5.4\",\n    )\n\n    # Start a long-running task\n    msg_id = await session.send(\n        \"Refactor the authentication module to use sessions\",\n    )\n\n    # While the agent is working, steer it\n    await session.send(\n        \"Actually, use JWT tokens instead of sessions\",\n        mode=\"immediate\",\n    )\n\n    await client.stop()\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    if err := client.Start(ctx); err != nil {\n        log.Fatal(err)\n    }\n    defer client.Stop()\n\n    session, err := client.CreateSession(ctx, &copilot.SessionConfig{\n        Model: \"gpt-5.4\",\n        OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {\n            return &rpc.PermissionDecisionApproveOnce{}, nil\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Start a long-running task\n    _, err = session.Send(ctx, copilot.MessageOptions{\n        Prompt: \"Refactor the authentication module to use sessions\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // While the agent is working, steer it\n    _, err = session.Send(ctx, copilot.MessageOptions{\n        Prompt: \"Actually, use JWT tokens instead of sessions\",\n        Mode:   \"immediate\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\nusing GitHub.Copilot.Rpc;\n\nawait using var client = new CopilotClient();\nawait using var session = await client.CreateSessionAsync(new SessionConfig\n{\n    Model = \"gpt-5.4\",\n    OnPermissionRequest = (req, inv) =>\n        Task.FromResult(PermissionDecision.ApproveOnce()),\n});\n\n// Start a long-running task\nvar msgId = await session.SendAsync(new MessageOptions\n{\n    Prompt = \"Refactor the authentication module to use sessions\"\n});\n\n// While the agent is working, steer it\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Actually, use JWT tokens instead of sessions\",\n    Mode = \"immediate\"\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.*;\n\ntry (var client = new CopilotClient()) {\n    client.start().get();\n\n    var session = client.createSession(\n        new SessionConfig()\n            .setModel(\"gpt-5.4\")\n            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n    ).get();\n\n    // Start a long-running task\n    session.send(new MessageOptions()\n        .setPrompt(\"Refactor the authentication module to use sessions\")\n    ).get();\n\n    // While the agent is working, steer it\n    session.send(new MessageOptions()\n        .setPrompt(\"Actually, use JWT tokens instead of sessions\")\n        .setMode(\"immediate\")\n    ).get();\n}\n```\n\n</div>\n\n</div>\n\n### Fonctionnement interne de la direction\n\n1. Le message est ajouté à la file d’attente du `ImmediatePromptProcessor` runtime\n2. Avant la requête LLM suivante au sein du tour actuel, le processeur injecte le message dans la conversation\n3. L’agent voit le message de direction en tant que nouveau message utilisateur et ajuste sa réponse\n4. Si le tour se termine avant le traitement du message de direction, il est automatiquement déplacé vers la file d’attente normale pour le prochain tour\n\n> \\[!NOTE]\n> Les messages de pilotage sont traités au mieux pendant le tour en cours. Si l’assistant s’est déjà engagé dans un appel d’outil, le pilotage prend effet après l’achèvement de cet appel, mais toujours dans le même tour.\n\n## Mise en file d’attente (mode d’enfilement)\n\nLa mise en file d’attente stocke les messages pour qu’ils soient traités séquentiellement après la fin du tour en cours. Chaque message mis en file d’attente démarre son propre tour complet. Il s’agit du mode par défaut : si vous omettez `mode`, le Kit de développement logiciel (SDK) utilise `\"enqueue\"`.\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nawait client.start();\n\nconst session = await client.createSession({\n    model: \"gpt-5.4\",\n    onPermissionRequest: async () => ({ kind: \"approve-once\" }),\n});\n\n// Send an initial task\nawait session.send({ prompt: \"Set up the project structure\" });\n\n// Queue follow-up tasks while the agent is busy\nawait session.send({\n    prompt: \"Add unit tests for the auth module\",\n    mode: \"enqueue\",\n});\n\nawait session.send({\n    prompt: \"Update the README with setup instructions\",\n    mode: \"enqueue\",\n});\n\n// Messages are processed in FIFO order after each turn completes\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient, PermissionDecisionApproveOnce\n\nasync def main():\n    client = CopilotClient()\n    await client.start()\n\n    session = await client.create_session(\n        on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),\n        model=\"gpt-5.4\",\n    )\n\n    # Send an initial task\n    await session.send(\"Set up the project structure\")\n\n    # Queue follow-up tasks while the agent is busy\n    await session.send(\n        \"Add unit tests for the auth module\",\n        mode=\"enqueue\",\n    )\n\n    await session.send(\n        \"Update the README with setup instructions\",\n        mode=\"enqueue\",\n    )\n\n    # Messages are processed in FIFO order after each turn completes\n    await client.stop()\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\n// Send an initial task\nsession.Send(ctx, copilot.MessageOptions{\n    Prompt: \"Set up the project structure\",\n})\n\n// Queue follow-up tasks while the agent is busy\nsession.Send(ctx, copilot.MessageOptions{\n    Prompt: \"Add unit tests for the auth module\",\n    Mode:   \"enqueue\",\n})\n\nsession.Send(ctx, copilot.MessageOptions{\n    Prompt: \"Update the README with setup instructions\",\n    Mode:   \"enqueue\",\n})\n\n// Messages are processed in FIFO order after each turn completes\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\n// Send an initial task\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Set up the project structure\"\n});\n\n// Queue follow-up tasks while the agent is busy\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Add unit tests for the auth module\",\n    Mode = \"enqueue\"\n});\n\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Update the README with setup instructions\",\n    Mode = \"enqueue\"\n});\n\n// Messages are processed in FIFO order after each turn completes\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.*;\n\ntry (var client = new CopilotClient()) {\n    client.start().get();\n\n    var session = client.createSession(\n        new SessionConfig()\n            .setModel(\"gpt-5.4\")\n            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n    ).get();\n\n    // Send an initial task\n    session.send(new MessageOptions().setPrompt(\"Set up the project structure\")).get();\n\n    // Queue follow-up tasks while the agent is busy\n    session.send(new MessageOptions()\n        .setPrompt(\"Add unit tests for the auth module\")\n        .setMode(\"enqueue\")\n    ).get();\n\n    session.send(new MessageOptions()\n        .setPrompt(\"Update the README with setup instructions\")\n        .setMode(\"enqueue\")\n    ).get();\n\n    // Messages are processed in FIFO order after each turn completes\n}\n```\n\n</div>\n\n</div>\n\n### Fonctionnement interne de la mise en file d’attente\n\n1. Le message est ajouté à la session `itemQueue` en tant que `QueuedItem`\n2. Lorsque le tour actuel se termine et que la session devient inactive, `processQueuedItems()` s’exécute\n3. Les éléments sont mis en file d’attente dans l’ordre FIFO : chaque message déclenche un tour agentique complet\n4. Si un message de direction était en attente lorsque le tour s’est terminé, il est déplacé vers l’avant de la file d’attente\n5. Le traitement se poursuit jusqu’à ce que la file d’attente soit vide, puis la session émet un événement inactif\n\n## Combinaison du pilotage et de la file\n\nVous pouvez utiliser les deux modèles ensemble dans une seule session. Le pilotage affecte le tour en cours tandis que les messages en file d’attente attendent leur propre tour :\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nconst session = await client.createSession({\n    model: \"gpt-5.4\",\n    onPermissionRequest: async () => ({ kind: \"approve-once\" }),\n});\n\n// Start a task\nawait session.send({ prompt: \"Refactor the database layer\" });\n\n// Steer the current work\nawait session.send({\n    prompt: \"Make sure to keep backwards compatibility with the v1 API\",\n    mode: \"immediate\",\n});\n\n// Queue a follow-up for after this turn\nawait session.send({\n    prompt: \"Now add migration scripts for the schema changes\",\n    mode: \"enqueue\",\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nsession = await client.create_session(\n    on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),\n    model=\"gpt-5.4\",\n)\n\n# Start a task\nawait session.send(\"Refactor the database layer\")\n\n# Steer the current work\nawait session.send(\n    \"Make sure to keep backwards compatibility with the v1 API\",\n    mode=\"immediate\",\n)\n\n# Queue a follow-up for after this turn\nawait session.send(\n    \"Now add migration scripts for the schema changes\",\n    mode=\"enqueue\",\n)\n```\n\n</div>\n\n</div>\n\n## Choix entre la direction et la file d’attente\n\n| Scénario                                                            | Pattern                                                             | Pourquoi |\n| ------------------------------------------------------------------- | ------------------------------------------------------------------- | -------- |\n| L’agent prend le mauvais chemin                                     |                                                                     |          |\n| **Direction**                                                       | Redirige le tour actuel sans perdre de progression                  |          |\n| Vous avez pensé à quelque chose que l’agent devrait également faire |                                                                     |          |\n| **Mise en file d’attente**                                          | Ne perturbe pas le travail en cours ; s’exécute ensuite             |          |\n| L’agent est sur le point de faire une erreur                        |                                                                     |          |\n| **Direction**                                                       | Intervient avant que l’erreur ne soit commise                       |          |\n| Vous souhaitez chaîner plusieurs tâches                             |                                                                     |          |\n| **Mise en file d’attente**                                          | L’ordre FIFO garantit l’exécution prévisible                        |          |\n| Vous souhaitez ajouter un contexte à la tâche actuelle              |                                                                     |          |\n| **Direction**                                                       | Agent l’intègre dans son raisonnement actuel                        |          |\n| Vous souhaitez traiter des demandes non liées en lot                |                                                                     |          |\n| **Mise en file d’attente**                                          | Chacun bénéficie de son propre tour complet avec un contexte vierge |          |\n\n## Création d’une interface utilisateur avec pilotage et mise en file d’attente\n\nVoici un modèle permettant de créer une interface utilisateur interactive qui prend en charge les deux modes :\n\n```typescript\nimport { CopilotClient, CopilotSession } from \"@github/copilot-sdk\";\n\ninterface PendingMessage {\n    prompt: string;\n    mode: \"immediate\" | \"enqueue\";\n    sentAt: Date;\n}\n\nclass InteractiveChat {\n    private session: CopilotSession;\n    private isProcessing = false;\n    private pendingMessages: PendingMessage[] = [];\n\n    constructor(session: CopilotSession) {\n        this.session = session;\n\n        session.on((event) => {\n            if (event.type === \"session.idle\") {\n                this.isProcessing = false;\n                this.onIdle();\n            }\n            if (event.type === \"assistant.message\") {\n                this.renderMessage(event);\n            }\n        });\n    }\n\n    async sendMessage(prompt: string): Promise<void> {\n        if (!this.isProcessing) {\n            this.isProcessing = true;\n            await this.session.send({ prompt });\n            return;\n        }\n\n        // Session is busy — let the user choose how to deliver\n        // Your UI would present this choice (e.g., buttons, keyboard shortcuts)\n    }\n\n    async steer(prompt: string): Promise<void> {\n        this.pendingMessages.push({\n            prompt,\n            mode: \"immediate\",\n            sentAt: new Date(),\n        });\n        await this.session.send({ prompt, mode: \"immediate\" });\n    }\n\n    async enqueue(prompt: string): Promise<void> {\n        this.pendingMessages.push({\n            prompt,\n            mode: \"enqueue\",\n            sentAt: new Date(),\n        });\n        await this.session.send({ prompt, mode: \"enqueue\" });\n    }\n\n    private onIdle(): void {\n        this.pendingMessages = [];\n        // Update UI to show session is ready for new input\n    }\n\n    private renderMessage(event: unknown): void {\n        // Render assistant message in your UI\n    }\n}\n```\n\n## Référence d’API\n\n### Options de message\n\n| Language | Champ  | Catégorie                         | Par défaut  | Description                 |\n| -------- | ------ | --------------------------------- | ----------- | --------------------------- |\n| Node.js  | `mode` | `\"enqueue\" \\| \"immediate\"`        | `\"enqueue\"` | Mode de remise des messages |\n| Python   | `mode` | `Literal[\"enqueue\", \"immediate\"]` | `\"enqueue\"` | Mode de remise des messages |\n| Allez    | `Mode` | `string`                          | `\"enqueue\"` | Mode de remise des messages |\n| .NET     | `Mode` | `string?`                         | `\"enqueue\"` | Mode de remise des messages |\n\n### Modes de livraison\n\n| Mode          | Résultat                             | Pendant le tour actif              | Pendant l’inactivité                  |\n| ------------- | ------------------------------------ | ---------------------------------- | ------------------------------------- |\n| `\"enqueue\"`   | File d’attente pour le prochain tour | Attend dans la file d’attente FIFO | Démarre immédiatement un nouveau tour |\n| `\"immediate\"` | Injecter dans le tour en cours       | Injecté avant l’appel LLM suivant  | Démarre immédiatement un nouveau tour |\n\n> \\[!NOTE]\n> Lorsque la session est inactive (pas de traitement), les deux modes se comportent de la même façon : le message démarre immédiatement un nouveau tour.\n\n## Bonnes pratiques\n\n1. **Mise en file d’attente par défaut** : utilisez `\"enqueue\"` (ou omettez `mode`) pour la plupart des messages. Il est prévisible et ne risque pas de perturber les travaux en cours.\n\n2. **Réservez la direction pour les corrections** : utilisez `\"immediate\"` quand l’agent fait activement la mauvaise chose et que vous devez le rediriger avant d’aller plus loin.\n\n3. **Gardez les messages clairs et concis** : l’agent doit rapidement comprendre la correction du cap. Les messages de direction longs et complexes peuvent confondre le contexte actuel.\n\n4. **Évitez de surdiriger** : plusieurs messages de direction rapides peuvent dégrader la qualité du virage. Si vous devez changer de direction de manière significative, envisagez d’arrêter le tour et de commencer frais.\n\n5. **Afficher l’état de la file d’attente dans votre interface utilisateur** : affichez le nombre de messages mis en file d’attente afin que les utilisateurs sachent ce qui est en attente. Écoutez les événements d’inactivité pour effacer l’affichage.\n\n6. **Gérer le passage du pilotage à la file d’attente** — Si un message de pilotage arrive après la fin du tour, il est automatiquement déplacé dans la file d’attente. Concevez votre interface utilisateur pour refléter cette transition.\n\n## Voir aussi\n\n* [Créez votre première application avec Copilot](/fr/copilot/how-tos/copilot-sdk/getting-started) : Configurer une session et envoyer des messages\n* [Agents personnalisés et orchestration de sous-agents](/fr/copilot/how-tos/copilot-sdk/features/custom-agents) : Définir des agents spécialisés avec des outils délimités\n* [Hooks de session](/fr/copilot/how-tos/copilot-sdk/hooks/hooks-overview): Réagir aux événements du cycle de vie de la session\n* [Reprise de session et persistance](/fr/copilot/how-tos/copilot-sdk/features/session-persistence): Reprendre les sessions après redémarrage"}