{"meta":{"title":"Métricas de uso y facturación","intro":"En esta guía se muestra cómo leer los recuentos de tokens, el uso de ventanas de contexto, el costo de crédito de IA y la cuota de la cuenta desde una aplicación del SDK de Copilot. Se muestran ejemplos para TypeScript, Python, Go, .NET, Java y Rust.","product":"GitHub Copilot","breadcrumbs":[{"href":"/es/copilot","title":"GitHub Copilot"},{"href":"/es/copilot/how-tos","title":"Procedimientos"},{"href":"/es/copilot/how-tos/copilot-sdk","title":"SDK de Copilot"},{"href":"/es/copilot/how-tos/copilot-sdk/features","title":"Características"},{"href":"/es/copilot/how-tos/copilot-sdk/features/usage-and-billing","title":"Uso y facturación"}],"documentType":"article"},"body":"# Métricas de uso y facturación\n\nEn esta guía se muestra cómo leer los recuentos de tokens, el uso de ventanas de contexto, el costo de crédito de IA y la cuota de la cuenta desde una aplicación del SDK de Copilot. Se muestran ejemplos para TypeScript, Python, Go, .NET, Java y Rust.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n> \\[!TIP]\n> Cada ejemplo es funcionalmente equivalente entre idiomas. El fragmento de código de TypeScript aparece expandido de forma predeterminada; selecciona tu idioma en los bloques desplegables para ver la misma lógica en ese SDK correspondiente.\n\n## Información general\n\nEl SDK expone los datos de uso a través de dos mecanismos complementarios:\n\n* **Eventos de sesión**: eventos transitorios que el entorno de ejecución emite mientras se ejecuta un turno. Suscríbase a estas para obtener datos en tiempo real de cada llamada a la API.\n* **Métodos RPC**: llamadas de petición-respuesta que se realizan bajo demanda. Úselos para obtener una instantánea de los totales acumulados o consultar la cuota de la cuenta.\n\nEn la tabla siguiente se asigna cada señal a la API que la expone.\n\n| Señal                                           | API                            | Ámbito   | Tipo |\n| ----------------------------------------------- | ------------------------------ | -------- | ---- |\n| Recuentos de tokens por llamada                 |                                |          |      |\n| `assistant.usage` evento                        | Session                        | Event    |      |\n| Uso de la ventana de contexto                   |                                |          |      |\n| `session.usage_info` evento                     | Session                        | Event    |      |\n| Desglose de la ventana de contexto (a petición) | `session.metadata.contextInfo` | Session  | RPC  |\n| Totales acumulados de créditos y tokens de IA   | `session.usage.getMetrics`     | Session  | RPC  |\n| Precios de crédito por modelo de IA             | `models.list`                  | Servidor | RPC  |\n| Cuota de cuenta e interacciones premium         | `account.getQuota`             | Servidor | RPC  |\n\n> \\[!NOTE]\n> `session.usage.getMetrics`, `session.metadata.contextInfo`y `session.metadata.recomputeContextTokens` se marcan como experimentales en la superficie RPC generada. En .NET emiten el `GHCP001` diagnóstico experimental, que se suprime con `#pragma warning disable GHCP001` o un `<NoWarn>GHCP001</NoWarn>` en el nivel de proyecto. Ancle tanto el SDK como el entorno de ejecución de la CLI de Copilot si la aplicación depende de ellos.\n\nLas tablas de campos siguientes muestran solo los campos usados en los ejemplos de esta página. La referencia de campos completa y siempre actualizada la componen los tipos generados del SDK y [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events), que se regenera a partir del esquema de la CLI con cada actualización de dependencias. Trátelos como la fuente de la verdad y esta página como una guía orientada a tareas.\n\n## Recuentos de tokens por llamada\n\nEl evento `assistant.usage` se emite una vez por cada llamada a la API del modelo en un turno (incluidas las llamadas realizadas por los subagentes). Incluye los recuentos de tokens y el multiplicador de facturación de esa llamada concreta.\n\nEn el ejemplo siguiente se usan estos campos. Consulte [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events#assistantusage) para obtener la lista completa, incluidos los campos de caché, razonamiento, latencia y seguimiento.\n\n| Campo          | Tipo     | Description                                                  |\n| -------------- | -------- | ------------------------------------------------------------ |\n| `model`        | `string` | Identificador de modelo para esta llamada                    |\n| `inputTokens`  | `number` | Tokens de entrada consumidos                                 |\n| `outputTokens` | `number` | Tokens de salida generados                                   |\n| `cost`         | `number` | Multiplicador de solicitudes Premium aplicado a esta llamada |\n\n> \\[!TIP]\n> `assistant.usage` es efímero, por lo que se entrega en vivo pero no se reproduce cuando se reanuda una sesión. Para leer los totales acumulados a posteriori, llame a `session.usage.getMetrics` (consulte [Crédito de IA acumulado y totales de tokens](#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## Uso de la ventana de contexto\n\nLos recuentos de tokens te indican cuántos consumió cada llamada. El uso de la ventana de contexto indica cómo está completa la ventana de solicitud del modelo en este momento, útil para mostrar una barra de progreso o advertir al usuario antes de que se inicie la compactación automática.\n\n### Actualizaciones en directo con `session.usage_info`\n\nEl entorno de ejecución emite el evento `session.usage_info` cada vez que cambia el tamaño de la ventana de contexto. En el ejemplo se usa `currentTokens` y `tokenLimit`; vea [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events#sessionusage_info) para obtener la carga completa.\n\n| Campo           | Tipo     | Description                                                    |\n| --------------- | -------- | -------------------------------------------------------------- |\n| `currentTokens` | `number` | Tokens actualmente en la ventana de contexto                   |\n| `tokenLimit`    | `number` | Número máximo de tokens para la ventana de contexto del modelo |\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### Desglose a petición con `session.metadata.contextInfo`\n\nLos eventos solo se activan cuando cambia el contexto. Para leer el desglose actual en cualquier momento (por ejemplo, justo después de reanudar una sesión), llame a `session.metadata.contextInfo`. Pase `0` para `promptTokenLimit` que use el valor predeterminado en tiempo de ejecución; pase `0` para `outputTokenLimit` si el valor es desconocido.\n\nEl resultado `contextInfo` es `null` hasta que se ha inicializado la sesión (se han almacenado en caché la solicitud del sistema y los metadatos de la herramienta). Divide el total en `systemTokens`, `conversationTokens`y `toolDefinitionsTokens`, junto con `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## Totales acumulados de créditos y tokens de IA\n\n`session.usage.getMetrics` devuelve los totales acumulados de toda la sesión en una sola llamada. Esta es la forma más clara de consultar el coste de los créditos de IA, porque agrega por ti cada llamada a la API (agente principal y subagentes).\n\nEn el ejemplo se usan los campos siguientes. El tipo generado `UsageGetMetricsResult` es la referencia completa.\n\n| Campo                     | Tipo                          | Description                                                                                       |\n| ------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- |\n| `totalNanoAiu`            | `number`                      | Coste de créditos de IA de toda la sesión, en unidades nano-IA                                    |\n| `totalPremiumRequestCost` | `number`                      | Coste de la solicitud prémium para todos los modelos, tras aplicar los multiplicadores            |\n| `modelMetrics`            | `Record<string, ModelMetric>` | Desglose por modelo; cada entrada tiene `usage.inputTokens`, `usage.outputTokens`y `totalNanoAiu` |\n\n> \\[!NOTE]\n> El costo se notifica en **unidades de nano-AI** (el campo se denomina `totalNanoAiu`). La conversión exacta a créditos de IA y el significado preciso del cómputo de las solicitudes prémium los define la facturación de GitHub Copilot, no el SDK; considera [la documentación de facturación de Copilot de GitHub](/es/copilot/concepts/billing) como la fuente autorizada y verifícala antes de mostrar a los usuarios valores de tipo monetario. Los ejemplos usan la división por `1e9` por comodidad, siguiendo el prefijo `nano` del SI; confirme que esto coincide con la facturación actual antes de basarse en ello. Los mapas `modelMetrics` y `tokenDetails` se codifican mediante cadenas de tiempo de ejecución (ID de modelos y nombres de tipo de token) que el sistema de tipo de SDK no valida.\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## Precios de crédito por modelo de IA\n\nPara calcular el coste antes de ejecutar un turno, lea los precios del token de cada modelo de `models.list`. Se trata de una llamada con ámbito de servidor en el cliente, por lo que no requiere una sesión. Los precios se expresan en créditos de IA por cada lote de tokens facturado. El tipo generado `ModelBillingTokenPrices` enumera todos los campos, incluido `cachePrice`.\n\n| Campo                             | Tipo     | Description                                                               |\n| --------------------------------- | -------- | ------------------------------------------------------------------------- |\n| `billing.multiplier`              | `number` | Multiplicador de costos de solicitud Premium en relación con la tasa base |\n| `billing.tokenPrices.inputPrice`  | `number` | Costo de crédito de IA por lote de tokens de entrada                      |\n| `billing.tokenPrices.outputPrice` | `number` | Costo de crédito de IA por lote de tokens de salida                       |\n| `billing.tokenPrices.batchSize`   | `number` | Número de tokens por lote de facturación                                  |\n\n> \\[!NOTE]\n> Los valores de precio cambian a medida que evolucionan los planes y los modelos. Léelas en tiempo de ejecución como se muestra a continuación; nunca codifique de forma rígida los números en la aplicación.\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## Cuota de cuenta e interacciones premium\n\n`account.getQuota` notifica el derecho de Copilot restante del usuario autenticado. El mapa `quotaSnapshots` del resultado se codifica por tipo de cuota, normalmente `premium_interactions`, `chat` y `completions`. Úselo para mostrar a los usuarios cuánto les queda de su cuota mensual o para bloquear el trabajo antes de que alcancen el límite.\n\nEn el ejemplo se usan los campos siguientes; el tipo generado `AccountQuotaSnapshot` es la referencia completa. Las claves `quotaSnapshots` son cadenas de tiempo de ejecución que el sistema de tipos de SDK no valida, así que compruebe las búsquedas.\n\n| Campo                 | Tipo     | Description                                                          |\n| --------------------- | -------- | -------------------------------------------------------------------- |\n| `entitlementRequests` | `number` | Solicitudes incluidas en el plan, o `-1` para solicitudes ilimitadas |\n| `usedRequests`        | `number` | Solicitudes usadas hasta ahora en este período                       |\n| `remainingPercentage` | `number` | Porcentaje del derecho restante                                      |\n| `resetDate`           | `string` | Fecha ISO 8601 cuando se restablece la cuota                         |\n\n> \\[!TIP]\n> Para leer la cuota de un usuario específico en lugar del contexto de autenticación global de la conexión (por ejemplo, en un back-end multiinquilino), pase el token de GitHub del usuario a `getQuota`. Consulte [Multiinquilino e implementaciones de servidor](/es/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## Elección de la API correcta\n\nUse este resumen para decidir qué API se ajusta a su caso de uso:\n\n* ```\n            **Representar un medidor en directo de costes o tokens mientras se ejecuta un turno**: suscríbase a `assistant.usage` y `session.usage_info`.\n  ```\n* **Mostrar un resumen final de costes al final de un turno o de una sesión**: llamar a `session.usage.getMetrics`.\n* ```\n            **Mostrar el uso de la ventana de contexto al reanudar, antes de cualquier nuevo turno**: llame a `session.metadata.contextInfo`.\n  ```\n* **Calcule el costo antes de ejecutar el trabajo**: leer `models.list` los precios del token.\n* **Advertir a los usuarios antes de agotar su plan**: llame a `account.getQuota`.\n\n## Lectura adicional\n\n* [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events): referencia de nivel de campo completo para `assistant.usage`, `session.usage_info`y todos los demás eventos de sesión\n* [Observability](/es/copilot/how-tos/copilot-sdk/observability): exportar datos de uso a OpenTelemetry para la atribución de costos\n* [Multiinquilino e implementaciones de servidor](/es/copilot/how-tos/copilot-sdk/setup/multi-tenancy): resolución de la cuota y los modelos por usuario con un token de GitHub"}