{"meta":{"title":"Métriques d’utilisation et de facturation","intro":"Ce guide montre comment lire le nombre de jetons, l’utilisation de la fenêtre de contexte, le coût en crédits IA et le quota du compte dans une application utilisant SDK Copilot. Des exemples sont présentés pour TypeScript, Python, Go, .NET, Java et Rust.","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/usage-and-billing","title":"Utilisation et facturation"}],"documentType":"article"},"body":"# Métriques d’utilisation et de facturation\n\nCe guide montre comment lire le nombre de jetons, l’utilisation de la fenêtre de contexte, le coût en crédits IA et le quota du compte dans une application utilisant SDK Copilot. Des exemples sont présentés pour TypeScript, Python, Go, .NET, Java et Rust.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n> \\[!TIP]\n> Chaque exemple est fonctionnellement équivalent entre les langages. L’extrait TypeScript est déplié par défaut : sélectionnez votre langue dans les sections repliables pour voir la même logique dans le SDK correspondant.\n\n## Vue d’ensemble\n\nLe SDK expose les données d’utilisation par le biais de deux mécanismes complémentaires :\n\n* **Événements de session** : événements éphémères émis par l’environnement d’exécution au cours de l’exécution d’un tour. Abonnez-vous à ceux-ci pour obtenir des données en temps réel pour chaque appel d’API.\n* **Méthodes RPC** : appels de requête/réponse que vous effectuez à la demande. Utilisez-les pour obtenir un instantané des totaux cumulés ou consulter le quota du compte.\n\nLe tableau ci-dessous mappe chaque signal à l’API qui l’expose.\n\n| Signal                                                      | API                            | Scope     | Type |\n| ----------------------------------------------------------- | ------------------------------ | --------- | ---- |\n| Nombre de jetons par appel                                  |                                |           |      |\n| événement `assistant.usage`                                 | Session                        | Événement |      |\n| Utilisation de la fenêtre contextuelle                      |                                |           |      |\n| événement `session.usage_info`                              | Session                        | Événement |      |\n| Répartition des fenêtres contextuelles (à la demande)       | `session.metadata.contextInfo` | Session   | RPC  |\n| Totaux cumulés des crédits d’IA et des jetons               | `session.usage.getMetrics`     | Session   | RPC  |\n| Tarification des crédits IA par modèle                      | `models.list`                  | Serveur   | RPC  |\n| Interactions entre le quota du compte et la version premium | `account.getQuota`             | Serveur   | RPC  |\n\n> \\[!NOTE]\n> `session.usage.getMetrics`, `session.metadata.contextInfo`et `session.metadata.recomputeContextTokens` sont marqués expérimentaux dans la surface RPC générée. Dans .NET, ils émettent le diagnostic expérimental `GHCP001`, que vous supprimez avec `#pragma warning disable GHCP001` ou avec `<NoWarn>GHCP001</NoWarn>` au niveau du projet. Épinglez le Kit de développement logiciel (SDK) et le runtime cli Copilot si votre application en dépend.\n\nLes tableaux de champs ci-dessous répertorient uniquement les champs utilisés dans les exemples de cette page. La référence des champs complète et toujours à jour se compose des types du SDK générés ainsi que de [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events), qui est régénéré à partir du schéma CLI à chaque mise à jour des dépendances. Considérez-les comme la référence et cette page comme un guide pratique.\n\n## Nombre de jetons par appel\n\nL’événement `assistant.usage` est émis une fois pour chaque appel d’API de modèle à son tour (y compris les appels effectués par les sous-agents). Il indique le nombre de tokens et le multiplicateur de facturation pour cet appel uniquement.\n\nL’exemple ci-dessous utilise ces champs. Consultez [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events#assistantusage) pour obtenir la liste complète, notamment le cache, le raisonnement, la latence et les champs de suivi.\n\n| Champ          | Type     | Description                                            |\n| -------------- | -------- | ------------------------------------------------------ |\n| `model`        | `string` | Identificateur de modèle pour cet appel                |\n| `inputTokens`  | `number` | Jetons d’entrée consommés                              |\n| `outputTokens` | `number` | Jetons de sortie produits                              |\n| `cost`         | `number` | Multiplicateur de demande Premium appliqué à cet appel |\n\n> \\[!TIP]\n> `assistant.usage` est éphémère ; il est donc diffusé en direct, mais n’est pas rejoué lorsque vous reprenez une session. Pour lire les totaux cumulés a posteriori, appelez `session.usage.getMetrics` (voir [Crédits IA et totaux de jetons cumulés](#accumulated-ai-credit-and-token-totals)).\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\nsession.on(\"assistant.usage\", (event) => {\n    const { model, inputTokens, outputTokens, cost } = event.data;\n    console.log(\n        `${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,\n    );\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\ndef on_usage(event):\n    if event.type == SessionEventType.ASSISTANT_USAGE:\n        data = event.data\n        print(f\"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}\")\n\nsession.on(on_usage)\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\nsession.On(func(event copilot.SessionEvent) {\n    d, ok := event.Data.(*copilot.AssistantUsageData)\n    if !ok {\n        return\n    }\n    in, out, cost := int64(0), int64(0), float64(0)\n    if d.InputTokens != nil {\n        in = *d.InputTokens\n    }\n    if d.OutputTokens != nil {\n        out = *d.OutputTokens\n    }\n    if d.Cost != nil {\n        cost = *d.Cost\n    }\n    fmt.Printf(\"%s: in=%d out=%d cost=%g\\n\", d.Model, in, out, cost)\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\nsession.On<AssistantUsageEvent>(evt =>\n{\n    var data = evt.Data;\n    Console.WriteLine(\n        $\"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}\");\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<!-- docs-validate: skip -->\n\n```java\nsession.on(AssistantUsageEvent.class, event -> {\n    var data = event.getData();\n    long in = data.inputTokens() != null ? data.inputTokens() : 0;\n    long out = data.outputTokens() != null ? data.outputTokens() : 0;\n    double cost = data.cost() != null ? data.cost() : 0.0;\n    System.out.printf(\"%s: in=%d out=%d cost=%s%n\", data.model(), in, out, cost);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::session_events::AssistantUsageData;\n\nlet mut events = session.subscribe();\nwhile let Ok(event) = events.recv().await {\n    if event.event_type == \"assistant.usage\" {\n        if let Some(data) = event.typed_data::<AssistantUsageData>() {\n            println!(\n                \"{}: in={} out={} cost={}\",\n                data.model,\n                data.input_tokens.unwrap_or(0),\n                data.output_tokens.unwrap_or(0),\n                data.cost.unwrap_or(0.0),\n            );\n        }\n    }\n}\n```\n\n</div>\n\n</div>\n\n## Utilisation de la fenêtre contextuelle\n\nLes nombres de jetons vous indiquent ce que chaque appel a consommé. L’utilisation de la fenêtre de contexte vous indique à quel point la fenêtre de contexte du modèle est remplie actuellement, ce qui est utile pour afficher une barre de progression ou avertir l’utilisateur avant que le compactage automatique ne se déclenche.\n\n### Mises à jour en direct avec `session.usage_info`\n\nLe runtime émet un `session.usage_info` événement chaque fois que la taille de la fenêtre de contexte change. L’exemple utilise `currentTokens` et `tokenLimit`; consultez [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events#sessionusage_info) pour la charge utile complète.\n\n| Champ           | Type     | Description                                                    |\n| --------------- | -------- | -------------------------------------------------------------- |\n| `currentTokens` | `number` | Tokens actuellement dans la fenêtre de contexte                |\n| `tokenLimit`    | `number` | Nombre maximal de jetons pour la fenêtre de contexte du modèle |\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\nsession.on(\"session.usage_info\", (event) => {\n    const { currentTokens, tokenLimit } = event.data;\n    const pct = Math.round((currentTokens / tokenLimit) * 100);\n    console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);\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\ndef on_usage_info(event):\n    if event.type == SessionEventType.SESSION_USAGE_INFO:\n        data = event.data\n        pct = round(data.current_tokens / data.token_limit * 100)\n        print(f\"Context: {data.current_tokens}/{data.token_limit} ({pct}%)\")\n\nsession.on(on_usage_info)\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\nsession.On(func(event copilot.SessionEvent) {\n    d, ok := event.Data.(*copilot.SessionUsageInfoData)\n    if !ok {\n        return\n    }\n    pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)\n    fmt.Printf(\"Context: %d/%d (%d%%)\\n\", d.CurrentTokens, d.TokenLimit, pct)\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\nsession.On<SessionUsageInfoEvent>(evt =>\n{\n    var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);\n    Console.WriteLine($\"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)\");\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<!-- docs-validate: skip -->\n\n```java\nsession.on(SessionUsageInfoEvent.class, event -> {\n    var data = event.getData();\n    long pct = Math.round((double) data.currentTokens() / data.tokenLimit() * 100);\n    System.out.printf(\"Context: %d/%d (%d%%)%n\", data.currentTokens(), data.tokenLimit(), pct);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::session_events::SessionUsageInfoData;\n\nlet mut events = session.subscribe();\nwhile let Ok(event) = events.recv().await {\n    if event.event_type == \"session.usage_info\" {\n        if let Some(data) = event.typed_data::<SessionUsageInfoData>() {\n            let pct = (data.current_tokens as f64 / data.token_limit as f64 * 100.0) as i64;\n            println!(\"Context: {}/{} ({}%)\", data.current_tokens, data.token_limit, pct);\n        }\n    }\n}\n```\n\n</div>\n\n</div>\n\n### Décomposition à la demande avec `session.metadata.contextInfo`\n\nLes événements se déclenchent uniquement lorsque le contexte change. Pour lire la répartition actuelle à tout moment, par exemple, juste après avoir repris une session, appelez `session.metadata.contextInfo`. Passez `0` pour `promptTokenLimit` afin d’utiliser la valeur par défaut de l’environnement d’exécution ; passez `0` pour `outputTokenLimit` si la valeur est inconnue.\n\nLe `null` du résultat est `contextInfo` jusqu’à ce que la session ait été initialisée (l’invite système et les métadonnées de l’outil ont été mises en cache). Il décompose le total en `systemTokens`, `conversationTokens`et `toolDefinitionsTokens`, en même temps que le `promptTokenLimit`.\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 { contextInfo } = await session.rpc.metadata.contextInfo({\n    promptTokenLimit: 0,\n    outputTokenLimit: 0,\n});\n\nif (contextInfo) {\n    console.log(\n        `Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +\n            `(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,\n    );\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\nresult = await session.rpc.metadata.context_info(\n    MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)\n)\ninfo = result.context_info\n\nif info is not None:\n    print(\n        f\"Total {info.total_tokens}/{info.prompt_token_limit} \"\n        f\"(system={info.system_tokens}, conversation={info.conversation_tokens})\"\n    )\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\nresult, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{\n    PromptTokenLimit: 0,\n    OutputTokenLimit: 0,\n})\n\nif info := result.ContextInfo; info != nil {\n    fmt.Printf(\"Total %d/%d (system=%d, conversation=%d)\\n\",\n        info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)\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\nvar result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);\nvar info = result.ContextInfo;\n\nif (info is not null)\n{\n    Console.WriteLine(\n        $\"Total {info.TotalTokens}/{info.PromptTokenLimit} \" +\n        $\"(system={info.SystemTokens}, conversation={info.ConversationTokens})\");\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<!-- docs-validate: skip -->\n\n```java\nvar result = session.getRpc().metadata\n    .contextInfo(new SessionMetadataContextInfoParams(null, 0L, 0L, null))\n    .join();\nvar info = result.contextInfo();\n\nif (info != null) {\n    System.out.printf(\"Total %d/%d (system=%d, conversation=%d)%n\",\n        info.totalTokens(), info.promptTokenLimit(), info.systemTokens(), info.conversationTokens());\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::rpc::MetadataContextInfoRequest;\n\nlet result = session\n    .rpc()\n    .metadata()\n    .context_info(MetadataContextInfoRequest {\n        prompt_token_limit: 0,\n        output_token_limit: 0,\n        selected_model: None,\n    })\n    .await?;\n\nif let Some(info) = result.context_info {\n    println!(\n        \"Total {}/{} (system={}, conversation={})\",\n        info.total_tokens, info.prompt_token_limit, info.system_tokens, info.conversation_tokens,\n    );\n}\n```\n\n</div>\n\n</div>\n\n## Totaux cumulés des crédits d’IA et des jetons\n\n`session.usage.getMetrics` retourne les totaux cumulés de toute la session en un seul appel. C’est la façon la plus claire de consulter le coût en crédits IA, car elle agrège tous les appels à l’API (agent principal et sous-agents) pour vous.\n\nL’exemple utilise les champs ci-dessous. Le type généré `UsageGetMetricsResult` est la référence complète.\n\n| Champ                     | Type                          | Description                                                                                         |\n| ------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------- |\n| `totalNanoAiu`            | `number`                      | Coût en crédits IA sur l’ensemble de la session, en nano-unités d’IA                                |\n| `totalPremiumRequestCost` | `number`                      | Coût de la demande Premium sur tous les modèles, après les multiplicateurs                          |\n| `modelMetrics`            | `Record<string, ModelMetric>` | Répartition par modèle ; chaque entrée a `usage.inputTokens`, `usage.outputTokens`et `totalNanoAiu` |\n\n> \\[!NOTE]\n> Le coût est signalé dans les **unités nano-IA** (le champ est nommé `totalNanoAiu`). La conversion exacte en crédits d’IA et la signification exacte du décompte des requêtes premium sont définies par la facturation de GitHub Copilot, et non par le SDK ; considérez la [documentation de facturation de GitHub Copilot](/fr/copilot/concepts/billing) comme la référence faisant foi et vérifiez-la avant d’afficher aux utilisateurs des valeurs assimilables à des montants. Les exemples divisent les valeurs par `1e9` par souci de simplicité, conformément au préfixe SI `nano` ; vérifiez que cela correspond à la facturation actuelle avant de vous y fier. Les mappages `modelMetrics` et `tokenDetails` ont pour clés des chaînes définies à l’exécution (identifiants de modèle et noms de types de jeton) que le système de types SDK ne valide pas.\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 metrics = await session.rpc.usage.getMetrics();\n\nconst aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;\nconsole.log(`AI credits used: ${aiCredits.toFixed(6)}`);\nconsole.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);\n\nfor (const [model, m] of Object.entries(metrics.modelMetrics)) {\n    if (!m) continue;\n    console.log(\n        `${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +\n            `nanoAiu=${m.totalNanoAiu ?? 0}`,\n    );\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\nmetrics = await session.rpc.usage.get_metrics()\n\nai_credits = (metrics.total_nano_aiu or 0) / 1e9\nprint(f\"AI credits used: {ai_credits:.6f}\")\nprint(f\"Premium requests: {metrics.total_premium_request_cost}\")\n\nfor model, m in metrics.model_metrics.items():\n    print(f\"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}\")\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\nmetrics, _ := session.RPC.Usage.GetMetrics(ctx)\n\naiCredits := float64(0)\nif metrics.TotalNanoAiu != nil {\n    aiCredits = *metrics.TotalNanoAiu / 1e9\n}\nfmt.Printf(\"AI credits used: %.6f\\n\", aiCredits)\nfmt.Printf(\"Premium requests: %v\\n\", metrics.TotalPremiumRequestCost)\n\nfor model, m := range metrics.ModelMetrics {\n    nanoAiu := float64(0)\n    if m.TotalNanoAiu != nil {\n        nanoAiu = *m.TotalNanoAiu\n    }\n    fmt.Printf(\"%s: in=%d out=%d nanoAiu=%v\\n\", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)\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\nvar metrics = await session.Rpc.Usage.GetMetricsAsync();\n\nvar aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;\nConsole.WriteLine($\"AI credits used: {aiCredits:F6}\");\nConsole.WriteLine($\"Premium requests: {metrics.TotalPremiumRequestCost}\");\n\nforeach (var (model, m) in metrics.ModelMetrics)\n{\n    Console.WriteLine(\n        $\"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}\");\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<!-- docs-validate: skip -->\n\n```java\nvar metrics = session.getRpc().usage.getMetrics().join();\n\ndouble aiCredits = metrics.totalNanoAiu() != null ? metrics.totalNanoAiu() / 1e9 : 0;\nSystem.out.printf(\"AI credits used: %.6f%n\", aiCredits);\nSystem.out.printf(\"Premium requests: %s%n\", metrics.totalPremiumRequestCost());\n\nmetrics.modelMetrics().forEach((model, m) -> {\n    double nanoAiu = m.totalNanoAiu() != null ? m.totalNanoAiu() : 0;\n    System.out.printf(\"%s: in=%d out=%d nanoAiu=%s%n\",\n        model, m.usage().inputTokens(), m.usage().outputTokens(), nanoAiu);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nlet metrics = session.rpc().usage().get_metrics().await?;\n\nlet ai_credits = metrics.total_nano_aiu.unwrap_or(0.0) / 1e9;\nprintln!(\"AI credits used: {ai_credits:.6}\");\nprintln!(\"Premium requests: {}\", metrics.total_premium_request_cost);\n\nfor (model, m) in &metrics.model_metrics {\n    let nano_aiu = m.total_nano_aiu.unwrap_or(0.0);\n    println!(\n        \"{model}: in={} out={} nanoAiu={nano_aiu}\",\n        m.usage.input_tokens, m.usage.output_tokens,\n    );\n}\n```\n\n</div>\n\n</div>\n\n## Tarification des crédits IA par modèle\n\nPour estimer le coût avant d’effectuer un tour, consultez le prix des jetons de chaque modèle dans `models.list`. Il s’agit d’un appel de portée serveur côté client, il ne nécessite donc pas de session. Les prix sont exprimés en crédits IA par lot de jetons facturé. Le type généré `ModelBillingTokenPrices` répertorie chaque champ, y compris `cachePrice`.\n\n| Champ                             | Type     | Description                                                              |\n| --------------------------------- | -------- | ------------------------------------------------------------------------ |\n| `billing.multiplier`              | `number` | Multiplicateur de coût de la demande Premium par rapport au taux de base |\n| `billing.tokenPrices.inputPrice`  | `number` | Coût de crédit IA par lot de jetons d’entrée                             |\n| `billing.tokenPrices.outputPrice` | `number` | Coût en crédits d’IA par lot de jetons de sortie                         |\n| `billing.tokenPrices.batchSize`   | `number` | Nombre de jetons par lot de facturation                                  |\n\n> \\[!NOTE]\n> Les valeurs de prix changent à mesure que les plans et les modèles évoluent. Lisez-les au moment de l’exécution, comme indiqué ci-dessous ; ne codez jamais en dur les nombres dans votre application.\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 { models } = await client.rpc.models.list({});\n\nfor (const model of models) {\n    const prices = model.billing?.tokenPrices;\n    if (!prices) continue;\n    console.log(\n        `${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +\n            `per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,\n    );\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\nresult = await client.rpc.models.list(ModelsListRequest())\n\nfor model in result.models:\n    prices = model.billing.token_prices if model.billing else None\n    if prices is None:\n        continue\n    multiplier = model.billing.multiplier if model.billing else 1\n    print(\n        f\"{model.id}: input={prices.input_price} output={prices.output_price} \"\n        f\"per {prices.batch_size} tokens (x{multiplier})\"\n    )\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\nlist, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})\n\nfor _, model := range list.Models {\n    if model.Billing == nil || model.Billing.TokenPrices == nil {\n        continue\n    }\n    prices := model.Billing.TokenPrices\n    multiplier := 1.0\n    if model.Billing.Multiplier != nil {\n        multiplier = *model.Billing.Multiplier\n    }\n    in, out := 0.0, 0.0\n    if prices.InputPrice != nil {\n        in = *prices.InputPrice\n    }\n    if prices.OutputPrice != nil {\n        out = *prices.OutputPrice\n    }\n    batch := int64(0)\n    if prices.BatchSize != nil {\n        batch = *prices.BatchSize\n    }\n    fmt.Printf(\"%s: input=%v output=%v per %d tokens (x%v)\\n\", model.ID, in, out, batch, multiplier)\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\nvar list = await client.Rpc.Models.ListAsync();\n\nforeach (var model in list.Models)\n{\n    var prices = model.Billing?.TokenPrices;\n    if (prices is null) continue;\n    Console.WriteLine(\n        $\"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} \" +\n        $\"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})\");\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<!-- docs-validate: skip -->\n\n```java\nvar list = client.getRpc().models.list().join();\n\nfor (var model : list.models()) {\n    var billing = model.billing();\n    if (billing == null || billing.tokenPrices() == null) {\n        continue;\n    }\n    var prices = billing.tokenPrices();\n    double multiplier = billing.multiplier() != null ? billing.multiplier() : 1;\n    System.out.printf(\"%s: input=%s output=%s per %d tokens (x%s)%n\",\n        model.id(), prices.inputPrice(), prices.outputPrice(), prices.batchSize(), multiplier);\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nlet list = client.rpc().models().list().await?;\n\nfor model in &list.models {\n    let Some(billing) = &model.billing else { continue };\n    let Some(prices) = &billing.token_prices else { continue };\n    let multiplier = billing.multiplier.unwrap_or(1.0);\n    println!(\n        \"{}: input={} output={} per {} tokens (x{multiplier})\",\n        model.id,\n        prices.input_price.unwrap_or(0.0),\n        prices.output_price.unwrap_or(0.0),\n        prices.batch_size.unwrap_or(0),\n    );\n}\n```\n\n</div>\n\n</div>\n\n## Interactions entre le quota du compte et la version premium\n\n`account.getQuota` indique le quota Copilot restant de l’utilisateur authentifié. La table `quotaSnapshots` du résultat est indexée par type de quota, généralement `premium_interactions`, `chat` et `completions`. Utilisez-le pour montrer aux utilisateurs la quantité de leur allocation mensuelle restante ou pour effectuer un travail avant d’atteindre une limite.\n\nL’exemple utilise les champs ci-dessous ; le type généré `AccountQuotaSnapshot` est la référence complète. Les `quotaSnapshots` clés sont des chaînes d’exécution que le système de type du Kit de développement logiciel (SDK) ne valide pas. Par conséquent, protégez vos recherches.\n\n| Champ                 | Type     | Description                                                        |\n| --------------------- | -------- | ------------------------------------------------------------------ |\n| `entitlementRequests` | `number` | Demandes incluses dans le forfait, ou `-1` pour un nombre illimité |\n| `usedRequests`        | `number` | Requêtes utilisées jusqu’à présent pendant cette période           |\n| `remainingPercentage` | `number` | Pourcentage du droit restant                                       |\n| `resetDate`           | `string` | Date de réinitialisation du quota ISO 8601                         |\n\n> \\[!TIP]\n> Pour lire le quota pour un utilisateur spécifique plutôt que le contexte d'authentification global de la connexion (par exemple, dans un serveur principal multilocataire), transmettez le jeton GitHub de cet utilisateur à `getQuota`. Consultez « [Multilocataire et déploiements de serveurs](/fr/copilot/how-tos/copilot-sdk/setup/multi-tenancy) ».\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 { quotaSnapshots } = await client.rpc.account.getQuota({});\nconst premium = quotaSnapshots[\"premium_interactions\"];\n\nif (premium) {\n    console.log(\n        `Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +\n            `(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? \"n/a\"})`,\n    );\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\nresult = await client.rpc.account.get_quota(AccountGetQuotaRequest())\npremium = result.quota_snapshots.get(\"premium_interactions\")\n\nif premium is not None:\n    print(\n        f\"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} \"\n        f\"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})\"\n    )\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\nresult, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})\n\nif premium, ok := result.QuotaSnapshots[\"premium_interactions\"]; ok {\n    resets := \"n/a\"\n    if premium.ResetDate != nil {\n        resets = premium.ResetDate.Format(time.RFC3339)\n    }\n    fmt.Printf(\"Premium interactions: %d/%d (%.1f%% left, resets %s)\\n\",\n        premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)\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\nvar result = await client.Rpc.Account.GetQuotaAsync();\n\nif (result.QuotaSnapshots.TryGetValue(\"premium_interactions\", out var premium))\n{\n    Console.WriteLine(\n        $\"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} \" +\n        $\"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString(\"o\") ?? \"n/a\"})\");\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<!-- docs-validate: skip -->\n\n```java\nvar result = client.getRpc().account.getQuota().join();\nvar premium = result.quotaSnapshots().get(\"premium_interactions\");\n\nif (premium != null) {\n    System.out.printf(\"Premium interactions: %d/%d (%.1f%% left, resets %s)%n\",\n        premium.usedRequests(), premium.entitlementRequests(),\n        premium.remainingPercentage(), premium.resetDate());\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nlet result = client.rpc().account().get_quota().await?;\n\nif let Some(premium) = result.quota_snapshots.get(\"premium_interactions\") {\n    let resets = premium.reset_date.as_deref().unwrap_or(\"n/a\");\n    println!(\n        \"Premium interactions: {}/{} ({:.1}% left, resets {resets})\",\n        premium.used_requests, premium.entitlement_requests, premium.remaining_percentage,\n    );\n}\n```\n\n</div>\n\n</div>\n\n## Choix de l’API appropriée\n\nUtilisez ce résumé pour déterminer l’API qui correspond à votre cas d’usage :\n\n* ```\n            **Afficher un coût en temps réel ou un compteur de jetons pendant l’exécution d’un tour** : abonnez-vous à `assistant.usage` et `session.usage_info`.\n  ```\n* **Afficher un résumé des coûts finals après un tour ou une session** : appel `session.usage.getMetrics`.\n* **Afficher l’utilisation de la fenêtre contextuelle lors de la reprise, avant tout nouveau tour** : appel `session.metadata.contextInfo`.\n* **Estimer le coût avant l’exécution du travail** : lire `models.list` les prix des jetons.\n* **Avertir les utilisateurs avant qu’ils n’épuisent leur plan** : appel `account.getQuota`.\n\n## Lectures complémentaires\n\n* [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events) : référence au niveau du champ complet pour `assistant.usage`, `session.usage_info`et chaque autre événement de session\n* [Observabilité](/fr/copilot/how-tos/copilot-sdk/observability) : exporter des données d’utilisation vers OpenTelemetry pour l’attribution des coûts\n* [Multilocataire et déploiements de serveurs](/fr/copilot/how-tos/copilot-sdk/setup/multi-tenancy) : résoudre le quota et les modèles par utilisateur avec un jeton GitHub"}