# 账号、Coding Plan 与闲时计划

> zcode login 怎样经 ZCode 平台中转完成浏览器授权，z.ai 与 bigmodel 两个账号区域怎样区分，令牌与 API Key 存在哪、怎样加密；个人、团队 Coding Plan、Start Plan 与隐藏的闲时计划各自用什么凭据、配哪些模型，额度又从哪里查。

- 作者：David（道雾轩）
- 专栏：ZCode 源码解读（https://daiw.org/manual/zcode.md）
- 最后更新：2026-09-21
- 原文：https://daiw.org/manual/zcode/accounts-plans
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

智谱把 ZCode 的模型服务做成了订阅：登录 z.ai 或 bigmodel 账号，开通 Coding Plan，就能用上 GLM 系列模型，不必自己填 API Key。这一篇讲这条“账号型”路径：命令行登录怎样完成授权，登录态存在哪里，怎样在每次模型请求前变成一份凭据；各档套餐对应哪些内置模型，隐藏的闲时计划又是什么。套餐在规则集里长什么样见[Provider 规则、模型目录与选项映射](https://daiw.org/manual/zcode/provider-config)，凭据怎样被塞进请求见[模型适配层](https://daiw.org/manual/zcode/model-adapters)。

代码分两处。Agent CLI 自己能完成登录：`apps/zcode-cli/packages/adapters/src/auth` 负责授权客户端、API Key 解析与凭据文件，`bootstrap/src/auth-login*.ts` 串起流程，`cli/src/login-command.ts` 与 `tui-auth.ts` 是入口。桌面端的登录、权益判定、购买与额度在 `packages/services/src` 的 `oauth`、`model-provider`、`bigmodel`、`coding-plan-subscription`、`usage-stats` 里，跨端类型在 `packages/shared/src`。

## 怎么用

| 场景 | 做法 |
| --- | --- |
| 用 z.ai 账号登录 | `zcode login`，等价于 `zcode login zai` |
| 用 bigmodel 账号登录 | `zcode login bigmodel` |
| 不自动打开浏览器 | 加 `--no-browser`，只打印授权地址 |
| 机器可读输出 | 加 `--json`，授权地址改写到 stderr，stdout 只有一段 JSON |
| 退出登录 | `zcode logout` |
| TUI 里配置 | `/login` 弹出四个选项：Z.AI、BigModel 两家的浏览器授权，以及两家的 Coding Plan API Key 手工粘贴 |

用法字符串是 `zcode login [zai|bigmodel] [--no-browser]`，别的参数一律报错（`apps/zcode-cli/packages/cli/src/login-command.ts:15`）。TUI 的四个选项分别对应 `/login zai-coding-plan`、`/login bigmodel-coding-plan`、`/login zai-coding-plan-api-key <key>`、`/login bigmodel-coding-plan-api-key <key>`，粘贴 Key 的输入框会掩码显示（`apps/zcode-cli/packages/cli/src/command-center/login-flow.ts:12`、`49`）。登录成功后打印用户名、选中的模型、凭据文件与模型选择文件的路径（`login-command.ts:67`）。

## 登录流程：经平台中转的轮询授权

命令行登录既不是标准的设备码流程，也不在本机起回调端口：CLI 生成一个随机的轮询令牌，请 ZCode 平台开一个短期 flow，用户在浏览器里授权，CLI 凭同一个令牌轮询结果。

```mermaid
sequenceDiagram
  participant U as zcode login
  participant Z as ZCode 平台
  participant B as 浏览器
  participant P as z.ai 或 bigmodel 开放平台
  U->>U: 生成 32 字节随机 pollToken
  U->>Z: POST /api/v1/oauth/cli/init，携带 pollToken
  Z-->>U: authorize_url、flow_id、expires_at、poll_interval_sec
  U->>B: 打开 authorize_url，--no-browser 时只打印
  loop 按 poll_interval_sec，至少 1 秒
    U->>Z: GET /api/v1/oauth/cli/poll/flow_id
    Z-->>U: pending、failed 或 ready
  end
  Z-->>U: ready 带回 ZCode JWT、用户信息、平台 access_token
  U->>P: 查组织与项目，找到或新建 zcode-api-key
  P-->>U: Coding Plan API Key
  U->>U: 加密写入凭据文件，写默认模型选择
```

- **地址**：平台 API 根取控制面地址加 `/api/v1`，缺省 `https://zcode.z.ai/api/v1`（`apps/zcode-cli/packages/adapters/src/auth/cli-oauth.ts:4`，`apps/zcode-cli/packages/bootstrap/src/auth-login.ts:366`）。轮询令牌是 32 字节随机数的十六进制串，init 与 poll 都以 `Authorization: Bearer <令牌>` 发送（`cli-oauth.ts:6`、`89`、`110`）。
- **校验**：init 的返回必须有 `flow_id`、https 的 `authorize_url`、`expires_at`，且 `poll_interval_sec` 不小于 1；每个响应最多读 64 KB（`cli-oauth.ts:138`、`172`）。
- **时限**：整个登录默认 5 分钟，并且不会超过服务端给的 `expires_at`（`auth-login.ts:39`、`148`）。被取消或超时的尝试，即使之后收到迟到的 ready，也不会落盘（`auth-login.ts:186`）。
- **结果**：ready 里 `token` 是 ZCode 平台的 JWT，平台账号令牌按家族放在 `zai` 或 `bigmodel` 字段下，含 `access_token` 与可选的 `refresh_token`（`cli-oauth.ts:214`）。

轮询循环本身（`apps/zcode-cli/packages/bootstrap/src/auth-login-polling.ts:23`）：

```ts
  const expiresAtMs = input.initData.expires_at * 1_000;
  const deadlineMs = Math.min(input.now() + input.timeoutMs, expiresAtMs);
  const pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, input.initData.poll_interval_sec * 1_000);

  while (input.now() < deadlineMs) {
    throwIfAborted(input.abortSignal);
    let data: CliOAuthPollData = { status: "pending" };
    try {
      data = await waitWithAbort(
        input.oauthClient.poll(
          {
            flowId: input.initData.flow_id,
            pollToken: input.pollToken,
          },
          { signal: input.abortSignal },
        ),
        input.abortSignal,
      );
    } catch (error) {
      throwIfAborted(input.abortSignal);
      if (
        error instanceof CliOAuthError &&
        !(error.httpStatus === 408 || error.httpStatus === 429 || (error.httpStatus ?? 0) >= 500)
      )
        throw error;
      // Match App polling: transient network and server failures retry at the server interval.
    }
```

408、429、5xx 和网络错误都当作暂时失败，按原间隔继续轮询；其余平台错误立即结束登录。桌面端 OAuth 服务的 `startOAuthWithPolling` 用的是同一对 `/api/v1/oauth/cli/init` 与 `poll` 接口，只是浏览器回调最终经官网中转页跳回 `zcode://oauth/callback`（`packages/services/src/oauth/oauthService.ts:609`，`packages/services/src/oauth/providers/configUtils.ts:34`）。接口注释说后端 flow “当前仅 Z.AI 支持”（`packages/services/src/oauth/oauth.ts:40`），实际实现对 z.ai 和 bigmodel 都走这条路（`oauthService.ts:595`）。`adapters/src/auth` 里还有一个 bigmodel 授权码交换客户端 `bigmodel-oauth.ts`，非测试代码里找不到调用方；`localhost-callback.ts` 的本地回调服务器只给 MCP 的 OAuth 用（`apps/zcode-cli/packages/adapters/src/mcp/oauth-interactive.ts:15`）。

## 两个账号区域：z.ai 与 bigmodel

两个区域在代码里叫 Provider Family，各自一套 ID 与域名（`packages/shared/src/model-provider-family.ts:26`）：

| 家族 | 根域名 | OAuth provider | 账号型 Provider |
| --- | --- | --- | --- |
| `zai`（Z.ai） | `z.ai` | `zai` | `account:zai-individual-coding-plan`、`account:zai-team-coding-plan`、`account:zai-start-plan` |
| `bigmodel`（BigModel） | `bigmodel.cn` | `bigmodel` | `account:bigmodel-individual-coding-plan`、`account:bigmodel-team-coding-plan`、`account:bigmodel-start-plan` |

区分靠几处事实：命令行登录时显式指定，缺省 `zai`（`login-command.ts:15`）；凭据文件里的 `oauth:active_provider` 记下当前登录的是哪家（`apps/zcode-cli/packages/adapters/src/auth/shared-credentials.ts:16`）；桌面端只展示与当前登录同一家族的套餐（`model-provider-family.ts:139`）；拿不到身份时还可以按 Provider 地址的根域名反推（`model-provider-family.ts:78`）。

登录拿到的 OAuth 令牌并不直接用于模型请求。CLI 随后用它在开放平台上找一把 API Key，两家只在第一步不同（`apps/zcode-cli/packages/adapters/src/auth/coding-plan-api-key.ts:81`）：bigmodel 直接拿 access token 调 `bigmodel.cn` 的业务接口；z.ai 要先在 `https://api.z.ai/api/auth/z/login` 把它换成业务令牌（`coding-plan-api-key.ts:108`）。接下来两家一样：读客户信息，挑名字含“默认机构”的组织和含“默认项目”的项目，找不到就取第一个；在该项目下找名为 `zcode-api-key` 的 Key，没有就新建一把；最后取出密钥，有 `secretKey` 时拼成 `apiKey.secretKey` 的形式，z.ai 缺了它就报错（`coding-plan-api-key.ts:143`、`172`、`190`、`237`）。桌面端的个人套餐走同样的逻辑，团队套餐则在团队项目下维护一把 `zcode-team-api-key`，类型号为 2（`packages/services/src/model-provider/accountProviderApiKeyResolver.ts:123`，`packages/services/src/bigmodel/teamPlanApiKey.ts:4`）。

## 令牌存在哪、怎样续期

CLI 与桌面端共用一个凭据文件：`~/.zcode/v2/credentials.json`，数据基目录可用 `ZCODE_DATA_BASE_DIR` 改（`shared-credentials.ts:280`，`packages/services/src/credential/credentialService.ts:31`）。里面有这些键，前几个是固定键名（`shared-credentials.ts:15`）：

| 键 | 内容 |
| --- | --- |
| `oauth:active_provider` | 当前登录的家族 |
| `zcodejwttoken` | ZCode 平台 JWT |
| `oauth:zai:access_token`、`oauth:zai:user_info`、`oauth:zai:refresh_token` | z.ai 账号令牌与用户信息 |
| `oauth:bigmodel:access_token`、`oauth:bigmodel:user_info`、`oauth:bigmodel:refresh_token` | bigmodel 同上 |
| `account-provider:coding-plan:<providerId>:account:<身份>:api-key` | 某个账号型 Provider 的请求 Key |
| `account-provider:<providerId>:identity` | 这个 Provider 当前绑定的账号身份 |

后两类键名由 `standaloneAccountProviderCredentialKey` 与 `standaloneAccountIdentityCredentialKey` 生成，团队与 Start Plan 在桌面端有各自的变体（`apps/zcode-cli/packages/bootstrap/src/app/standalone-account-provider-runtime.ts:82`，`packages/services/src/model-provider/accountProviderCredentialKey.ts:20`）。CLI 的 z.ai 登录只写 access token、JWT 与用户信息，不保存 refresh token；bigmodel 登录在服务端给了时才保存（`auth-login.ts:189`、`196`）。

每个值写入前都单独加密，格式是 `enc:v1:` 加 AES-256-GCM 的 IV、认证标签和密文。密钥是一个口令的 SHA-256（`apps/zcode-cli/packages/adapters/src/auth/credential-cipher.ts:83`），口令优先取环境变量 `ZCODE_CREDENTIAL_SECRET`，没设时退回一个由本机事实拼出的字符串（`credential-cipher.ts:87`）：

```ts
function resolveCredentialSecret(env: Record<string, string | undefined>): string {
  const configuredSecret = env[CREDENTIAL_SECRET_ENV_KEY]?.trim();
  if (configuredSecret) {
    return configuredSecret;
  }

  let username = "unknown";
  try {
    username = userInfo().username;
  } catch {
    // Some packaged or sandboxed runtimes cannot resolve OS user info.
  }

  return `zcode-credential-fallback:${platform()}:${homedir()}:${username}`;
}
```

从代码看，缺省密钥只由平台、主目录和用户名决定，能挡住“直接打开文件看到明文”，挡不住同一用户下的其他程序；桌面端的注释也写着以后可能改用 Electron safeStorage 托管密钥（`credentialService.ts:22`）。写入在文件锁内完成整段读改写，再以 `0600` 权限原子替换；文件损坏时先备份现场再报错，不会当成空文件覆盖掉别的进程写的凭据（`shared-credentials.ts:306`、`316`）。

**续期**。桌面端的 OAuth 服务接口里有 `refreshToken`，但 z.ai 与 bigmodel 两个适配器都没有实现刷新方法，调用会直接报“暂未提供 refresh token 交换接口，请重新登录”（`oauthService.ts:964`，`packages/services/src/oauth/providers/providerAdapter.ts:31`）。桌面端的做法是被动失效：带当前 JWT 的请求，或带当前 access token 查询用户信息的请求返回 401，就退出当前会话（`packages/services/src/oauth/oauthUnauthorizedRequest.ts:21`）。CLI 里没有刷新逻辑：模型请求用的是登录时取到的那把 API Key，不依赖 OAuth 令牌。`zcode logout` 删除所有共享键和各个人套餐 Provider 的身份与 Key，而且只删除值仍与读取时相同的项，避免误删并发登录刚写入的凭据（`auth-login.ts:282`）。

## 从登录态到请求凭据

账号型 Provider 的配置里没有 Key。Registry 只从账号层拿到“有没有权益、是不是当前连接”，真正的凭据在每次模型请求尝试之前现取，用完不进配置、不进协议（[模型适配层](https://daiw.org/manual/zcode/model-adapters)讲了它怎样被塞进请求）。

```mermaid
flowchart LR
  L["zcode login 或桌面登录"] --> C["credentials.json<br/>JWT、access_token、API Key"]
  C --> H["请求头端口<br/>每次尝试前取凭据"]
  H --> A["适配层替换 apiKey 与请求头"]
  A --> G["官方端点改写到平台网关"]
  G --> S["套餐服务校验权益"]
```

桌面端按套餐类型决定凭据（`packages/services/src/model-provider/accountProviderRequestAuthService.ts:68`）：

```ts
  async resolveCurrent(input: AccountRequestAuthInput): Promise<AccountRequestAuthMaterial> {
    const providerId = input.providerId.trim();
    const access = await this.#resolveAccess(input.accountAccess);
    if (!access) throw new AccountRequestCredentialUnavailableError(providerId);

    if (access.planKind === "start-plan") {
      const tokenSet = await this.#options.loadOAuthTokenSet(resolveOAuthProviderId(access.family));
      return { apiKey: requireApiKey(tokenSet?.zcodeJwtToken, providerId) };
    }

    if (access.planKind === "individual-coding-plan") {
      const apiKey = await this.#options.loadIndividualPlanApiKey(providerId, access.family);
      return { apiKey: requireApiKey(apiKey, providerId) };
    }

    const apiKey = await this.#options.resolveTeamPlanApiKey(access);
    return { apiKey: requireApiKey(apiKey, providerId) };
  }
```

个人套餐用那把 `zcode-api-key`，团队套餐用团队 Key，Start Plan 则直接把 ZCode JWT 当作 API Key。桌面端拉起的 Agent 进程通过协议向 Host 请求这份材料，单次最多等 180000 毫秒（`apps/zcode-cli/packages/bootstrap/src/zcode-protocol/provider-runtime-headers.ts:16`）。

独立运行的 CLI 更简单，也更窄：它只认各家的个人 Coding Plan Provider（`standalone-account-provider-runtime.ts:40`）。凭据文件里有这个 Provider 的身份和 Key，账号层就把它标成有权益，否则显式标成无权益，好让它退出 Registry（`standalone-account-provider-runtime.ts:137`）；请求前的端口每次重新读身份与 Key（`standalone-account-provider-runtime.ts:169`）。也就是说，CLI 本地并不查询订阅状态，是否真的开通了套餐，要等请求发到官方端点、被改写到 ZCode 平台网关后由服务端判定（`apps/zcode-cli/packages/adapters/src/model/official-coding-plan-gateway.ts:7`）。从代码看，团队套餐、Start Plan 和闲时计划在独立 CLI 里拿不到权益，都进不了 Registry。

## Coding Plan 各档与内置模型

四档账号型套餐都用 `anthropic-messages` 协议，端点与内置模型清单以规则集为准（`config/provider/zcode-builtin.json:697`、`739`、`823`）：

| 套餐 | 端点 | 内置模型 | 说明 |
| --- | --- | --- | --- |
| 个人 Coding Plan | z.ai：`https://api.z.ai/api/anthropic`；bigmodel：`https://open.bigmodel.cn/api/anthropic` | GLM-5.3、GLM-5.3-Flash | 独立 CLI 登录后默认选中 GLM-5.3 |
| 团队 Coding Plan | 同个人版 | GLM-5.3、GLM-5.3-Flash | 仅桌面端，按组织与项目选连接 |
| Start Plan | 两家都是 `https://zcode.z.ai/api/v1/zcode-plan/anthropic` | GLM-5.3-Flash、GLM-5.2、GLM-5-Turbo | 实际清单由服务端下发 |
| 闲时（Idle plan） | 两家都是 `https://zcode.z.ai/api/v1/off-peak/anthropic` | GLM-5.3、GLM-5.3-Flash | 隐藏，只供闲时任务 |

`builtinProviderModelRules` 另外为个人版与团队版登记了 GLM-5.2、GLM-5-Turbo 的启用规则（`zcode-builtin.json:6026`），但一个 Provider 的模型列表只由内置清单加个人追加的模型 ID 组成（`packages/provider/src/resolver.ts:237`）；从代码看，这两个模型要用户自己追加才会出现在个人与团队套餐下。Start Plan 的内置清单只是起点，账号层会用服务端返回的模型名单整体替换它，空名单也算数（`packages/provider/src/account-provider-resolution.ts:106`）。代码注释里 Start Plan 又叫“体验套餐”，是免费档（`packages/ui/src/settings/model-provider-section/StatusCards.tsx:447`）。

按规则集的叠加顺序算下来（叠加方式见[Provider 规则一篇](https://daiw.org/manual/zcode/provider-config)），Coding Plan 站点上四个模型的有效能力如下：

| 模型 | 上下文 | 输入 | 推理档位 | 输出上限 |
| --- | --- | --- | --- | --- |
| GLM-5.3 | 1000000 | 文本、图片、视频 | `low`、`high`、`max` | 128000 |
| GLM-5.3-Flash | 1000000 | 文本、图片、视频、PDF | `low`、`high`、`max` | 128000 |
| GLM-5.2 | 1000000 | 文本、图片、视频 | `disabled`、`high`、`max` | 128000 |
| GLM-5-Turbo | 200000 | 文本、图片、视频 | `disabled`、`enabled` | 64000 |

图片与视频输入是 Coding Plan 与 Start Plan 站点规则统一打开的（`zcode-builtin.json:4012`）；闲时端点没有这条规则，GLM-5.3 在那里只收文本，也不开原生 WebSearch（`zcode-builtin.json:4125`）。

桌面端判定权益的规则（`packages/services/src/bigmodel/codingPlanEntitlement.ts:45`、`119`）：

- **个人版**：订阅列表里有一条产品 ID 或名称含 `coding` 的记录，状态为 `VALID` 且在当前周期内；列表请求超时 15 秒（`packages/services/src/model-provider/codingPlanProviderAvailability.ts:33`）。
- **团队版**：`EXPIRED` 判为过期，`EFFECTIVE` 但成员未分配（`UNASSIGNED`）判为未分配，`EFFECTIVE` 且成员授权 `VALID` 才算可用，其余新状态一律记为未知，不擅自当成无权益。

不可用的原因只有四种：未登录、未连接、凭据获取失败、明确无权益（`packages/shared/src/account-provider-state.ts:5`）。已保存的模型选择若指向个人或团队套餐，执行前会被换成当前账号唯一处于“当前连接”的那档（`packages/provider/src/effective-model-selection.ts:29`），换了套餐不必重选模型。购买与续费（国内支付宝、微信，海外 Stripe、PayPal，以及团队的企业订单）都是桌面端服务，CLI 不涉及（`packages/shared/src/coding-plan-subscription.ts:5`）。

## API Key 模式与账号模式

“用 API Key 接 Coding Plan”在代码里有两种形态，结果不一样：

| | TUI 粘贴 Coding Plan Key | Coding Plan API Key 模板 |
| --- | --- | --- |
| 入口 | `/login zai-coding-plan-api-key <key>` 等 | 新建 Provider 时选 `zai-api` 或 `bigmodel-api` |
| 落在哪个 Provider | 账号型的个人 Coding Plan Provider | 个人 Provider，访问方式 `zhipu-coding-plan-api-key` |
| Key 存在哪 | `credentials.json`，逐项加密 | `provider_config.json`，明文 |
| 身份 | Key 的 SHA-256 前 24 位，形如 `key-…` | 无 |
| 权益与当前连接 | 参与账号层判定 | 不参与 |
| 请求路径 | 官方端点，经平台网关 | 同一端点，同样经网关 |

TUI 粘贴的 Key 由 `configureCodingPlanApiKey` 当作一次“登录”处理：用 Key 的摘要当账号身份，写进与 OAuth 登录相同的凭据键（`auth-login.ts:258`，`standalone-account-provider-runtime.ts:101`）。所以在独立 CLI 里，OAuth 登录与粘贴 Key 最终都表现为同一个 `account:*-individual-coding-plan` Provider，差别只是 Key 的来源。模板方式则完全是普通的 BYOK：两个模板默认启用 GLM-5.3 与 GLM-5.3-Flash（`zcode-builtin.json:4507`），因为地址相同，请求照样被改写到平台网关，但它们不算“账号连接”，闲时任务用不了（`packages/services/src/session/offPeakRuntimeModel.ts:91`）。

## 闲时计划（Idle plan）

闲时计划是两个隐藏的账号型 Provider，`account:zai-offpeak-idle-plan` 与 `account:bigmodel-offpeak-idle-plan`（`packages/shared/src/off-peak-types.ts:41`）。隐藏意味着它们不出现在模型选择器里，只由桌面端的调度器在派发闲时任务时使用；任务怎样排队、派发和防递归，见[定时任务与闲时任务](https://daiw.org/manual/zcode/cron-offpeak)。这里只看与套餐相关的部分：

- **什么时候可用**：远端 `client/configs` 里的灰度开关 `offPeak.enable_offpeak_task` 为真，且 Registry 里确有闲时模型（`packages/services/src/coding-plan-subscription/bigmodelCodingPlanSubscriptionProvider.ts:1328`）。服务端的票据先排队，低峰窗口开且排到号才进入可派发状态；类型注释记录了两个时限，就绪票据 5 分钟、执行中票据 3 小时（`off-peak-types.ts:32`、`157`）。
- **谁能用**：当前选中的连接必须是同一家族的个人或团队 Coding Plan，并且已登录、有 ZCode JWT；Start Plan 明确不支持（`offPeakRuntimeModel.ts:98`、`164`）。
- **凭据**：一次闲时执行同时带三样东西，`Authorization: Bearer <JWT>`、`X-Coding-Plan-Api-Key` 与 `X-Off-Peak-Ticket-ID`，BigModel 团队版另带组织与项目头（`offPeakRuntimeModel.ts:246`）。
- **排队语义**：适配层只对闲时 Provider 特判，429 或业务码 3105 表示还在排队，按服务端给的等待时间、最多 5 分钟探测一次，缺省 60 秒，不消耗重试预算；400 带 3102（兼容旧的 3001）表示票据失效，错误信息前缀 `off-peak-ticket-expired`，桌面端据此重新取号并续跑同一个会话（`apps/zcode-cli/packages/adapters/src/model/offpeak-retry.ts:1`、`40`）。
- **工具限制**：`OffPeakCreate`、`OffPeakList` 两个工具让模型在对话里创建和查看闲时任务；闲时派发的回合里，它们以及会绕过本轮模型重新拉起子 Agent、落到用户付费套餐上的工具都会被拒绝（`apps/zcode-cli/packages/core/src/tool/handlers/off-peak.ts:39`）。额度用尽（3103）、没有合格套餐（3101）、模型不在允许名单等失败，会翻译成模型能转述给用户的固定文案（`off-peak.ts:80`）。

## 用量与额度

从代码看，CLI 与 TUI 里没有额度查询，用量与额度只在桌面端展示，服务接口是 `IUsageStatsService`（`packages/services/src/usage-stats/usageStats.ts:20`）：

| 数据 | 来源 | 出处 |
| --- | --- | --- |
| Coding Plan 额度 | 所属家族业务域的 `/api/monitor/usage/quota/limit`，超时 15 秒 | `packages/services/src/usage-stats/providers/bigmodelUsageQuotaProvider.ts:72` |
| 额度重置机会 | 控制面 `/api/v1/coding-plan/reset` 下的状态、领取、使用接口，分 5 小时与每周两种 | `bigmodelUsageQuotaProvider.ts:528`，`packages/shared/src/coding-plan-reset.ts:1` |
| Start Plan 余额 | 控制面的 `/api/v1/zcode-plan/billing/balance` | `packages/shared/src/zcodeEndpoint.ts:269` |
| 官方 MCP 调用额度 | `GET /api/v1/mcp/usage` | `packages/services/src/usage-stats/providers/zcodeMcpQuotaProvider.ts:24` |

额度快照是一个等级加若干条限额，每条有类型、已用、剩余、已用占比、下次重置时间和按模型的用量明细；Start Plan 的额度桶还带桶 ID、套餐实例与周期起止，用于提醒去重（`packages/shared/src/usage-quota.ts:9`）。

下一篇：[子 Agent](https://daiw.org/manual/zcode/subagents)——主会话怎样派出 explore、general-purpose 等子 Agent，它们用什么模型、带什么工具、怎样把结果交回来。
