Перейти к основному содержанию

Что это

  • Получает данные об использовании/квоте провайдера напрямую из его endpoints использования.
  • Без расчетных затрат; только сообщаемые провайдером окна квот или сводки состояния аккаунта.
  • Удобочитаемый вывод статуса окна квоты нормализуется до X% left, даже когда вышестоящий API сообщает использованную квоту, оставшуюся квоту или только сырые счетчики. Провайдеры без сбрасываемых окон квоты могут вместо этого показывать текст сводки провайдера, например баланс.
  • Сессионные /status и session_status могут откатываться к последней записи использования в транскрипте, когда живой снимок сессии неполный. Этот fallback заполняет отсутствующие счетчики токенов/кэша, может восстановить метку активной runtime-модели и предпочитает больший prompt-ориентированный итог, когда метаданные сессии отсутствуют или меньше. Существующие ненулевые живые значения по-прежнему имеют приоритет.

Где это отображается

  • /status в чатах: статусная карточка с эмодзи, токенами сессии и расчетной стоимостью (только API-ключ). Использование провайдера показывается для провайдера текущей модели, когда доступно, как нормализованное окно X% left или текст сводки провайдера.
  • /usage off|tokens|full в чатах: футер использования для каждого ответа (OAuth показывает только токены).
  • /usage cost в чатах: локальная сводка стоимости, агрегированная из журналов сессий OpenClaw.
  • CLI: openclaw status --usage печатает полный разбор по провайдерам.
  • CLI: openclaw channels list печатает тот же снимок использования рядом с конфигурацией провайдера (используйте --no-usage, чтобы пропустить).
  • Строка меню macOS: раздел “Использование” в Context (только если доступно).

Режим футера использования по умолчанию

/usage off|tokens|full задает футер для сессии и запоминается для этой сессии. messages.responseUsage задает начальное значение этого режима для сессий, которые еще не выбрали его, поэтому футер может быть включен по умолчанию без ввода /usage каждый раз. Задайте один режим для каждого канала или карту по каналам с fallback default:
{
  "messages": {
    "responseUsage": "tokens",
    // or: { "default": "off", "discord": "full" }
  },
}

Три различных состояния сессии

Поле responseUsage у сессии имеет три представимых состояния, каждое с разной семантикой:
СостояниеСохраненное значениеЭффективный режим
Не задано / наследоватьundefined (отсутствует)Переходит к значению по умолчанию messages.responseUsage, затем к off.
Явно выключено"off" (сохранено)Всегда выключено — значение конфигурации не off не может снова включить футер.
Явно включено"tokens" или "full" (сохранено)Этот режим, независимо от значения конфигурации по умолчанию.

Приоритет

Эффективный режим = переопределение сессии → запись конфигурации канала → defaultoff. Явный /usage off сохраняется как буквальное значение "off" в сессии, а не как “не задано”. Это означает, что значение messages.responseUsage по умолчанию, отличное от off, не может снова включить футер после того, как пользователь явно отключил его.

Сброс и выключение

  • /usage off — принудительно выключает футер и сохраняет этот выбор. Настроенное значение по умолчанию, отличное от off, не может переопределить это.
  • /usage reset (алиасы: inherit, clear, default) — очищает сессионное переопределение. Затем сессия наследует эффективное значение конфигурации по умолчанию (messages.responseUsage). Если значение по умолчанию не настроено, футер выключен (как и раньше). Используйте это, чтобы “вернуться к значению по умолчанию”, не включая футер явно.
  • Полный сброс сессии (/reset или /new) или rollover сессии сохраняет явное предпочтение режима использования, чтобы выбор отображения пользователя переживал rollover сессии. Только /usage reset (и его алиасы) действительно очищает переопределение.

Поведение переключателя

/usage без аргументов циклически переключает: off → tokens → full → off. Начальная точка цикла — эффективный текущий режим (переопределение сессии с переходом к значению конфигурации по умолчанию, если оно не задано), поэтому цикл всегда согласуется с тем, что пользователь видит в футере.

Конфигурация

Без конфигурации сохраняется прежнее поведение (футер выключен до /usage). Используйте /usage reset, чтобы очистить сессионное переопределение и снова унаследовать настроенное значение по умолчанию.

Пользовательский футер /usage full

/usage full показывает встроенный компактный футер с моделью, reasoning, fast/slow, окном контекста, токенами хода, кэшем и стоимостью, когда эти поля доступны. Файл шаблона не требуется. messages.usageTemplate предназначен только для расширенных пользовательских макетов. Значение — это путь к JSON-файлу (поддерживает ~) или inline-объект, и при валидности оно заменяет встроенный футер:
{
  "messages": {
    "usageTemplate": "~/.openclaw/usage-footer.json"
  }
}
Отсутствующие или пустые шаблоны тихо откатываются к встроенному футеру. Нечитаемые или недействительные настроенные шаблоны также откатываются к встроенному футеру и выводят предупреждение оператору. Начните пользовательские шаблоны со встроенной формы, затем измените нужные части:
{
  "schema": "openclaw.usageBar.v1",
  "scales": {
    "braille": "⠐⡀⡄⡆⡇⣇⣧⣷⣿",
    "block": "░▏▎▍▌▋▊▉█",
    "shade": "░▒▓█",
    "moon": "🌑🌘🌗🌖🌕",
    "level": "▁▂▃▄▅▆▇█",
    "weather": ["🥶", "☁️", "🌥", "⛅️", "🌤", "☀️"],
    "plants": ["🪾", "🍂", "🌱", "☘️", "🍀", "🌿"],
    "moons6": ["🌑", "🌚", "🌘", "🌗", "🌖", "🌝"],
  },
  "aliases": {
    "models": {
      "claude-opus-4-6": "opus46",
      "claude-opus-4-8": "opus48",
      "claude-sonnet-4-6": "sonnet46",
      "claude-haiku-4-5": "haiku45",
      "gpt-5.5": "gpt5.5",
    },
    "reasoning": {
      "off": "🌑",
      "minimal": "🌚",
      "low": "🌘",
      "medium": "🌗",
      "high": "🌕",
      "xhigh": "🌝",
    },
  },
  "output": {
    "sep": "",
    "default": [
      { "text": "{model.provider}{identity.emoji|🤖} {model.display_name|alias:models}" },
      { "map": "model.is_fallback", "cases": { "true": " 🔄" } },
      { "map": "model.is_override", "cases": { "true": " 📌" } },
      { "when": "model.reasoning", "text": " {model.reasoning|alias:reasoning}" },
      { "map": "state.fast_mode", "cases": { "true": " ⚡", "false": " 🐌" } },
      {
        "when": "context.max_tokens",
        "text": " | 📚 [{context.pct_used|meter:5:braille}]{context.max_tokens|num}",
      },
      {
        "when": "usage.has_split_tokens",
        "text": " ↕️ {usage.input_tokens|num|?}/{usage.output_tokens|num|?}",
      },
      { "when": "usage.has_total_only_tokens", "text": " ↕️ {usage.total_tokens|num}" },
      { "when": "usage.cache_hit_pct", "text": " 🗄 {usage.cache_hit_pct|pct}" },
      { "when": "cost.turn_usd", "text": " 💰{cost.turn_usd|fixed:4}" },
    ],
    "surfaces": {
      "discord": [
        { "text": "-# -\n" },
        { "text": "-# {model.provider}{identity.emoji|🤖} {model.display_name|alias:models}" },
        { "map": "model.is_fallback", "cases": { "true": "🔄" } },
        { "map": "model.is_override", "cases": { "true": "📌" } },
        { "when": "model.reasoning", "text": " {model.reasoning|alias:reasoning}" },
        { "map": "state.fast_mode", "cases": { "true": " ⚡️", "false": " 🐌" } },
        {
          "when": "context.max_tokens",
          "text": " | 📚 [{context.pct_used|meter:5:braille}]{context.max_tokens|num}",
        },
        {
          "when": "usage.has_split_tokens",
          "text": " ↕️ {usage.input_tokens|num|?}/{usage.output_tokens|num|?}",
        },
        { "when": "usage.has_total_only_tokens", "text": " ↕️ {usage.total_tokens|num}" },
        { "when": "usage.cache_hit_pct", "text": " 🗄 {usage.cache_hit_pct|pct}" },
        { "when": "cost.turn_usd", "text": " 💰{cost.turn_usd|fixed:4}" },
      ],
    },
  },
}

Форма

{
  "schema": "openclaw.usageBar.v1",
  "scales": { "<name>": "low-to-high glyphs" }, // string (1 glyph/char) or array
  "aliases": { "<table>": { "<value>": "<label>" } },
  "output": {
    "sep": "", // joins surviving pieces
    "default": [
      /* pieces */
    ], // fallback for any surface
    "surfaces": {
      "discord": [
        /* pieces */
      ],
      "telegram": [
        /* pieces */
      ],
    },
  },
}
Каждая поверхность — это упорядоченный список фрагментов; движок рендерит каждый, отбрасывает пустые и соединяет оставшиеся через sep. Поверхность без записи использует output.default.

Пути контракта

Фрагмент читает значения из контракта для каждого хода по dot-path. Отсутствующие значения пусты (поэтому guard when или |fallback сохраняет фрагмент чистым).
ПутьЗначение
surfaceid канала (discord/telegram/и т. д.)
model.provider / model.display_nameid провайдера / id модели
model.reasoningeffort (от off до xhigh)
model.is_fallback / model.is_overridebool: использован fallback / модель закреплена
state.fast_modebool: fast или slow
context.max_tokens / context.pct_usedбюджет окна / 0-100 использовано
usage.input_tokens / usage.output_tokens / usage.total_tokensагрегат хода
usage.has_split_tokens / usage.has_total_only_tokens / usage.cache_hit_pctguards отображения токенов и процент кэша
usage.last.input_tokens / usage.last.output_tokens / usage.last.cache_hit_pctтолько финальный вызов модели
cost.turn_usdрасчетная стоимость хода
identity.name / identity.emojiимя агента / выбранный эмодзи
(Окна rate-limit провайдера не входят в этот контракт.)

Глаголы

Пропускайте значение через глаголы слева направо; сегмент, не являющийся глаголом, — это fallback.
ГлаголЭффектПример
numкомпактный счетчик272000 -> 272k
fixed:NN десятичных знаков (по умолчанию 2)0.0377
durсекунды в длительность14820 -> 4h07m
pctдобавить %96 -> 96%
inv100 - xиз использованного в оставшееся
alias:TABLEпоиск в aliases, эхо, если нет в спискеmedium -> 🌗
meter:W:SCALEW-ячеечная glyph-полоса по значению 0-100[⣿⣿⠐⠐⠐] (meter:1 = один glyph)

Формы фрагментов

  • { "text": "📚 {context.max_tokens|num}" }: литерал + интерполяция.
  • { "when": "<path>", "text": "..." }: рендерить только если путь truthy.
  • { "map": "<path>", "cases": { "true": "⚡", "false": "🐌" } }: значение в glyph.
  • { "each": "limits.windows", "item": "{label}" }: итерация по массиву.

Пример

{
  "schema": "openclaw.usageBar.v1",
  "scales": { "braille": "⠐⡀⡄⡆⡇⣇⣧⣷⣿" },
  "aliases": { "reasoning": { "medium": "🌗", "high": "🌕" } },
  "output": {
    "surfaces": {
      "discord": [
        { "text": "{model.display_name}" },
        { "when": "model.reasoning", "text": " {model.reasoning|alias:reasoning}" },
        { "map": "state.fast_mode", "cases": { "true": " ⚡", "false": " 🐌" } },
        {
          "when": "context.max_tokens",
          "text": " | 📚 [{context.pct_used|meter:5:braille}]{context.max_tokens|num}",
        },
      ],
    },
  },
}
отображается, например, как claude-sonnet-4-6 🌗 🐌 | 📚 [⣿⣿⣿⣿⣧]272k.

Провайдеры + учетные данные

  • Anthropic (Claude): токены OAuth в профилях аутентификации.
  • GitHub Copilot: токены OAuth в профилях аутентификации.
  • Gemini CLI: токены OAuth в профилях аутентификации.
    • Использование JSON откатывается к stats; stats.cached нормализуется в cacheRead.
  • OpenAI Codex: токены OAuth в профилях аутентификации (accountId используется, когда присутствует).
  • MiniMax: ключ API или профиль аутентификации MiniMax OAuth. OpenClaw рассматривает minimax, minimax-cn и minimax-portal как одну и ту же поверхность квоты MiniMax, предпочитает сохраненный MiniMax OAuth, когда он присутствует, а в остальных случаях откатывается к MINIMAX_CODE_PLAN_KEY, MINIMAX_CODING_API_KEY или MINIMAX_API_KEY. Опрос использования выводит хост Coding Plan из models.providers.minimax-portal.baseUrl или models.providers.minimax.baseUrl, когда они настроены, а в остальных случаях использует хост MiniMax CN. Необработанные поля MiniMax usage_percent / usagePercent означают оставшуюся квоту, поэтому OpenClaw инвертирует их перед отображением; поля на основе счетчиков имеют приоритет, когда присутствуют.
    • Метки окна Coding Plan берутся из полей часов/минут провайдера, когда присутствуют, затем откатываются к интервалу start_time / end_time.
    • Если конечная точка Coding Plan возвращает model_remains, OpenClaw предпочитает запись модели чата, выводит метку окна из временных меток, когда явные поля window_hours / window_minutes отсутствуют, и включает имя модели в метку плана.
  • Xiaomi MiMo: ключ API через хранилище env/config/auth (XIAOMI_API_KEY).
  • z.ai: ключ API через хранилище env/config/auth.
  • DeepSeek: ключ API через хранилище env/config/auth (DEEPSEEK_API_KEY). OpenClaw вызывает конечную точку баланса DeepSeek и показывает сообщенный провайдером баланс как текст вместо окна квоты с оставшимся процентом.
Использование скрывается, когда не удается определить пригодную аутентификацию использования провайдера. Провайдеры могут предоставлять логику аутентификации использования, специфичную для Plugin; в остальных случаях OpenClaw откатывается к сопоставлению учетных данных OAuth/ключа API из профилей аутентификации, переменных среды или конфигурации.

Связанные материалы