提示
每个示例在功能上等效于语言。 默认情况下,TypeScript 代码片段已展开;从可折叠块中选择语言,以查看该 SDK 中的相同逻辑。
概述
SDK 通过两种互补机制显示使用情况数据:
- 会话事件:运行时在轮次运行时发出的临时事件。 订阅这些数据,以获取实时、按 API 调用的数据。
- RPC 方法:按需发出的请求/响应调用。 使用它们来快照累积的总计或查找帐户级配额。
下表将每个信号映射到公开它的 API。
| 信号 | API | Scope | 类型 |
|---|---|---|---|
| 按调用令牌计数 | |||
assistant.usage 事件 | 会话 | 事件 | |
| 上下文窗口利用率 | |||
session.usage_info 事件 | 会话 | 事件 | |
| 上下文窗口细分(按需) | session.metadata.context | 会话 | RPC |
| 累积的 AI 信用额度和令牌总计 | session.usage.get | 会话 | RPC |
| 按模型 AI 信用定价 | models.list | 服务器 | RPC |
| 帐户配额和高级交互 | account.getQuota | 服务器 | RPC |
注意
session.usage.getMetrics, session.metadata.contextInfo并在 session.metadata.recomputeContextTokens 生成的 RPC 图面中标记为实验性。 在.NET,它们会引发GHCP001试验性诊断,你禁止使用#pragma warning disable GHCP001或项目级<NoWarn>GHCP001</NoWarn>进行诊断。 如果应用程序依赖于 SDK 和 Copilot CLI 运行时,则固定 SDK 和 Copilot CLI 运行时。
下面的字段表仅列出本页上示例中使用的字段。 完整的始终当前字段引用是生成的 SDK 类型以及 流式处理会话事件,每次依赖项颠簸时,都会从 CLI 架构重新生成。 将这些内容视为事实来源,此页面作为面向任务的指南。
按调用令牌计数
对于 assistant.usage 轮次的每个模型 API 调用(包括子代理发出的调用),都会发出该事件一次。 它携带该单个调用的令牌计数和计费乘数。
下面的示例使用这些字段。 有关完整列表,请参阅 流式处理会话事件 ,包括缓存、推理、延迟和跟踪字段。
| 领域 | 类型 | Description |
|---|---|---|
model | string | 此调用的模型标识符 |
inputTokens | number | 消耗的输入令牌 |
outputTokens | number | 生成的输出令牌 |
cost | number | 应用于此调用的高级请求乘数 |
提示
assistant.usage 是临时的,因此在恢复会话时会实时传送,但不会重播。 若要在事实之后读取累计总计,请调用 session.usage.getMetrics (请参阅 累积的 AI 信用额度和令牌总计)。
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({ streaming: true });
session.on("assistant.usage", (event) => {
const { model, inputTokens, outputTokens, cost } = event.data;
console.log(
`${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,
);
});
session.on("assistant.usage", (event) => {
const { model, inputTokens, outputTokens, cost } = event.data;
console.log(
`${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,
);
});
from copilot import CopilotClient
from copilot.session_events import SessionEventType
client = CopilotClient()
session = await client.create_session(streaming=True)
def on_usage(event):
if event.type == SessionEventType.ASSISTANT_USAGE:
data = event.data
print(f"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}")
session.on(on_usage)
def on_usage(event):
if event.type == SessionEventType.ASSISTANT_USAGE:
data = event.data
print(f"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}")
session.on(on_usage)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Streaming: copilot.Bool(true),
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.AssistantUsageData)
if !ok {
return
}
in, out, cost := int64(0), int64(0), float64(0)
if d.InputTokens != nil {
in = *d.InputTokens
}
if d.OutputTokens != nil {
out = *d.OutputTokens
}
if d.Cost != nil {
cost = *d.Cost
}
fmt.Printf("%s: in=%d out=%d cost=%g\n", d.Model, in, out, cost)
})
_ = session
}
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.AssistantUsageData)
if !ok {
return
}
in, out, cost := int64(0), int64(0), float64(0)
if d.InputTokens != nil {
in = *d.InputTokens
}
if d.OutputTokens != nil {
out = *d.OutputTokens
}
if d.Cost != nil {
cost = *d.Cost
}
fmt.Printf("%s: in=%d out=%d cost=%g\n", d.Model, in, out, cost)
})
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Streaming = true });
session.On<AssistantUsageEvent>(evt =>
{
var data = evt.Data;
Console.WriteLine(
$"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}");
});
session.On<AssistantUsageEvent>(evt =>
{
var data = evt.Data;
Console.WriteLine(
$"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}");
});
session.on(AssistantUsageEvent.class, event -> {
var data = event.getData();
long in = data.inputTokens() != null ? data.inputTokens() : 0;
long out = data.outputTokens() != null ? data.outputTokens() : 0;
double cost = data.cost() != null ? data.cost() : 0.0;
System.out.printf("%s: in=%d out=%d cost=%s%n", data.model(), in, out, cost);
});
use github_copilot_sdk::session_events::AssistantUsageData;
let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
if event.event_type == "assistant.usage" {
if let Some(data) = event.typed_data::<AssistantUsageData>() {
println!(
"{}: in={} out={} cost={}",
data.model,
data.input_tokens.unwrap_or(0),
data.output_tokens.unwrap_or(0),
data.cost.unwrap_or(0.0),
);
}
}
}
上下文窗口利用率
令牌计数会告知每个调用使用的内容。 上下文窗口利用率会告诉你模型提示窗口现在有多完整,这对于在自动压缩开始之前显示进度栏或警告用户非常有用。
使用 <a0/a0> 实时更新
每当上下文窗口大小发生更改时,运行时都会发出事件 session.usage_info 。 该示例使用 currentTokens 并 tokenLimit;有关完整有效负载,请参阅 流式处理会话事件 。
| 领域 | 类型 | Description |
|---|---|---|
currentTokens | number | 上下文窗口中当前存在的令牌 |
tokenLimit | number | 模型上下文窗口的最大标记数 |
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({ streaming: true });
session.on("session.usage_info", (event) => {
const { currentTokens, tokenLimit } = event.data;
const pct = Math.round((currentTokens / tokenLimit) * 100);
console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);
});
session.on("session.usage_info", (event) => {
const { currentTokens, tokenLimit } = event.data;
const pct = Math.round((currentTokens / tokenLimit) * 100);
console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);
});
from copilot import CopilotClient
from copilot.session_events import SessionEventType
client = CopilotClient()
session = await client.create_session(streaming=True)
def on_usage_info(event):
if event.type == SessionEventType.SESSION_USAGE_INFO:
data = event.data
pct = round(data.current_tokens / data.token_limit * 100)
print(f"Context: {data.current_tokens}/{data.token_limit} ({pct}%)")
session.on(on_usage_info)
def on_usage_info(event):
if event.type == SessionEventType.SESSION_USAGE_INFO:
data = event.data
pct = round(data.current_tokens / data.token_limit * 100)
print(f"Context: {data.current_tokens}/{data.token_limit} ({pct}%)")
session.on(on_usage_info)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Streaming: copilot.Bool(true),
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.SessionUsageInfoData)
if !ok {
return
}
pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)
fmt.Printf("Context: %d/%d (%d%%)\n", d.CurrentTokens, d.TokenLimit, pct)
})
_ = session
}
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.SessionUsageInfoData)
if !ok {
return
}
pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)
fmt.Printf("Context: %d/%d (%d%%)\n", d.CurrentTokens, d.TokenLimit, pct)
})
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Streaming = true });
session.On<SessionUsageInfoEvent>(evt =>
{
var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);
Console.WriteLine($"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)");
});
session.On<SessionUsageInfoEvent>(evt =>
{
var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);
Console.WriteLine($"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)");
});
session.on(SessionUsageInfoEvent.class, event -> {
var data = event.getData();
long pct = Math.round((double) data.currentTokens() / data.tokenLimit() * 100);
System.out.printf("Context: %d/%d (%d%%)%n", data.currentTokens(), data.tokenLimit(), pct);
});
use github_copilot_sdk::session_events::SessionUsageInfoData;
let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
if event.event_type == "session.usage_info" {
if let Some(data) = event.typed_data::<SessionUsageInfoData>() {
let pct = (data.current_tokens as f64 / data.token_limit as f64 * 100.0) as i64;
println!("Context: {}/{} ({}%)", data.current_tokens, data.token_limit, pct);
}
}
}
按需细分 session.metadata.contextInfo
仅当上下文更改时才会触发事件。 若要随时读取当前细目(例如,在恢复会话后)调用 session.metadata.contextInfo。 传递0以promptTokenLimit使用运行时默认值;如果outputTokenLimit值未知,则传递0。
结果是contextInfo``null在会话初始化之前(系统提示和工具元数据已缓存)。 它把总数分解成 systemTokens, conversationTokens并 toolDefinitionsTokens和 promptTokenLimit。
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({});
const { contextInfo } = await session.rpc.metadata.contextInfo({
promptTokenLimit: 0,
outputTokenLimit: 0,
});
if (contextInfo) {
console.log(
`Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +
`(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,
);
}
const { contextInfo } = await session.rpc.metadata.contextInfo({
promptTokenLimit: 0,
outputTokenLimit: 0,
});
if (contextInfo) {
console.log(
`Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +
`(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,
);
}
from copilot import CopilotClient
from copilot.rpc import MetadataContextInfoRequest
client = CopilotClient()
session = await client.create_session()
result = await session.rpc.metadata.context_info(
MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)
)
info = result.context_info
if info is not None:
print(
f"Total {info.total_tokens}/{info.prompt_token_limit} "
f"(system={info.system_tokens}, conversation={info.conversation_tokens})"
)
result = await session.rpc.metadata.context_info(
MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)
)
info = result.context_info
if info is not None:
print(
f"Total {info.total_tokens}/{info.prompt_token_limit} "
f"(system={info.system_tokens}, conversation={info.conversation_tokens})"
)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{})
result, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{
PromptTokenLimit: 0,
OutputTokenLimit: 0,
})
if info := result.ContextInfo; info != nil {
fmt.Printf("Total %d/%d (system=%d, conversation=%d)\n",
info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)
}
}
result, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{
PromptTokenLimit: 0,
OutputTokenLimit: 0,
})
if info := result.ContextInfo; info != nil {
fmt.Printf("Total %d/%d (system=%d, conversation=%d)\n",
info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)
}
#pragma warning disable GHCP001
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig());
var result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);
var info = result.ContextInfo;
if (info is not null)
{
Console.WriteLine(
$"Total {info.TotalTokens}/{info.PromptTokenLimit} " +
$"(system={info.SystemTokens}, conversation={info.ConversationTokens})");
}
#pragma warning restore GHCP001
var result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);
var info = result.ContextInfo;
if (info is not null)
{
Console.WriteLine(
$"Total {info.TotalTokens}/{info.PromptTokenLimit} " +
$"(system={info.SystemTokens}, conversation={info.ConversationTokens})");
}
var result = session.getRpc().metadata
.contextInfo(new SessionMetadataContextInfoParams(null, 0L, 0L, null))
.join();
var info = result.contextInfo();
if (info != null) {
System.out.printf("Total %d/%d (system=%d, conversation=%d)%n",
info.totalTokens(), info.promptTokenLimit(), info.systemTokens(), info.conversationTokens());
}
use github_copilot_sdk::rpc::MetadataContextInfoRequest;
let result = session
.rpc()
.metadata()
.context_info(MetadataContextInfoRequest {
prompt_token_limit: 0,
output_token_limit: 0,
selected_model: None,
})
.await?;
if let Some(info) = result.context_info {
println!(
"Total {}/{} (system={}, conversation={})",
info.total_tokens, info.prompt_token_limit, info.system_tokens, info.conversation_tokens,
);
}
累积的 AI 信用额度和令牌总计
session.usage.getMetrics 返回单个调用中整个会话的运行总计。 这是读取 AI 信用额度成本的最干净方法,因为它会为你聚合每个 API 调用(主代理和子代理)。
该示例使用下面的字段。 生成的 UsageGetMetricsResult 类型是完整引用。
| 领域 | 类型 | Description |
|---|---|---|
totalNanoAiu | number | 以 nano-AI 单元为单位的全会话式 AI 信用成本 |
total | number | 乘数后所有模型的高级请求成本 |
modelMetrics | Record<string, ModelMetric> | 按模型细分;每个条目都有 usage.inputTokens, usage.output和 totalNanoAiu |
注意
以 nano-AI 单位(该字段命名totalNanoAiu)报告成本。 精确转换到 AI 信用额度和高级请求会计的精确含义由GitHub Copilot计费而不是 SDK 定义-将GitHub的Copilot计费文档视为事实来源,并在向用户显示类似货币的值之前进行验证。 示例除 1e9 以方便起见,遵循 SI nano 前缀;在依赖它之前,请确认这与当前计费匹配。 和modelMetrics``tokenDetails映射由 SDK 类型系统未验证的运行时字符串(模型 ID 和令牌类型名称)进行密钥处理。
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({});
const metrics = await session.rpc.usage.getMetrics();
const aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;
console.log(`AI credits used: ${aiCredits.toFixed(6)}`);
console.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);
for (const [model, m] of Object.entries(metrics.modelMetrics)) {
if (!m) continue;
console.log(
`${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +
`nanoAiu=${m.totalNanoAiu ?? 0}`,
);
}
const metrics = await session.rpc.usage.getMetrics();
const aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;
console.log(`AI credits used: ${aiCredits.toFixed(6)}`);
console.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);
for (const [model, m] of Object.entries(metrics.modelMetrics)) {
if (!m) continue;
console.log(
`${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +
`nanoAiu=${m.totalNanoAiu ?? 0}`,
);
}
from copilot import CopilotClient
client = CopilotClient()
session = await client.create_session()
metrics = await session.rpc.usage.get_metrics()
ai_credits = (metrics.total_nano_aiu or 0) / 1e9
print(f"AI credits used: {ai_credits:.6f}")
print(f"Premium requests: {metrics.total_premium_request_cost}")
for model, m in metrics.model_metrics.items():
print(f"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}")
metrics = await session.rpc.usage.get_metrics()
ai_credits = (metrics.total_nano_aiu or 0) / 1e9
print(f"AI credits used: {ai_credits:.6f}")
print(f"Premium requests: {metrics.total_premium_request_cost}")
for model, m in metrics.model_metrics.items():
print(f"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}")
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{})
metrics, _ := session.RPC.Usage.GetMetrics(ctx)
aiCredits := float64(0)
if metrics.TotalNanoAiu != nil {
aiCredits = *metrics.TotalNanoAiu / 1e9
}
fmt.Printf("AI credits used: %.6f\n", aiCredits)
fmt.Printf("Premium requests: %v\n", metrics.TotalPremiumRequestCost)
for model, m := range metrics.ModelMetrics {
nanoAiu := float64(0)
if m.TotalNanoAiu != nil {
nanoAiu = *m.TotalNanoAiu
}
fmt.Printf("%s: in=%d out=%d nanoAiu=%v\n", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)
}
}
metrics, _ := session.RPC.Usage.GetMetrics(ctx)
aiCredits := float64(0)
if metrics.TotalNanoAiu != nil {
aiCredits = *metrics.TotalNanoAiu / 1e9
}
fmt.Printf("AI credits used: %.6f\n", aiCredits)
fmt.Printf("Premium requests: %v\n", metrics.TotalPremiumRequestCost)
for model, m := range metrics.ModelMetrics {
nanoAiu := float64(0)
if m.TotalNanoAiu != nil {
nanoAiu = *m.TotalNanoAiu
}
fmt.Printf("%s: in=%d out=%d nanoAiu=%v\n", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)
}
#pragma warning disable GHCP001
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig());
var metrics = await session.Rpc.Usage.GetMetricsAsync();
var aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;
Console.WriteLine($"AI credits used: {aiCredits:F6}");
Console.WriteLine($"Premium requests: {metrics.TotalPremiumRequestCost}");
foreach (var (model, m) in metrics.ModelMetrics)
{
Console.WriteLine(
$"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}");
}
#pragma warning restore GHCP001
var metrics = await session.Rpc.Usage.GetMetricsAsync();
var aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;
Console.WriteLine($"AI credits used: {aiCredits:F6}");
Console.WriteLine($"Premium requests: {metrics.TotalPremiumRequestCost}");
foreach (var (model, m) in metrics.ModelMetrics)
{
Console.WriteLine(
$"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}");
}
var metrics = session.getRpc().usage.getMetrics().join();
double aiCredits = metrics.totalNanoAiu() != null ? metrics.totalNanoAiu() / 1e9 : 0;
System.out.printf("AI credits used: %.6f%n", aiCredits);
System.out.printf("Premium requests: %s%n", metrics.totalPremiumRequestCost());
metrics.modelMetrics().forEach((model, m) -> {
double nanoAiu = m.totalNanoAiu() != null ? m.totalNanoAiu() : 0;
System.out.printf("%s: in=%d out=%d nanoAiu=%s%n",
model, m.usage().inputTokens(), m.usage().outputTokens(), nanoAiu);
});
let metrics = session.rpc().usage().get_metrics().await?;
let ai_credits = metrics.total_nano_aiu.unwrap_or(0.0) / 1e9;
println!("AI credits used: {ai_credits:.6}");
println!("Premium requests: {}", metrics.total_premium_request_cost);
for (model, m) in &metrics.model_metrics {
let nano_aiu = m.total_nano_aiu.unwrap_or(0.0);
println!(
"{model}: in={} out={} nanoAiu={nano_aiu}",
m.usage.input_tokens, m.usage.output_tokens,
);
}
按模型 AI 信用定价
若要在运行轮次之前估算成本,请从 models.list中读取每个模型的令牌价格。 这是客户端上的服务器范围的调用,因此不需要会话。 每个计费批次的令牌以 AI 额度表示价格。 生成的 ModelBillingTokenPrices 类型列出每个字段,包括 cachePrice。
| 领域 | 类型 | Description |
|---|---|---|
billing.multiplier | number | 相对于基本费率的高级请求成本乘数 |
billing.token | number | 每批输入令牌的 AI 信用成本 |
billing.token | number | 每批输出令牌的 AI 信用成本 |
billing.token | number | 每个计费批次的令牌数 |
注意
随着计划和模型的发展,价格值会发生变化。 在运行时读取它们,如下所示;切勿将数字硬编码到应用程序中。
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const { models } = await client.rpc.models.list({});
for (const model of models) {
const prices = model.billing?.tokenPrices;
if (!prices) continue;
console.log(
`${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +
`per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,
);
}
const { models } = await client.rpc.models.list({});
for (const model of models) {
const prices = model.billing?.tokenPrices;
if (!prices) continue;
console.log(
`${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +
`per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,
);
}
from copilot import CopilotClient
from copilot.rpc import ModelsListRequest
client = CopilotClient()
result = await client.rpc.models.list(ModelsListRequest())
for model in result.models:
prices = model.billing.token_prices if model.billing else None
if prices is None:
continue
multiplier = model.billing.multiplier if model.billing else 1
print(
f"{model.id}: input={prices.input_price} output={prices.output_price} "
f"per {prices.batch_size} tokens (x{multiplier})"
)
result = await client.rpc.models.list(ModelsListRequest())
for model in result.models:
prices = model.billing.token_prices if model.billing else None
if prices is None:
continue
multiplier = model.billing.multiplier if model.billing else 1
print(
f"{model.id}: input={prices.input_price} output={prices.output_price} "
f"per {prices.batch_size} tokens (x{multiplier})"
)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
list, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})
for _, model := range list.Models {
if model.Billing == nil || model.Billing.TokenPrices == nil {
continue
}
prices := model.Billing.TokenPrices
multiplier := 1.0
if model.Billing.Multiplier != nil {
multiplier = *model.Billing.Multiplier
}
in, out := 0.0, 0.0
if prices.InputPrice != nil {
in = *prices.InputPrice
}
if prices.OutputPrice != nil {
out = *prices.OutputPrice
}
batch := int64(0)
if prices.BatchSize != nil {
batch = *prices.BatchSize
}
fmt.Printf("%s: input=%v output=%v per %d tokens (x%v)\n", model.ID, in, out, batch, multiplier)
}
}
list, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})
for _, model := range list.Models {
if model.Billing == nil || model.Billing.TokenPrices == nil {
continue
}
prices := model.Billing.TokenPrices
multiplier := 1.0
if model.Billing.Multiplier != nil {
multiplier = *model.Billing.Multiplier
}
in, out := 0.0, 0.0
if prices.InputPrice != nil {
in = *prices.InputPrice
}
if prices.OutputPrice != nil {
out = *prices.OutputPrice
}
batch := int64(0)
if prices.BatchSize != nil {
batch = *prices.BatchSize
}
fmt.Printf("%s: input=%v output=%v per %d tokens (x%v)\n", model.ID, in, out, batch, multiplier)
}
using GitHub.Copilot;
await using var client = new CopilotClient();
var list = await client.Rpc.Models.ListAsync();
foreach (var model in list.Models)
{
var prices = model.Billing?.TokenPrices;
if (prices is null) continue;
Console.WriteLine(
$"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} " +
$"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})");
}
var list = await client.Rpc.Models.ListAsync();
foreach (var model in list.Models)
{
var prices = model.Billing?.TokenPrices;
if (prices is null) continue;
Console.WriteLine(
$"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} " +
$"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})");
}
var list = client.getRpc().models.list().join();
for (var model : list.models()) {
var billing = model.billing();
if (billing == null || billing.tokenPrices() == null) {
continue;
}
var prices = billing.tokenPrices();
double multiplier = billing.multiplier() != null ? billing.multiplier() : 1;
System.out.printf("%s: input=%s output=%s per %d tokens (x%s)%n",
model.id(), prices.inputPrice(), prices.outputPrice(), prices.batchSize(), multiplier);
}
let list = client.rpc().models().list().await?;
for model in &list.models {
let Some(billing) = &model.billing else { continue };
let Some(prices) = &billing.token_prices else { continue };
let multiplier = billing.multiplier.unwrap_or(1.0);
println!(
"{}: input={} output={} per {} tokens (x{multiplier})",
model.id,
prices.input_price.unwrap_or(0.0),
prices.output_price.unwrap_or(0.0),
prices.batch_size.unwrap_or(0),
);
}
帐户配额和高级交互
account.getQuota报告经过身份验证的用户剩余Copilot权利。 结果的 quotaSnapshots 映射按配额类型(通常 premium_interactions) chat和 completions。 使用它可向用户显示每月津贴的剩余量,或在达到限制之前限制工作。
该示例使用下面的字段;生成的 AccountQuotaSnapshot 类型是完整引用。 密钥 quotaSnapshots 是 SDK 类型系统未验证的运行时字符串,因此请保护查找。
| 领域 | 类型 | Description |
|---|---|---|
entitlement | number | 权利中包含的请求或 -1 无限制的请求 |
usedRequests | number | 此时间段到目前为止使用的请求 |
remaining | number | 剩余权利百分比 |
resetDate | string | 配额重置时的 ISO 8601 日期 |
提示
若要读取特定用户的配额,而不是连接的全局身份验证上下文(例如,在多租户后端中),请将该用户的GitHub令牌传递给getQuota。 请参阅“多租户与服务器部署”。
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const { quotaSnapshots } = await client.rpc.account.getQuota({});
const premium = quotaSnapshots["premium_interactions"];
if (premium) {
console.log(
`Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +
`(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? "n/a"})`,
);
}
const { quotaSnapshots } = await client.rpc.account.getQuota({});
const premium = quotaSnapshots["premium_interactions"];
if (premium) {
console.log(
`Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +
`(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? "n/a"})`,
);
}
from copilot import CopilotClient
from copilot.rpc import AccountGetQuotaRequest
client = CopilotClient()
result = await client.rpc.account.get_quota(AccountGetQuotaRequest())
premium = result.quota_snapshots.get("premium_interactions")
if premium is not None:
print(
f"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} "
f"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})"
)
result = await client.rpc.account.get_quota(AccountGetQuotaRequest())
premium = result.quota_snapshots.get("premium_interactions")
if premium is not None:
print(
f"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} "
f"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})"
)
package main
import (
"context"
"fmt"
"time"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
result, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})
if premium, ok := result.QuotaSnapshots["premium_interactions"]; ok {
resets := "n/a"
if premium.ResetDate != nil {
resets = premium.ResetDate.Format(time.RFC3339)
}
fmt.Printf("Premium interactions: %d/%d (%.1f%% left, resets %s)\n",
premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)
}
}
result, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})
if premium, ok := result.QuotaSnapshots["premium_interactions"]; ok {
resets := "n/a"
if premium.ResetDate != nil {
resets = premium.ResetDate.Format(time.RFC3339)
}
fmt.Printf("Premium interactions: %d/%d (%.1f%% left, resets %s)\n",
premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)
}
using GitHub.Copilot;
await using var client = new CopilotClient();
var result = await client.Rpc.Account.GetQuotaAsync();
if (result.QuotaSnapshots.TryGetValue("premium_interactions", out var premium))
{
Console.WriteLine(
$"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} " +
$"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString("o") ?? "n/a"})");
}
var result = await client.Rpc.Account.GetQuotaAsync();
if (result.QuotaSnapshots.TryGetValue("premium_interactions", out var premium))
{
Console.WriteLine(
$"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} " +
$"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString("o") ?? "n/a"})");
}
var result = client.getRpc().account.getQuota().join();
var premium = result.quotaSnapshots().get("premium_interactions");
if (premium != null) {
System.out.printf("Premium interactions: %d/%d (%.1f%% left, resets %s)%n",
premium.usedRequests(), premium.entitlementRequests(),
premium.remainingPercentage(), premium.resetDate());
}
let result = client.rpc().account().get_quota().await?;
if let Some(premium) = result.quota_snapshots.get("premium_interactions") {
let resets = premium.reset_date.as_deref().unwrap_or("n/a");
println!(
"Premium interactions: {}/{} ({:.1}% left, resets {resets})",
premium.used_requests, premium.entitlement_requests, premium.remaining_percentage,
);
}
选择正确的 API
使用此摘要来确定哪种 API 适合你的用例:
- 将实时成本或令牌计量呈现为轮次运行:订阅
assistant.usage和session.usage_info。 - 在轮次或会话后显示最终成本摘要:调用
session.usage.getMetrics。 - 在恢复时显示上下文窗口使用情况,然后再显示任何新轮次:调用
session.metadata.contextInfo。 - 在运行工作之前估算成本:读取
models.list令牌价格。 - 在用户耗尽计划之前警告用户:呼叫
account.getQuota。