@trydecember/cli 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/december.js +1237 -411
  2. package/package.json +1 -1
package/dist/december.js CHANGED
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "@trydecember/cli",
68
- version: "0.4.0",
68
+ version: "0.4.1",
69
69
  description: "a coding agent for terminal and cloud.",
70
70
  homepage: "https://trydecember.com",
71
71
  repository: {
@@ -65004,6 +65004,30 @@ function decomposeContext(options) {
65004
65004
  }
65005
65005
 
65006
65006
  // ../../packages/shared/src/usage-rates.ts
65007
+ function resolveModelRate(modelName, customCache) {
65008
+ const normalized = (modelName || "").trim().toLowerCase();
65009
+ const stripped = normalized.includes("/") ? normalized.split("/").pop() : normalized;
65010
+ if (customCache) {
65011
+ if (customCache.has(normalized))
65012
+ return customCache.get(normalized);
65013
+ if (customCache.has(stripped))
65014
+ return customCache.get(stripped);
65015
+ }
65016
+ if (OFFICIAL_MODEL_RATES[normalized])
65017
+ return OFFICIAL_MODEL_RATES[normalized];
65018
+ if (OFFICIAL_MODEL_RATES[stripped])
65019
+ return OFFICIAL_MODEL_RATES[stripped];
65020
+ if (normalized.includes("ollama") || stripped.includes("llama") || stripped.includes("qwen")) {
65021
+ return { name: modelName, inputRate: 0, outputRate: 0 };
65022
+ }
65023
+ const fallbackInput = parseFloat(process.env.FALLBACK_MODEL_INPUT_RATE ?? "2.00");
65024
+ const fallbackOutput = parseFloat(process.env.FALLBACK_MODEL_OUTPUT_RATE ?? "8.00");
65025
+ return {
65026
+ name: modelName,
65027
+ inputRate: isNaN(fallbackInput) ? 2 : fallbackInput,
65028
+ outputRate: isNaN(fallbackOutput) ? 8 : fallbackOutput
65029
+ };
65030
+ }
65007
65031
  function formatInsufficientCreditsNotice(provider, model, rawErrorMsg) {
65008
65032
  const rawLower = (rawErrorMsg || "").toLowerCase();
65009
65033
  let normalized = (provider || "").toLowerCase().trim();
@@ -65224,8 +65248,471 @@ function getCleanProviderDisplayName(providerId, model) {
65224
65248
  }
65225
65249
  return id.charAt(0).toUpperCase() + id.slice(1);
65226
65250
  }
65227
- var PROVIDER_BILLING_LINKS, PROVIDER_DISPLAY_NAMES;
65251
+ var OFFICIAL_MODEL_RATES, PROVIDER_BILLING_LINKS, PROVIDER_DISPLAY_NAMES;
65228
65252
  var init_usage_rates = __esm(() => {
65253
+ OFFICIAL_MODEL_RATES = {
65254
+ "december-auto": { name: "december-auto", inputRate: 0.1, outputRate: 0.4 },
65255
+ "gemini-3.8-flash": { name: "gemini-3.8-flash", inputRate: 0.1, outputRate: 0.4 },
65256
+ "gemini-3.7-flash": { name: "gemini-3.7-flash", inputRate: 0.1, outputRate: 0.4 },
65257
+ "gemini-3.6-flash": { name: "gemini-3.6-flash", inputRate: 0.1, outputRate: 0.4 },
65258
+ "gemini-3.5-flash": { name: "gemini-3.5-flash", inputRate: 0.1, outputRate: 0.4 },
65259
+ "gemini-3.5-flash-lite": { name: "gemini-3.5-flash-lite", inputRate: 0.05, outputRate: 0.2 },
65260
+ "gemini-2.5-flash": { name: "gemini-2.5-flash", inputRate: 0.075, outputRate: 0.3 },
65261
+ "gemini-2.5-pro": { name: "gemini-2.5-pro", inputRate: 1.25, outputRate: 5 },
65262
+ "gemini-3-pro-preview": { name: "gemini-3-pro-preview", inputRate: 1.25, outputRate: 5 },
65263
+ "gemini-3.1-pro": { name: "gemini-3.1-pro", inputRate: 1.25, outputRate: 5 },
65264
+ "claude-3-7-sonnet": { name: "claude-3-7-sonnet", inputRate: 3, outputRate: 15 },
65265
+ "claude-3-7-sonnet-latest": {
65266
+ name: "claude-3-7-sonnet-latest",
65267
+ inputRate: 3,
65268
+ outputRate: 15
65269
+ },
65270
+ "claude-3-5-sonnet": { name: "claude-3-5-sonnet", inputRate: 3, outputRate: 15 },
65271
+ "claude-3-5-sonnet-latest": {
65272
+ name: "claude-3-5-sonnet-latest",
65273
+ inputRate: 3,
65274
+ outputRate: 15
65275
+ },
65276
+ "claude-3-5-haiku": { name: "claude-3-5-haiku", inputRate: 0.8, outputRate: 4 },
65277
+ "claude-3-5-haiku-latest": {
65278
+ name: "claude-3-5-haiku-latest",
65279
+ inputRate: 0.8,
65280
+ outputRate: 4
65281
+ },
65282
+ "claude-3-opus": { name: "claude-3-opus", inputRate: 15, outputRate: 75 },
65283
+ "claude-3-opus-latest": { name: "claude-3-opus-latest", inputRate: 15, outputRate: 75 },
65284
+ "gpt-4o": { name: "gpt-4o", inputRate: 2.5, outputRate: 10 },
65285
+ "gpt-4o-mini": { name: "gpt-4o-mini", inputRate: 0.15, outputRate: 0.6 },
65286
+ "gpt-4.5-preview": { name: "gpt-4.5-preview", inputRate: 75, outputRate: 150 },
65287
+ "o3-mini": { name: "o3-mini", inputRate: 1.1, outputRate: 4.4 },
65288
+ o1: { name: "o1", inputRate: 15, outputRate: 60 },
65289
+ "o1-mini": { name: "o1-mini", inputRate: 1.1, outputRate: 4.4 },
65290
+ "deepseek-chat": { name: "deepseek-chat", inputRate: 0.14, outputRate: 0.28 },
65291
+ "deepseek-v3": { name: "deepseek-v3", inputRate: 0.14, outputRate: 0.28 },
65292
+ "deepseek-reasoner": { name: "deepseek-reasoner", inputRate: 0.55, outputRate: 2.19 },
65293
+ "deepseek-r1": { name: "deepseek-r1", inputRate: 0.55, outputRate: 2.19 },
65294
+ "muse-spark-1.3": { name: "muse-spark-1.3", inputRate: 1.25, outputRate: 4.25 },
65295
+ "muse-spark-1.3-contributor": {
65296
+ name: "muse-spark-1.3-contributor",
65297
+ inputRate: 0.1,
65298
+ outputRate: 0.2
65299
+ },
65300
+ "muse-spark-1.2": { name: "muse-spark-1.2", inputRate: 1.25, outputRate: 4.25 },
65301
+ "muse-spark-1.2-contributor": {
65302
+ name: "muse-spark-1.2-contributor",
65303
+ inputRate: 0.1,
65304
+ outputRate: 0.2
65305
+ },
65306
+ "muse-spark-1.1": { name: "muse-spark-1.1", inputRate: 1.25, outputRate: 4.25 },
65307
+ "minimax-m3": { name: "minimax-m3", inputRate: 0.3, outputRate: 1.2 },
65308
+ "minimax-m2.7": { name: "minimax-m2.7", inputRate: 0.3, outputRate: 1.2 },
65309
+ "minimax-m2.7-highspeed": { name: "minimax-m2.7-highspeed", inputRate: 0.6, outputRate: 2.4 },
65310
+ "minimax-m2.5": { name: "minimax-m2.5", inputRate: 0.3, outputRate: 1.2 },
65311
+ "minimax-m2.5-highspeed": { name: "minimax-m2.5-highspeed", inputRate: 0.6, outputRate: 2.4 },
65312
+ "minimax-m2.1": { name: "minimax-m2.1", inputRate: 0.3, outputRate: 1.2 },
65313
+ "minimax-m2.1-highspeed": { name: "minimax-m2.1-highspeed", inputRate: 0.6, outputRate: 2.4 },
65314
+ "minimax-m2": { name: "minimax-m2", inputRate: 0.3, outputRate: 1.2 },
65315
+ "minimax-text-01": { name: "minimax-text-01", inputRate: 0.15, outputRate: 1.2 },
65316
+ "minimax-vl-01": { name: "minimax-vl-01", inputRate: 0.15, outputRate: 1.2 },
65317
+ "kimi-k3": { name: "kimi-k3", inputRate: 3, outputRate: 15 },
65318
+ "moonshotai/kimi-k3": { name: "moonshotai/kimi-k3", inputRate: 3, outputRate: 15 },
65319
+ "kimi-k2.7-code": { name: "kimi-k2.7-code", inputRate: 0.95, outputRate: 4 },
65320
+ "kimi-k2.7-code-highspeed": {
65321
+ name: "kimi-k2.7-code-highspeed",
65322
+ inputRate: 1.9,
65323
+ outputRate: 8
65324
+ },
65325
+ "kimi-k2.6": { name: "kimi-k2.6", inputRate: 0.95, outputRate: 4 },
65326
+ "kimi-k2.5": { name: "kimi-k2.5", inputRate: 0.95, outputRate: 4 },
65327
+ "mistral-large-latest": { name: "mistral-large-latest", inputRate: 0.5, outputRate: 1.5 },
65328
+ "mistral-large-2512": { name: "mistral-large-2512", inputRate: 0.5, outputRate: 1.5 },
65329
+ "mistral-medium-latest": { name: "mistral-medium-latest", inputRate: 1.5, outputRate: 7.5 },
65330
+ "mistral-medium-2604": { name: "mistral-medium-2604", inputRate: 1.5, outputRate: 7.5 },
65331
+ "mistral-small-latest": { name: "mistral-small-latest", inputRate: 0.15, outputRate: 0.6 },
65332
+ "mistral-small-2603": { name: "mistral-small-2603", inputRate: 0.15, outputRate: 0.6 },
65333
+ "codestral-latest": { name: "codestral-latest", inputRate: 0.3, outputRate: 0.9 },
65334
+ "codestral-2501": { name: "codestral-2501", inputRate: 0.3, outputRate: 0.9 },
65335
+ "devstral-2512": { name: "devstral-2512", inputRate: 0.4, outputRate: 2 },
65336
+ "devstral-latest": { name: "devstral-latest", inputRate: 0.4, outputRate: 2 },
65337
+ "magistral-medium-latest": {
65338
+ name: "magistral-medium-latest",
65339
+ inputRate: 2,
65340
+ outputRate: 5
65341
+ },
65342
+ "magistral-small": { name: "magistral-small", inputRate: 0.5, outputRate: 1.5 },
65343
+ "ministral-8b-latest": { name: "ministral-8b-latest", inputRate: 0.1, outputRate: 0.1 },
65344
+ "ministral-3b-latest": { name: "ministral-3b-latest", inputRate: 0.04, outputRate: 0.04 },
65345
+ "mistral-nemo": { name: "mistral-nemo", inputRate: 0.15, outputRate: 0.15 },
65346
+ "sarvam-105b": { name: "sarvam-105b", inputRate: 0.75, outputRate: 3 },
65347
+ "sarvam-30b": { name: "sarvam-30b", inputRate: 0.25, outputRate: 1 },
65348
+ "step-3.7-flash": { name: "step-3.7-flash", inputRate: 0.1, outputRate: 0.4 },
65349
+ "step-3.5-flash": { name: "step-3.5-flash", inputRate: 0.1, outputRate: 0.4 },
65350
+ "step-1-32k": { name: "step-1-32k", inputRate: 0.2, outputRate: 0.8 },
65351
+ "solar-pro4": { name: "solar-pro4", inputRate: 0.25, outputRate: 0.25 },
65352
+ "solar-pro3": { name: "solar-pro3", inputRate: 0.25, outputRate: 0.25 },
65353
+ "solar-pro2": { name: "solar-pro2", inputRate: 0.25, outputRate: 0.25 },
65354
+ "solar-mini": { name: "solar-mini", inputRate: 0.15, outputRate: 0.15 },
65355
+ "thinkingmachines/inkling": {
65356
+ name: "thinkingmachines/Inkling",
65357
+ inputRate: 2,
65358
+ outputRate: 6
65359
+ },
65360
+ "thinkingmachines/inkling:peft:262144": {
65361
+ name: "thinkingmachines/Inkling:peft:262144",
65362
+ inputRate: 2.5,
65363
+ outputRate: 7.5
65364
+ },
65365
+ inkling: { name: "thinkingmachines/Inkling", inputRate: 2, outputRate: 6 },
65366
+ "grok-4.6": { name: "grok-4.6", inputRate: 2, outputRate: 6 },
65367
+ "grok-4.5": { name: "grok-4.5", inputRate: 2, outputRate: 6 },
65368
+ "grok-4.3": { name: "grok-4.3", inputRate: 1.25, outputRate: 2.5 },
65369
+ "grok-4.20": { name: "grok-4.20", inputRate: 1.25, outputRate: 2.5 },
65370
+ "grok-4.20-0309-reasoning": {
65371
+ name: "grok-4.20-0309-reasoning",
65372
+ inputRate: 1.25,
65373
+ outputRate: 2.5
65374
+ },
65375
+ "grok-4.20-0309-non-reasoning": {
65376
+ name: "grok-4.20-0309-non-reasoning",
65377
+ inputRate: 1.25,
65378
+ outputRate: 2.5
65379
+ },
65380
+ "grok-4.1-fast": { name: "grok-4.1-fast", inputRate: 0.2, outputRate: 0.5 },
65381
+ "grok-4.1-fast-reasoning": { name: "grok-4.1-fast-reasoning", inputRate: 0.2, outputRate: 0.5 },
65382
+ "grok-build-0.1": { name: "grok-build-0.1", inputRate: 1, outputRate: 2 },
65383
+ "glm-5.3-flash": { name: "glm-5.3-flash", inputRate: 0.075, outputRate: 0.25 },
65384
+ "glm-5.3": { name: "glm-5.3", inputRate: 1.4, outputRate: 4.4 },
65385
+ "glm-5.2": { name: "glm-5.2", inputRate: 1.4, outputRate: 4.4 },
65386
+ "zai-org/glm-5.2": { name: "zai-org/glm-5.2", inputRate: 1.4, outputRate: 4.4 },
65387
+ "glm-5.1": { name: "glm-5.1", inputRate: 1.4, outputRate: 4.4 },
65388
+ "glm-5": { name: "glm-5", inputRate: 1, outputRate: 3.2 },
65389
+ "glm-5-turbo": { name: "glm-5-turbo", inputRate: 5, outputRate: 22 },
65390
+ "glm-5v-turbo": { name: "glm-5v-turbo", inputRate: 5, outputRate: 22 },
65391
+ "glm-4.7": { name: "glm-4.7", inputRate: 0.6, outputRate: 2.2 },
65392
+ "glm-4.7-flash": { name: "glm-4.7-flash", inputRate: 0, outputRate: 0 },
65393
+ "glm-4.7-flashx": { name: "glm-4.7-flashx", inputRate: 0.07, outputRate: 0.4 },
65394
+ "glm-4.6": { name: "glm-4.6", inputRate: 0.6, outputRate: 2.2 },
65395
+ "glm-4.6v": { name: "glm-4.6v", inputRate: 0.3, outputRate: 0.9 },
65396
+ "glm-4.5": { name: "glm-4.5", inputRate: 0.6, outputRate: 2.2 },
65397
+ "glm-4.5-air": { name: "glm-4.5-air", inputRate: 0.2, outputRate: 1.1 },
65398
+ "glm-4.5-flash": { name: "glm-4.5-flash", inputRate: 0, outputRate: 0 },
65399
+ "glm-4.5v": { name: "glm-4.5v", inputRate: 0.6, outputRate: 1.8 },
65400
+ "glm-4-plus": { name: "glm-4-plus", inputRate: 1.4, outputRate: 4.4 },
65401
+ "glm-4-flash": { name: "glm-4-flash", inputRate: 0, outputRate: 0 },
65402
+ "mimo-v2.5": { name: "mimo-v2.5", inputRate: 0.14, outputRate: 0.28 },
65403
+ "mimo-v2.5-pro": { name: "mimo-v2.5-pro", inputRate: 0.435, outputRate: 0.87 },
65404
+ "mimo-v2.5-pro-ultraspeed": {
65405
+ name: "mimo-v2.5-pro-ultraspeed",
65406
+ inputRate: 1.305,
65407
+ outputRate: 2.61
65408
+ },
65409
+ "mimo-v2-flash": { name: "mimo-v2-flash", inputRate: 0.14, outputRate: 0.28 },
65410
+ "mimo-v2-omni": { name: "mimo-v2-omni", inputRate: 0.14, outputRate: 0.28 },
65411
+ "mimo-v2-pro": { name: "mimo-v2-pro", inputRate: 0.435, outputRate: 0.87 },
65412
+ "xiaomi/mimo-v2.5": { name: "xiaomi/mimo-v2.5", inputRate: 0.14, outputRate: 0.28 },
65413
+ "xiaomi/mimo-v2.5-pro": { name: "xiaomi/mimo-v2.5-pro", inputRate: 0.435, outputRate: 0.87 },
65414
+ "xiaomi/mimo-v2.5-pro-ultraspeed": {
65415
+ name: "xiaomi/mimo-v2.5-pro-ultraspeed",
65416
+ inputRate: 1.305,
65417
+ outputRate: 2.61
65418
+ },
65419
+ "xiaomi/mimo-v2-flash": { name: "xiaomi/mimo-v2-flash", inputRate: 0.14, outputRate: 0.28 },
65420
+ "xiaomi/mimo-v2-omni": { name: "xiaomi/mimo-v2-omni", inputRate: 0.14, outputRate: 0.28 },
65421
+ "xiaomi/mimo-v2-pro": { name: "xiaomi/mimo-v2-pro", inputRate: 0.435, outputRate: 0.87 },
65422
+ "abliterated-model": { name: "abliterated-model", inputRate: 3, outputRate: 3 },
65423
+ "abliterated-model-large": { name: "abliterated-model-large", inputRate: 5, outputRate: 5 },
65424
+ "abliterated-model-large-v2": {
65425
+ name: "abliterated-model-large-v2",
65426
+ inputRate: 5,
65427
+ outputRate: 5
65428
+ },
65429
+ "abliteration/abliterated-model": {
65430
+ name: "abliteration/abliterated-model",
65431
+ inputRate: 3,
65432
+ outputRate: 3
65433
+ },
65434
+ "abliteration/abliterated-model-large": {
65435
+ name: "abliteration/abliterated-model-large",
65436
+ inputRate: 5,
65437
+ outputRate: 5
65438
+ },
65439
+ "abliteration/abliterated-model-large-v2": {
65440
+ name: "abliteration/abliterated-model-large-v2",
65441
+ inputRate: 5,
65442
+ outputRate: 5
65443
+ },
65444
+ "agnes-3.0-flash": { name: "agnes-3.0-flash", inputRate: 0.05, outputRate: 0.15 },
65445
+ "agnes-2.5-pro": { name: "agnes-2.5-pro", inputRate: 0.45, outputRate: 0.9 },
65446
+ "agnes-2.5-flash": { name: "agnes-2.5-flash", inputRate: 0.05, outputRate: 0.15 },
65447
+ "agnes-2.5-pro-beta": { name: "agnes-2.5-pro-beta", inputRate: 0.1, outputRate: 0.3 },
65448
+ "agnes/agnes-3.0-flash": { name: "agnes/agnes-3.0-flash", inputRate: 0.05, outputRate: 0.15 },
65449
+ "agnes/agnes-2.5-pro": { name: "agnes/agnes-2.5-pro", inputRate: 0.45, outputRate: 0.9 },
65450
+ "agnes/agnes-2.5-flash": { name: "agnes/agnes-2.5-flash", inputRate: 0.05, outputRate: 0.15 },
65451
+ "agnes/agnes-2.5-pro-beta": {
65452
+ name: "agnes/agnes-2.5-pro-beta",
65453
+ inputRate: 0.1,
65454
+ outputRate: 0.3
65455
+ },
65456
+ "gpt-5.6-luna": { name: "gpt-5.6-luna", inputRate: 1, outputRate: 6 },
65457
+ "gpt-5.6-terra": { name: "gpt-5.6-terra", inputRate: 2.5, outputRate: 15 },
65458
+ "gpt-5.6-sol": { name: "gpt-5.6-sol", inputRate: 5, outputRate: 30 },
65459
+ "gpt-5.4": { name: "gpt-5.4", inputRate: 2.5, outputRate: 15 },
65460
+ "gpt-5.5": { name: "gpt-5.5", inputRate: 5, outputRate: 30 },
65461
+ "airouter/gpt-5.6-luna": { name: "airouter/gpt-5.6-luna", inputRate: 1, outputRate: 6 },
65462
+ "airouter/gpt-5.6-terra": { name: "airouter/gpt-5.6-terra", inputRate: 2.5, outputRate: 15 },
65463
+ "airouter/gpt-5.6-sol": { name: "airouter/gpt-5.6-sol", inputRate: 5, outputRate: 30 },
65464
+ "airouter/gpt-5.4": { name: "airouter/gpt-5.4", inputRate: 2.5, outputRate: 15 },
65465
+ "airouter/gpt-5.5": { name: "airouter/gpt-5.5", inputRate: 5, outputRate: 30 },
65466
+ "deepseek-ai/deepseek-v4-flash": {
65467
+ name: "deepseek-ai/deepseek-v4-flash",
65468
+ inputRate: 0.15,
65469
+ outputRate: 0.25
65470
+ },
65471
+ "deepseek-ai/deepseek-v4-pro": {
65472
+ name: "deepseek-ai/deepseek-v4-pro",
65473
+ inputRate: 1,
65474
+ outputRate: 2.5
65475
+ },
65476
+ "zai-org/glm-5.3": { name: "zai-org/glm-5.3", inputRate: 1, outputRate: 4 },
65477
+ "moonshotai/kimi-k2.7-code": {
65478
+ name: "moonshotai/kimi-k2.7-code",
65479
+ inputRate: 0.75,
65480
+ outputRate: 3.5
65481
+ },
65482
+ "google/gemma-4-31b-it": { name: "google/gemma-4-31b-it", inputRate: 0.2, outputRate: 0.5 },
65483
+ "openai/gpt-oss-120b": { name: "openai/gpt-oss-120b", inputRate: 0.15, outputRate: 0.6 },
65484
+ "motif-technologies/motif-3": {
65485
+ name: "motif-technologies/motif-3",
65486
+ inputRate: 0.5,
65487
+ outputRate: 2
65488
+ },
65489
+ "qwen/qwen3.8-27b": { name: "qwen/qwen3.8-27b", inputRate: 0.4, outputRate: 3 },
65490
+ "aiand/deepseek-ai/deepseek-v4-flash": {
65491
+ name: "aiand/deepseek-ai/deepseek-v4-flash",
65492
+ inputRate: 0.15,
65493
+ outputRate: 0.25
65494
+ },
65495
+ "aiand/deepseek-ai/deepseek-v4-pro": {
65496
+ name: "aiand/deepseek-ai/deepseek-v4-pro",
65497
+ inputRate: 1,
65498
+ outputRate: 2.5
65499
+ },
65500
+ "aiand/zai-org/glm-5.3": { name: "aiand/zai-org/glm-5.3", inputRate: 1, outputRate: 4 },
65501
+ "aiand/zai-org/glm-5.2": { name: "aiand/zai-org/glm-5.2", inputRate: 1, outputRate: 4 },
65502
+ "aiand/moonshotai/kimi-k2.7-code": {
65503
+ name: "aiand/moonshotai/kimi-k2.7-code",
65504
+ inputRate: 0.75,
65505
+ outputRate: 3.5
65506
+ },
65507
+ "aiand/moonshotai/kimi-k3": {
65508
+ name: "aiand/moonshotai/kimi-k3",
65509
+ inputRate: 3,
65510
+ outputRate: 12.5
65511
+ },
65512
+ "aiand/google/gemma-4-31b-it": {
65513
+ name: "aiand/google/gemma-4-31b-it",
65514
+ inputRate: 0.2,
65515
+ outputRate: 0.5
65516
+ },
65517
+ "aiand/openai/gpt-oss-120b": {
65518
+ name: "aiand/openai/gpt-oss-120b",
65519
+ inputRate: 0.15,
65520
+ outputRate: 0.6
65521
+ },
65522
+ "aiand/motif-technologies/motif-3": {
65523
+ name: "aiand/motif-technologies/motif-3",
65524
+ inputRate: 0.5,
65525
+ outputRate: 2
65526
+ },
65527
+ "aiand/qwen/qwen3.8-27b": { name: "aiand/qwen/qwen3.8-27b", inputRate: 0.4, outputRate: 3 },
65528
+ "deepseek-v4-flash-0731-284b": {
65529
+ name: "deepseek-v4-flash-0731-284b",
65530
+ inputRate: 0.2,
65531
+ outputRate: 0.5
65532
+ },
65533
+ "glm5.3-754b": { name: "glm5.3-754b", inputRate: 1, outputRate: 3.5 },
65534
+ "gemma4-26b": { name: "gemma4-26b", inputRate: 0.1, outputRate: 0.5 },
65535
+ "gpt-oss-120b": { name: "gpt-oss-120b", inputRate: 0.15, outputRate: 0.55 },
65536
+ "mistral4-119b": { name: "mistral4-119b", inputRate: 0.2, outputRate: 0.6 },
65537
+ "qwen3.8-27b": { name: "qwen3.8-27b", inputRate: 0.3, outputRate: 2.2 },
65538
+ "qwen3.6-35b": { name: "qwen3.6-35b", inputRate: 0.15, outputRate: 0.5 },
65539
+ "aki/deepseek-v4-flash-0731-284b": {
65540
+ name: "aki/deepseek-v4-flash-0731-284b",
65541
+ inputRate: 0.2,
65542
+ outputRate: 0.5
65543
+ },
65544
+ "aki/glm5.3-754b": { name: "aki/glm5.3-754b", inputRate: 1, outputRate: 3.5 },
65545
+ "aki/gemma4-26b": { name: "aki/gemma4-26b", inputRate: 0.1, outputRate: 0.5 },
65546
+ "aki/gpt-oss-120b": { name: "aki/gpt-oss-120b", inputRate: 0.15, outputRate: 0.55 },
65547
+ "aki/mistral4-119b": { name: "aki/mistral4-119b", inputRate: 0.2, outputRate: 0.6 },
65548
+ "aki/qwen3.8-27b": { name: "aki/qwen3.8-27b", inputRate: 0.3, outputRate: 2.2 },
65549
+ "aki/qwen3.6-35b": { name: "aki/qwen3.6-35b", inputRate: 0.15, outputRate: 0.5 },
65550
+ "deepseek/deepseek-v4-flash": {
65551
+ name: "deepseek/deepseek-v4-flash",
65552
+ inputRate: 0.14,
65553
+ outputRate: 0.28
65554
+ },
65555
+ "deepseek/deepseek-v4-flash-0731": {
65556
+ name: "deepseek/deepseek-v4-flash-0731",
65557
+ inputRate: 0.08,
65558
+ outputRate: 0.18
65559
+ },
65560
+ "ambient/large": { name: "ambient/large", inputRate: 0.6, outputRate: 2 },
65561
+ "zai-org/GLM-5.2-FP8": { name: "zai-org/GLM-5.2-FP8", inputRate: 1.2, outputRate: 4.2 },
65562
+ "ambient/deepseek/deepseek-v4-flash": {
65563
+ name: "ambient/deepseek/deepseek-v4-flash",
65564
+ inputRate: 0.14,
65565
+ outputRate: 0.28
65566
+ },
65567
+ "ambient/deepseek/deepseek-v4-flash-0731": {
65568
+ name: "ambient/deepseek/deepseek-v4-flash-0731",
65569
+ inputRate: 0.08,
65570
+ outputRate: 0.18
65571
+ },
65572
+ "ambient/ambient/large": { name: "ambient/ambient/large", inputRate: 0.6, outputRate: 2 },
65573
+ "ambient/zai-org/GLM-5.2-FP8": {
65574
+ name: "ambient/zai-org/GLM-5.2-FP8",
65575
+ inputRate: 1.2,
65576
+ outputRate: 4.2
65577
+ },
65578
+ "ambient/moonshotai/kimi-k2.7-code": {
65579
+ name: "ambient/moonshotai/kimi-k2.7-code",
65580
+ inputRate: 0.69,
65581
+ outputRate: 3.49
65582
+ },
65583
+ "ambient/xiaomi/mimo-v2.5": {
65584
+ name: "ambient/xiaomi/mimo-v2.5",
65585
+ inputRate: 0.4,
65586
+ outputRate: 2
65587
+ },
65588
+ "ambient/stepfun/step-3.7-flash": {
65589
+ name: "ambient/stepfun/step-3.7-flash",
65590
+ inputRate: 0.19,
65591
+ outputRate: 1.14
65592
+ },
65593
+ "auriko/claude-sonnet-4-6": {
65594
+ name: "auriko/claude-sonnet-4-6",
65595
+ inputRate: 3,
65596
+ outputRate: 15
65597
+ },
65598
+ "auriko/claude-opus-4-6": { name: "auriko/claude-opus-4-6", inputRate: 5, outputRate: 25 },
65599
+ "auriko/claude-opus-4-7": { name: "auriko/claude-opus-4-7", inputRate: 5, outputRate: 25 },
65600
+ "auriko/deepseek-v4-flash": {
65601
+ name: "auriko/deepseek-v4-flash",
65602
+ inputRate: 0.14,
65603
+ outputRate: 0.28
65604
+ },
65605
+ "auriko/deepseek-v4-pro": { name: "auriko/deepseek-v4-pro", inputRate: 0.43, outputRate: 0.87 },
65606
+ "auriko/gemini-2.5-flash": { name: "auriko/gemini-2.5-flash", inputRate: 0.3, outputRate: 2.5 },
65607
+ "auriko/gemini-2.5-pro": { name: "auriko/gemini-2.5-pro", inputRate: 1.25, outputRate: 10 },
65608
+ "auriko/gemini-3.1-pro-preview": {
65609
+ name: "auriko/gemini-3.1-pro-preview",
65610
+ inputRate: 2,
65611
+ outputRate: 12
65612
+ },
65613
+ "auriko/glm-5.1": { name: "auriko/glm-5.1", inputRate: 1.4, outputRate: 4.4 },
65614
+ "auriko/grok-4.3": { name: "auriko/grok-4.3", inputRate: 1.25, outputRate: 2.5 },
65615
+ "auriko/kimi-k2.5": { name: "auriko/kimi-k2.5", inputRate: 0.5, outputRate: 2.8 },
65616
+ "auriko/kimi-k2.6": { name: "auriko/kimi-k2.6", inputRate: 0.95, outputRate: 4 },
65617
+ "auriko/minimax-m2-7": { name: "auriko/minimax-m2-7", inputRate: 0.3, outputRate: 1.2 },
65618
+ "auriko/minimax-m2-7-highspeed": {
65619
+ name: "auriko/minimax-m2-7-highspeed",
65620
+ inputRate: 0.6,
65621
+ outputRate: 2.4
65622
+ },
65623
+ "auriko/qwen-3.6-plus": { name: "auriko/qwen-3.6-plus", inputRate: 0.5, outputRate: 3 },
65624
+ "baseten/deepseek-ai/deepseek-v4.1-flash": {
65625
+ name: "baseten/deepseek-ai/deepseek-v4.1-flash",
65626
+ inputRate: 0.3,
65627
+ outputRate: 1.2
65628
+ },
65629
+ "baseten/deepseek-ai/deepseek-v4-flash-0731": {
65630
+ name: "baseten/deepseek-ai/deepseek-v4-flash-0731",
65631
+ inputRate: 0.13,
65632
+ outputRate: 0.26
65633
+ },
65634
+ "baseten/deepseek-ai/deepseek-v4-pro": {
65635
+ name: "baseten/deepseek-ai/deepseek-v4-pro",
65636
+ inputRate: 1.74,
65637
+ outputRate: 3.48
65638
+ },
65639
+ "baseten/deepseek-ai/deepseek-v4-pro-0813": {
65640
+ name: "baseten/deepseek-ai/deepseek-v4-pro-0813",
65641
+ inputRate: 1.32,
65642
+ outputRate: 3.96
65643
+ },
65644
+ "baseten/deepseek-ai/deepseek-v3.1": {
65645
+ name: "baseten/deepseek-ai/deepseek-v3.1",
65646
+ inputRate: 0.5,
65647
+ outputRate: 1.5
65648
+ },
65649
+ "baseten/zai-org/glm-5.3": { name: "baseten/zai-org/glm-5.3", inputRate: 1.4, outputRate: 4.4 },
65650
+ "baseten/zai-org/glm-5.3-fast": {
65651
+ name: "baseten/zai-org/glm-5.3-fast",
65652
+ inputRate: 2.1,
65653
+ outputRate: 6.6
65654
+ },
65655
+ "baseten/zai-org/glm-5.3-flash": {
65656
+ name: "baseten/zai-org/glm-5.3-flash",
65657
+ inputRate: 0.15,
65658
+ outputRate: 0.5
65659
+ },
65660
+ "baseten/zai-org/glm-5.2": { name: "baseten/zai-org/glm-5.2", inputRate: 1.4, outputRate: 4.4 },
65661
+ "baseten/zai-org/glm-5.2-fast": {
65662
+ name: "baseten/zai-org/glm-5.2-fast",
65663
+ inputRate: 2.1,
65664
+ outputRate: 6.6
65665
+ },
65666
+ "baseten/zai-org/glm-5.1": { name: "baseten/zai-org/glm-5.1", inputRate: 1.3, outputRate: 4.3 },
65667
+ "baseten/zai-org/glm-5": { name: "baseten/zai-org/glm-5", inputRate: 0.95, outputRate: 3.15 },
65668
+ "baseten/zai-org/glm-4.7": { name: "baseten/zai-org/glm-4.7", inputRate: 0.6, outputRate: 2.2 },
65669
+ "baseten/moonshotai/kimi-k2.7-code": {
65670
+ name: "baseten/moonshotai/kimi-k2.7-code",
65671
+ inputRate: 0.95,
65672
+ outputRate: 4
65673
+ },
65674
+ "baseten/moonshotai/kimi-k3": {
65675
+ name: "baseten/moonshotai/kimi-k3",
65676
+ inputRate: 3,
65677
+ outputRate: 15
65678
+ },
65679
+ "baseten/moonshotai/kimi-k2.6": {
65680
+ name: "baseten/moonshotai/kimi-k2.6",
65681
+ inputRate: 0.95,
65682
+ outputRate: 4
65683
+ },
65684
+ "baseten/moonshotai/kimi-k2.5": {
65685
+ name: "baseten/moonshotai/kimi-k2.5",
65686
+ inputRate: 0.6,
65687
+ outputRate: 3
65688
+ },
65689
+ "baseten/thinkingmachines/inkling": {
65690
+ name: "baseten/thinkingmachines/inkling",
65691
+ inputRate: 1,
65692
+ outputRate: 4.05
65693
+ },
65694
+ "baseten/thinkingmachines/inkling-small": {
65695
+ name: "baseten/thinkingmachines/inkling-small",
65696
+ inputRate: 0.5,
65697
+ outputRate: 1.2
65698
+ },
65699
+ "baseten/nvidia/nemotron-120b-a12b": {
65700
+ name: "baseten/nvidia/nemotron-120b-a12b",
65701
+ inputRate: 0.3,
65702
+ outputRate: 0.75
65703
+ },
65704
+ "baseten/nvidia/nvidia-nemotron-3-ultra-550b-a55b": {
65705
+ name: "baseten/nvidia/nvidia-nemotron-3-ultra-550b-a55b",
65706
+ inputRate: 0.6,
65707
+ outputRate: 2.4
65708
+ },
65709
+ "baseten/openai/gpt-oss-120b": {
65710
+ name: "baseten/openai/gpt-oss-120b",
65711
+ inputRate: 0.1,
65712
+ outputRate: 0.5
65713
+ },
65714
+ ollama: { name: "ollama", inputRate: 0, outputRate: 0 }
65715
+ };
65229
65716
  PROVIDER_BILLING_LINKS = {
65230
65717
  december: "https://app.trydecember.com/settings/billing",
65231
65718
  december_proxy: "https://app.trydecember.com/settings/billing",
@@ -216251,7 +216738,7 @@ function TextArea({
216251
216738
  use_input_default((input, key) => {
216252
216739
  if (!focus)
216253
216740
  return;
216254
- if (input.startsWith("[<") || input.startsWith("\x1B[<") || input.startsWith("\x1B[M")) {
216741
+ if (input.includes("[<") || input.includes("\x1B[<") || input.includes("\x1B[M")) {
216255
216742
  return;
216256
216743
  }
216257
216744
  const offset = Math.min(Math.max(0, cursorOffset), value.length);
@@ -217242,11 +217729,11 @@ var init_scroll_viewport = __esm(async () => {
217242
217729
  use_input_default((input, key) => {
217243
217730
  if (!isActive)
217244
217731
  return;
217245
- if (input.includes("[<64;")) {
217732
+ if (/\[<(?:64|68|72|80|84);/.test(input)) {
217246
217733
  handleScrollUp(3);
217247
217734
  return;
217248
217735
  }
217249
- if (input.includes("[<65;")) {
217736
+ if (/\[<(?:65|69|73|81|85);/.test(input)) {
217250
217737
  handleScrollDown(3);
217251
217738
  return;
217252
217739
  }
@@ -261887,7 +262374,8 @@ var init_header = __esm(async () => {
261887
262374
  Header = import_react53.default.memo(function Header({
261888
262375
  cliVersion = "0.1.0",
261889
262376
  latestVersion,
261890
- userEmail
262377
+ userEmail,
262378
+ announcement
261891
262379
  }) {
261892
262380
  const cwd = getCwd();
261893
262381
  const branch = getGitBranch();
@@ -261962,6 +262450,53 @@ var init_header = __esm(async () => {
261962
262450
  ]
261963
262451
  })
261964
262452
  ]
262453
+ }),
262454
+ announcement && /* @__PURE__ */ jsx_runtime19.jsxs(Box_default, {
262455
+ flexDirection: "column",
262456
+ marginTop: 1,
262457
+ children: [
262458
+ /* @__PURE__ */ jsx_runtime19.jsxs(Box_default, {
262459
+ children: [
262460
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262461
+ color: THEME.colors.brand,
262462
+ children: "▎ "
262463
+ }),
262464
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262465
+ bold: true,
262466
+ color: THEME.colors.text,
262467
+ children: announcement.title || `What's New in v${announcement.version}`
262468
+ })
262469
+ ]
262470
+ }),
262471
+ announcement.bullets.map((bullet, idx) => /* @__PURE__ */ jsx_runtime19.jsxs(Box_default, {
262472
+ children: [
262473
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262474
+ color: THEME.colors.brand,
262475
+ children: "▎ "
262476
+ }),
262477
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262478
+ color: THEME.colors.muted,
262479
+ children: bullet
262480
+ })
262481
+ ]
262482
+ }, idx)),
262483
+ announcement.url && /* @__PURE__ */ jsx_runtime19.jsxs(Box_default, {
262484
+ children: [
262485
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262486
+ color: THEME.colors.brand,
262487
+ children: "▎ "
262488
+ }),
262489
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262490
+ color: THEME.colors.muted,
262491
+ children: "Check out detailed changelog on "
262492
+ }),
262493
+ /* @__PURE__ */ jsx_runtime19.jsx(Text3, {
262494
+ color: THEME.colors.brand,
262495
+ children: terminalLink(announcement.url, announcement.url)
262496
+ })
262497
+ ]
262498
+ })
262499
+ ]
261965
262500
  })
261966
262501
  ]
261967
262502
  });
@@ -262014,13 +262549,14 @@ var init_user_message = __esm(async () => {
262014
262549
  });
262015
262550
 
262016
262551
  // ../../packages/tui/src/components/message-list.tsx
262017
- function renderSingleMessage(msg, index, allMessages, cliVersion, latestVersion, userEmail, expandCommands) {
262552
+ function renderSingleMessage(msg, index, allMessages, cliVersion, latestVersion, userEmail, expandCommands, announcement) {
262018
262553
  const key = msg.id != null ? `${msg.id}-${index}` : `msg-idx-${index}`;
262019
262554
  if (msg.role === "header") {
262020
262555
  return /* @__PURE__ */ jsx_runtime21.jsx(Header, {
262021
262556
  cliVersion,
262022
262557
  latestVersion,
262023
- userEmail
262558
+ userEmail,
262559
+ announcement
262024
262560
  }, key);
262025
262561
  }
262026
262562
  if (msg.role === "user")
@@ -262063,14 +262599,15 @@ var init_message_list = __esm(async () => {
262063
262599
  latestVersion,
262064
262600
  userEmail,
262065
262601
  expandCommands,
262066
- fullscreen = true
262602
+ fullscreen = true,
262603
+ announcement
262067
262604
  }) {
262068
262605
  if (fullscreen) {
262069
262606
  const allMessages = [...staticMessages, ...activeMessages];
262070
262607
  return /* @__PURE__ */ jsx_runtime21.jsx(Box_default, {
262071
262608
  flexDirection: "column",
262072
262609
  width: "100%",
262073
- children: allMessages.map((msg, index) => renderSingleMessage(msg, index, allMessages, cliVersion, latestVersion, userEmail, expandCommands))
262610
+ children: allMessages.map((msg, index) => renderSingleMessage(msg, index, allMessages, cliVersion, latestVersion, userEmail, expandCommands, announcement))
262074
262611
  });
262075
262612
  }
262076
262613
  return /* @__PURE__ */ jsx_runtime21.jsxs(Box_default, {
@@ -262080,9 +262617,9 @@ var init_message_list = __esm(async () => {
262080
262617
  staticMessages.length > 0 && /* @__PURE__ */ jsx_runtime21.jsx(Static13, {
262081
262618
  items: staticMessages,
262082
262619
  style: { width: "100%" },
262083
- children: (msg, index) => renderSingleMessage(msg, index, staticMessages, cliVersion, latestVersion, userEmail, expandCommands)
262620
+ children: (msg, index) => renderSingleMessage(msg, index, staticMessages, cliVersion, latestVersion, userEmail, expandCommands, announcement)
262084
262621
  }, `${staticKey}-${expandCommands}`),
262085
- activeMessages.map((msg, index) => renderSingleMessage(msg, staticMessages.length + index, [...staticMessages, ...activeMessages], cliVersion, latestVersion, userEmail, expandCommands))
262622
+ activeMessages.map((msg, index) => renderSingleMessage(msg, staticMessages.length + index, [...staticMessages, ...activeMessages], cliVersion, latestVersion, userEmail, expandCommands, announcement))
262086
262623
  ]
262087
262624
  });
262088
262625
  });
@@ -263058,7 +263595,55 @@ function getModelLabel2(id) {
263058
263595
  return id;
263059
263596
  }
263060
263597
  function ContextSelectMenu(props) {
263061
- const { agent } = props;
263598
+ const { agent, setAuthMode, handleSubmit, onClose, onClear, onModelSelect, onNewSession } = props;
263599
+ use_input_default((input, key) => {
263600
+ if (key.escape || input === "\x1B") {
263601
+ if (onClose) {
263602
+ onClose();
263603
+ } else if (setAuthMode) {
263604
+ setAuthMode("none");
263605
+ }
263606
+ return;
263607
+ }
263608
+ if (input === "c" || input === "C") {
263609
+ if (onClear) {
263610
+ onClear();
263611
+ } else {
263612
+ if (setAuthMode)
263613
+ setAuthMode("none");
263614
+ if (handleSubmit) {
263615
+ handleSubmit("/clear");
263616
+ } else if (agent?.clearContext) {
263617
+ agent.clearContext();
263618
+ }
263619
+ }
263620
+ return;
263621
+ }
263622
+ if (input === "m" || input === "M") {
263623
+ if (onModelSelect) {
263624
+ onModelSelect();
263625
+ } else if (handleSubmit) {
263626
+ handleSubmit("/model");
263627
+ } else if (setAuthMode) {
263628
+ setAuthMode("model_select");
263629
+ }
263630
+ return;
263631
+ }
263632
+ if (input === "n" || input === "N") {
263633
+ if (onNewSession) {
263634
+ onNewSession();
263635
+ } else {
263636
+ if (setAuthMode)
263637
+ setAuthMode("none");
263638
+ if (handleSubmit) {
263639
+ handleSubmit("/new");
263640
+ } else if (agent?.newContext) {
263641
+ agent.newContext();
263642
+ }
263643
+ }
263644
+ return;
263645
+ }
263646
+ });
263062
263647
  const activeModelId = agent?.modelOptions?.model || "gemini-3.7-flash";
263063
263648
  const currentModelName = getModelLabel2(activeModelId);
263064
263649
  const maxTokens = getModelContextWindow(activeModelId) || 1e6;
@@ -263276,7 +263861,12 @@ function ContextSelectMenu(props) {
263276
263861
  ]
263277
263862
  }),
263278
263863
  /* @__PURE__ */ jsx_runtime27.jsx(MenuFooter, {
263279
- items: [{ key: "esc", label: "Cancel" }]
263864
+ items: [
263865
+ { key: "esc", label: "Cancel" },
263866
+ { key: "c", label: "Clear history" },
263867
+ { key: "m", label: "Model" },
263868
+ { key: "n", label: "New session" }
263869
+ ]
263280
263870
  })
263281
263871
  ]
263282
263872
  });
@@ -266174,28 +266764,463 @@ var init_tool_permission_menu = __esm(async () => {
266174
266764
  jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
266175
266765
  });
266176
266766
 
266767
+ // ../../packages/tui/src/components/menus/usage-select-menu.tsx
266768
+ function formatK(n) {
266769
+ if (n === 0)
266770
+ return "0";
266771
+ if (n >= 1000)
266772
+ return (n / 1000).toFixed(1) + "k";
266773
+ return n.toString();
266774
+ }
266775
+ function formatCost(val) {
266776
+ if (val === 0)
266777
+ return "$0.0000";
266778
+ if (val < 0.0001)
266779
+ return "< $0.0001";
266780
+ return `$${val.toFixed(4)}`;
266781
+ }
266782
+ function calculateCost(model, inTokens, outTokens, cacheTokens = 0) {
266783
+ const rate = resolveModelRate(model);
266784
+ const promptCost = inTokens / 1e6 * rate.inputRate;
266785
+ const completionCost = outTokens / 1e6 * rate.outputRate;
266786
+ const cacheSavings = cacheTokens / 1e6 * rate.inputRate * 0.9;
266787
+ return Math.max(0, promptCost + completionCost - cacheSavings);
266788
+ }
266789
+ function generateDefaultDailyUsage() {
266790
+ const now = new Date;
266791
+ const items = [];
266792
+ for (let i = 6;i >= 0; i--) {
266793
+ const d = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);
266794
+ const dateKey = d.toISOString().slice(0, 10);
266795
+ const dayName = d.toLocaleDateString("en-US", { weekday: "short" });
266796
+ const formattedDate = d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
266797
+ items.push({
266798
+ date: dateKey,
266799
+ dayName,
266800
+ formattedDate,
266801
+ tokens: 0,
266802
+ isToday: i === 0
266803
+ });
266804
+ }
266805
+ return items;
266806
+ }
266807
+ function UsageSelectMenu(props) {
266808
+ const {
266809
+ agent,
266810
+ setAuthMode,
266811
+ handleSubmit,
266812
+ onClose,
266813
+ onRefresh,
266814
+ onModelSelect,
266815
+ onOpenBilling,
266816
+ usageData
266817
+ } = props;
266818
+ const activeModelId = usageData?.model || props.model || agent?.modelOptions?.model || "gemini-3.7-flash";
266819
+ const providerKey = (usageData?.provider || props.provider || agent?.modelOptions?.provider || "google").toLowerCase();
266820
+ const providerDisplayName = usageData?.providerDisplayName || props.providerDisplayName || getCleanProviderDisplayName(providerKey, activeModelId);
266821
+ const billingUrl = usageData?.billingUrl || props.billingUrl || PROVIDER_BILLING_LINKS[providerKey] || "https://trydecember.com";
266822
+ use_input_default((input, key) => {
266823
+ if (key.escape || input === "\x1B") {
266824
+ if (onClose) {
266825
+ onClose();
266826
+ } else if (setAuthMode) {
266827
+ setAuthMode("none");
266828
+ }
266829
+ return;
266830
+ }
266831
+ if (input === "r" || input === "R") {
266832
+ if (onRefresh) {
266833
+ onRefresh();
266834
+ }
266835
+ return;
266836
+ }
266837
+ if (input === "m" || input === "M") {
266838
+ if (onModelSelect) {
266839
+ onModelSelect();
266840
+ } else if (handleSubmit) {
266841
+ handleSubmit("/model");
266842
+ } else if (setAuthMode) {
266843
+ setAuthMode("model_select");
266844
+ }
266845
+ return;
266846
+ }
266847
+ if (input === "b" || input === "B") {
266848
+ if (onOpenBilling) {
266849
+ onOpenBilling(billingUrl);
266850
+ }
266851
+ return;
266852
+ }
266853
+ });
266854
+ const sessionStats = usageData?.sessionStats || props.sessionStats || (() => {
266855
+ const msgs = agent?.messages || [];
266856
+ let inTokens = 0;
266857
+ let outTokens = 0;
266858
+ let cacheTokens = 0;
266859
+ let reqs = 0;
266860
+ for (const msg of msgs) {
266861
+ if (msg && msg.usage) {
266862
+ inTokens += msg.usage.promptTokens || 0;
266863
+ outTokens += msg.usage.completionTokens || 0;
266864
+ cacheTokens += msg.usage.cacheReadInputTokens || 0;
266865
+ reqs++;
266866
+ }
266867
+ }
266868
+ return {
266869
+ requests: reqs,
266870
+ inputTokens: inTokens,
266871
+ outputTokens: outTokens,
266872
+ cacheReadTokens: cacheTokens,
266873
+ totalTokens: inTokens + outTokens
266874
+ };
266875
+ })();
266876
+ const calculatedCost = sessionStats.cost ?? calculateCost(activeModelId, sessionStats.inputTokens || 0, sessionStats.outputTokens || 0, sessionStats.cacheReadTokens || 0);
266877
+ const dailyItems = usageData?.dailyUsage || props.dailyUsage || generateDefaultDailyUsage();
266878
+ const maxDayTokens = Math.max(...dailyItems.map((d) => d.tokens), 1);
266879
+ const getSpark = (tokens) => {
266880
+ if (tokens <= 0)
266881
+ return "·";
266882
+ const index = Math.min(SHADE_LEVELS.length - 1, Math.floor(tokens / maxDayTokens * SHADE_LEVELS.length));
266883
+ return SHADE_LEVELS[index];
266884
+ };
266885
+ const balance = usageData?.balance || props.balance;
266886
+ const balanceStr = balance?.supported ? balance.balance ? `${balance.balance} (Live)` : balance.error ? `Unavailable (${balance.error})` : "Checking..." : "Unavailable";
266887
+ const weekly = usageData?.weeklyStats || props.weeklyStats || {
266888
+ totalTokens: dailyItems.reduce((acc, d) => acc + d.tokens, 0),
266889
+ activeDays: dailyItems.filter((d) => d.tokens > 0).length,
266890
+ topModels: []
266891
+ };
266892
+ const topModelSummary = weekly.topModels && weekly.topModels.length > 0 ? `${weekly.topModels[0].model} (${weekly.topModels[0].percentage}%)` : "None";
266893
+ return /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
266894
+ flexDirection: "column",
266895
+ paddingX: THEME.padding.paddingX,
266896
+ children: [
266897
+ /* @__PURE__ */ jsx_runtime40.jsx(Box_default, {
266898
+ marginBottom: 1,
266899
+ children: /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
266900
+ color: THEME.colors.text,
266901
+ children: [
266902
+ "Usage · ",
266903
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266904
+ color: THEME.colors.brand,
266905
+ children: activeModelId
266906
+ }),
266907
+ " ",
266908
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
266909
+ color: THEME.colors.muted,
266910
+ children: [
266911
+ "(",
266912
+ providerDisplayName,
266913
+ ")"
266914
+ ]
266915
+ })
266916
+ ]
266917
+ })
266918
+ }),
266919
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
266920
+ flexDirection: "row",
266921
+ gap: 4,
266922
+ children: [
266923
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
266924
+ flexDirection: "column",
266925
+ width: 34,
266926
+ children: [
266927
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266928
+ color: THEME.colors.text,
266929
+ children: "Daily Volume (Past 7 Days)"
266930
+ }),
266931
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266932
+ color: THEME.colors.border,
266933
+ children: "──────────────────────────"
266934
+ }),
266935
+ dailyItems.map((item) => {
266936
+ const spark = getSpark(item.tokens);
266937
+ const isZero = item.tokens <= 0;
266938
+ return /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
266939
+ gap: 1,
266940
+ children: [
266941
+ /* @__PURE__ */ jsx_runtime40.jsx(Box_default, {
266942
+ width: 10,
266943
+ children: /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
266944
+ color: THEME.colors.muted,
266945
+ children: [
266946
+ item.dayName,
266947
+ " ",
266948
+ item.formattedDate
266949
+ ]
266950
+ })
266951
+ }),
266952
+ /* @__PURE__ */ jsx_runtime40.jsx(Box_default, {
266953
+ width: 2,
266954
+ children: /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266955
+ color: isZero ? THEME.colors.dim : THEME.colors.brand,
266956
+ children: spark
266957
+ })
266958
+ }),
266959
+ /* @__PURE__ */ jsx_runtime40.jsx(Box_default, {
266960
+ width: 12,
266961
+ children: /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
266962
+ color: isZero ? THEME.colors.dim : THEME.colors.text,
266963
+ children: [
266964
+ formatK(item.tokens).padStart(5),
266965
+ " tokens"
266966
+ ]
266967
+ })
266968
+ }),
266969
+ item.isToday && /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266970
+ color: THEME.colors.brand,
266971
+ children: "(Today)"
266972
+ })
266973
+ ]
266974
+ }, item.date);
266975
+ }),
266976
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
266977
+ gap: 1,
266978
+ marginTop: 1,
266979
+ children: [
266980
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266981
+ color: THEME.colors.muted,
266982
+ children: "Less"
266983
+ }),
266984
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266985
+ color: THEME.colors.dim,
266986
+ children: "·"
266987
+ }),
266988
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266989
+ color: THEME.colors.brand,
266990
+ children: "░ ▒ ▓ █"
266991
+ }),
266992
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266993
+ color: THEME.colors.muted,
266994
+ children: "More"
266995
+ })
266996
+ ]
266997
+ }),
266998
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
266999
+ color: THEME.colors.border,
267000
+ children: "──────────────────────────"
267001
+ }),
267002
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267003
+ gap: 1,
267004
+ children: [
267005
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267006
+ color: THEME.colors.muted,
267007
+ children: "Weekly Total:"
267008
+ }),
267009
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
267010
+ color: THEME.colors.text,
267011
+ children: [
267012
+ formatK(weekly.totalTokens),
267013
+ " tokens"
267014
+ ]
267015
+ })
267016
+ ]
267017
+ }),
267018
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267019
+ gap: 1,
267020
+ children: [
267021
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267022
+ color: THEME.colors.muted,
267023
+ children: "Active Days:"
267024
+ }),
267025
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
267026
+ color: THEME.colors.text,
267027
+ children: [
267028
+ weekly.activeDays,
267029
+ " / 7 days"
267030
+ ]
267031
+ })
267032
+ ]
267033
+ })
267034
+ ]
267035
+ }),
267036
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267037
+ flexDirection: "column",
267038
+ width: 38,
267039
+ children: [
267040
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267041
+ color: THEME.colors.text,
267042
+ children: "Session Stats"
267043
+ }),
267044
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267045
+ color: THEME.colors.border,
267046
+ children: "─────────────"
267047
+ }),
267048
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267049
+ gap: 1,
267050
+ children: [
267051
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267052
+ color: THEME.colors.muted,
267053
+ children: "· Requests:"
267054
+ }),
267055
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
267056
+ color: THEME.colors.text,
267057
+ children: [
267058
+ sessionStats.requests,
267059
+ " requests"
267060
+ ]
267061
+ })
267062
+ ]
267063
+ }),
267064
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267065
+ gap: 1,
267066
+ children: [
267067
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267068
+ color: THEME.colors.muted,
267069
+ children: "· Input:"
267070
+ }),
267071
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
267072
+ color: THEME.colors.text,
267073
+ children: [
267074
+ formatK(sessionStats.inputTokens),
267075
+ " tokens"
267076
+ ]
267077
+ })
267078
+ ]
267079
+ }),
267080
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267081
+ gap: 1,
267082
+ children: [
267083
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267084
+ color: THEME.colors.muted,
267085
+ children: "· Output:"
267086
+ }),
267087
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
267088
+ color: THEME.colors.text,
267089
+ children: [
267090
+ formatK(sessionStats.outputTokens),
267091
+ " tokens"
267092
+ ]
267093
+ })
267094
+ ]
267095
+ }),
267096
+ sessionStats.cacheReadTokens ? /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267097
+ gap: 1,
267098
+ children: [
267099
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267100
+ color: THEME.colors.warning,
267101
+ children: "· Cache Read:"
267102
+ }),
267103
+ /* @__PURE__ */ jsx_runtime40.jsxs(Text3, {
267104
+ color: THEME.colors.text,
267105
+ children: [
267106
+ formatK(sessionStats.cacheReadTokens),
267107
+ " tokens"
267108
+ ]
267109
+ })
267110
+ ]
267111
+ }) : null,
267112
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267113
+ gap: 1,
267114
+ children: [
267115
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267116
+ color: THEME.colors.muted,
267117
+ children: "· Est. Cost:"
267118
+ }),
267119
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267120
+ color: THEME.colors.success,
267121
+ children: formatCost(calculatedCost)
267122
+ })
267123
+ ]
267124
+ }),
267125
+ /* @__PURE__ */ jsx_runtime40.jsx(Box_default, {
267126
+ marginTop: 1,
267127
+ children: /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267128
+ color: THEME.colors.text,
267129
+ children: "Account & Quota"
267130
+ })
267131
+ }),
267132
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267133
+ color: THEME.colors.border,
267134
+ children: "───────────────"
267135
+ }),
267136
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267137
+ gap: 1,
267138
+ children: [
267139
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267140
+ color: THEME.colors.muted,
267141
+ children: "· Balance:"
267142
+ }),
267143
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267144
+ color: balance?.balance ? THEME.colors.success : THEME.colors.text,
267145
+ children: balanceStr
267146
+ })
267147
+ ]
267148
+ }),
267149
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267150
+ gap: 1,
267151
+ children: [
267152
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267153
+ color: THEME.colors.muted,
267154
+ children: "· Top Model:"
267155
+ }),
267156
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267157
+ color: THEME.colors.text,
267158
+ children: topModelSummary
267159
+ })
267160
+ ]
267161
+ }),
267162
+ /* @__PURE__ */ jsx_runtime40.jsxs(Box_default, {
267163
+ gap: 1,
267164
+ children: [
267165
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267166
+ color: THEME.colors.muted,
267167
+ children: "· Provider:"
267168
+ }),
267169
+ /* @__PURE__ */ jsx_runtime40.jsx(Text3, {
267170
+ color: THEME.colors.text,
267171
+ children: providerDisplayName
267172
+ })
267173
+ ]
267174
+ })
267175
+ ]
267176
+ })
267177
+ ]
267178
+ }),
267179
+ /* @__PURE__ */ jsx_runtime40.jsx(MenuFooter, {
267180
+ items: [
267181
+ { key: "esc", label: "Cancel" },
267182
+ { key: "r", label: "Refresh" },
267183
+ { key: "m", label: "Switch model" },
267184
+ { key: "b", label: "Billing portal" }
267185
+ ]
267186
+ })
267187
+ ]
267188
+ });
267189
+ }
267190
+ var jsx_runtime40, SHADE_LEVELS;
267191
+ var init_usage_select_menu = __esm(async () => {
267192
+ init_src();
267193
+ init_theme();
267194
+ await __promiseAll([
267195
+ init_build2(),
267196
+ init_menu_footer()
267197
+ ]);
267198
+ jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
267199
+ SHADE_LEVELS = ["░", "▒", "▓", "█"];
267200
+ });
267201
+
266177
267202
  // ../../packages/tui/src/components/menus/auth-menus.tsx
266178
267203
  function AuthMenus(props) {
266179
267204
  switch (props.authMode) {
266180
267205
  case "menu":
266181
- return /* @__PURE__ */ jsx_runtime40.jsx(MenuMenu, {
267206
+ return /* @__PURE__ */ jsx_runtime41.jsx(MenuMenu, {
266182
267207
  ...props
266183
267208
  });
266184
267209
  case "subscription_select":
266185
267210
  case "subscription_provider":
266186
- return /* @__PURE__ */ jsx_runtime40.jsx(SubscriptionSelectMenu, {
267211
+ return /* @__PURE__ */ jsx_runtime41.jsx(SubscriptionSelectMenu, {
266187
267212
  ...props
266188
267213
  });
266189
267214
  case "byok_provider":
266190
- return /* @__PURE__ */ jsx_runtime40.jsx(ByokProviderMenu, {
267215
+ return /* @__PURE__ */ jsx_runtime41.jsx(ByokProviderMenu, {
266191
267216
  ...props
266192
267217
  });
266193
267218
  case "byok_key":
266194
- return /* @__PURE__ */ jsx_runtime40.jsx(ByokKeyMenu, {
267219
+ return /* @__PURE__ */ jsx_runtime41.jsx(ByokKeyMenu, {
266195
267220
  ...props
266196
267221
  });
266197
267222
  case "ollama_setup":
266198
- return /* @__PURE__ */ jsx_runtime40.jsx(OllamaSetupMenu, {
267223
+ return /* @__PURE__ */ jsx_runtime41.jsx(OllamaSetupMenu, {
266199
267224
  provider: props.selectedProvider || props.ollamaStatus?.provider || "ollama",
266200
267225
  status: props.ollamaStatus,
266201
267226
  onRetry: props.handleOllamaRetry,
@@ -266203,43 +267228,47 @@ function AuthMenus(props) {
266203
267228
  onProceed: props.handleOllamaProceed
266204
267229
  });
266205
267230
  case "model_select":
266206
- return /* @__PURE__ */ jsx_runtime40.jsx(ModelSelectMenu, {
267231
+ return /* @__PURE__ */ jsx_runtime41.jsx(ModelSelectMenu, {
266207
267232
  ...props
266208
267233
  });
266209
267234
  case "context_select":
266210
- return /* @__PURE__ */ jsx_runtime40.jsx(ContextSelectMenu, {
267235
+ return /* @__PURE__ */ jsx_runtime41.jsx(ContextSelectMenu, {
266211
267236
  ...props
266212
267237
  });
266213
267238
  case "logout_select":
266214
- return /* @__PURE__ */ jsx_runtime40.jsx(LogoutSelectMenu, {
267239
+ return /* @__PURE__ */ jsx_runtime41.jsx(LogoutSelectMenu, {
266215
267240
  ...props
266216
267241
  });
266217
267242
  case "switch_select":
266218
- return /* @__PURE__ */ jsx_runtime40.jsx(SwitchSelectMenu, {
267243
+ return /* @__PURE__ */ jsx_runtime41.jsx(SwitchSelectMenu, {
266219
267244
  ...props
266220
267245
  });
266221
267246
  case "session_select":
266222
- return /* @__PURE__ */ jsx_runtime40.jsx(SessionSelectMenu, {
267247
+ return /* @__PURE__ */ jsx_runtime41.jsx(SessionSelectMenu, {
266223
267248
  ...props
266224
267249
  });
266225
267250
  case "tasks_mode":
266226
- return /* @__PURE__ */ jsx_runtime40.jsx(TasksModeMenu, {
267251
+ return /* @__PURE__ */ jsx_runtime41.jsx(TasksModeMenu, {
266227
267252
  ...props
266228
267253
  });
266229
267254
  case "plan_approve":
266230
- return /* @__PURE__ */ jsx_runtime40.jsx(PlanApproveMenu, {
267255
+ return /* @__PURE__ */ jsx_runtime41.jsx(PlanApproveMenu, {
266231
267256
  ...props
266232
267257
  });
266233
267258
  case "grill_question":
266234
- return /* @__PURE__ */ jsx_runtime40.jsx(GrillQuestionMenu, {
267259
+ return /* @__PURE__ */ jsx_runtime41.jsx(GrillQuestionMenu, {
266235
267260
  ...props
266236
267261
  });
266237
267262
  case "settings_main":
266238
- return /* @__PURE__ */ jsx_runtime40.jsx(SettingsMainMenu, {
267263
+ return /* @__PURE__ */ jsx_runtime41.jsx(SettingsMainMenu, {
267264
+ ...props
267265
+ });
267266
+ case "usage":
267267
+ return /* @__PURE__ */ jsx_runtime41.jsx(UsageSelectMenu, {
266239
267268
  ...props
266240
267269
  });
266241
267270
  case "tool_permission":
266242
- return /* @__PURE__ */ jsx_runtime40.jsx(ToolPermissionMenu, {
267271
+ return /* @__PURE__ */ jsx_runtime41.jsx(ToolPermissionMenu, {
266243
267272
  toolCall: props.pendingToolCall?.toolCall,
266244
267273
  questions: props.pendingQuestions?.questions || [],
266245
267274
  onComplete: (result) => {
@@ -266252,7 +267281,7 @@ function AuthMenus(props) {
266252
267281
  return null;
266253
267282
  }
266254
267283
  }
266255
- var jsx_runtime40;
267284
+ var jsx_runtime41;
266256
267285
  var init_auth_menus = __esm(async () => {
266257
267286
  await __promiseAll([
266258
267287
  init_byok_key_menu(),
@@ -266269,9 +267298,10 @@ var init_auth_menus = __esm(async () => {
266269
267298
  init_subscription_select_menu(),
266270
267299
  init_switch_select_menu(),
266271
267300
  init_tasks_mode_menu(),
266272
- init_tool_permission_menu()
267301
+ init_tool_permission_menu(),
267302
+ init_usage_select_menu()
266273
267303
  ]);
266274
- jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
267304
+ jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
266275
267305
  });
266276
267306
 
266277
267307
  // ../../packages/tui/src/components/menus/ask-question-menu.tsx
@@ -266347,44 +267377,44 @@ function AskQuestionMenu({ questions, onComplete }) {
266347
267377
  });
266348
267378
  if (!currentQ)
266349
267379
  return null;
266350
- return /* @__PURE__ */ jsx_runtime41.jsxs(Box_default, {
267380
+ return /* @__PURE__ */ jsx_runtime42.jsxs(Box_default, {
266351
267381
  flexDirection: "column",
266352
267382
  paddingX: THEME.padding.paddingX,
266353
267383
  gap: 1,
266354
267384
  children: [
266355
- /* @__PURE__ */ jsx_runtime41.jsxs(Box_default, {
267385
+ /* @__PURE__ */ jsx_runtime42.jsxs(Box_default, {
266356
267386
  flexDirection: "row",
266357
267387
  gap: 1,
266358
267388
  children: [
266359
- /* @__PURE__ */ jsx_runtime41.jsx(Text3, {
267389
+ /* @__PURE__ */ jsx_runtime42.jsx(Text3, {
266360
267390
  color: THEME.colors.brand,
266361
267391
  children: `Q${currentQuestionIdx + 1}/${questions.length}:`
266362
267392
  }),
266363
- /* @__PURE__ */ jsx_runtime41.jsx(Text3, {
267393
+ /* @__PURE__ */ jsx_runtime42.jsx(Text3, {
266364
267394
  color: THEME.colors.text,
266365
267395
  children: currentQ.question
266366
267396
  })
266367
267397
  ]
266368
267398
  }),
266369
- /* @__PURE__ */ jsx_runtime41.jsx(Box_default, {
267399
+ /* @__PURE__ */ jsx_runtime42.jsx(Box_default, {
266370
267400
  flexDirection: "column",
266371
267401
  paddingLeft: 1,
266372
267402
  children: options.map((opt, idx) => {
266373
267403
  const isHighlighted = idx === selectedIndex;
266374
267404
  const isChecked = selectedMultiIndices.has(idx);
266375
- return /* @__PURE__ */ jsx_runtime41.jsxs(Box_default, {
267405
+ return /* @__PURE__ */ jsx_runtime42.jsxs(Box_default, {
266376
267406
  flexDirection: "row",
266377
267407
  gap: 1,
266378
267408
  children: [
266379
- /* @__PURE__ */ jsx_runtime41.jsx(Text3, {
267409
+ /* @__PURE__ */ jsx_runtime42.jsx(Text3, {
266380
267410
  color: isHighlighted ? THEME.colors.brand : THEME.colors.muted,
266381
267411
  children: isHighlighted ? THEME.glyphs.selector : " "
266382
267412
  }),
266383
- isMulti && /* @__PURE__ */ jsx_runtime41.jsx(Text3, {
267413
+ isMulti && /* @__PURE__ */ jsx_runtime42.jsx(Text3, {
266384
267414
  color: isChecked ? THEME.colors.success : THEME.colors.muted,
266385
267415
  children: isChecked ? "[x]" : "[ ]"
266386
267416
  }),
266387
- /* @__PURE__ */ jsx_runtime41.jsx(Text3, {
267417
+ /* @__PURE__ */ jsx_runtime42.jsx(Text3, {
266388
267418
  color: isHighlighted ? THEME.colors.brand : isChecked ? THEME.colors.success : THEME.colors.text,
266389
267419
  children: opt
266390
267420
  })
@@ -266392,7 +267422,7 @@ function AskQuestionMenu({ questions, onComplete }) {
266392
267422
  }, idx);
266393
267423
  })
266394
267424
  }),
266395
- /* @__PURE__ */ jsx_runtime41.jsx(MenuFooter, {
267425
+ /* @__PURE__ */ jsx_runtime42.jsx(MenuFooter, {
266396
267426
  items: isMulti ? [
266397
267427
  { key: "↑/↓", label: "Navigate" },
266398
267428
  { key: "space", label: "Toggle" },
@@ -266405,7 +267435,7 @@ function AskQuestionMenu({ questions, onComplete }) {
266405
267435
  ]
266406
267436
  });
266407
267437
  }
266408
- var import_react68, jsx_runtime41;
267438
+ var import_react68, jsx_runtime42;
266409
267439
  var init_ask_question_menu = __esm(async () => {
266410
267440
  init_theme();
266411
267441
  await __promiseAll([
@@ -266413,7 +267443,7 @@ var init_ask_question_menu = __esm(async () => {
266413
267443
  init_menu_footer()
266414
267444
  ]);
266415
267445
  import_react68 = __toESM(require_react(), 1);
266416
- jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
267446
+ jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
266417
267447
  });
266418
267448
 
266419
267449
  // ../../packages/tui/src/components/pill.tsx
@@ -266421,7 +267451,6 @@ var init_pill = __esm(async () => {
266421
267451
  init_theme();
266422
267452
  await init_build2();
266423
267453
  });
266424
-
266425
267454
  // ../../packages/tui/src/components/global-shortcuts.tsx
266426
267455
  function GlobalShortcuts(session) {
266427
267456
  const { exit } = use_app_default();
@@ -266605,7 +267634,8 @@ function ChatApp({
266605
267634
  onLogin,
266606
267635
  onUpdateSuccess,
266607
267636
  session,
266608
- isInline = false
267637
+ isInline = false,
267638
+ announcement
266609
267639
  }) {
266610
267640
  const [exitConfirm, setExitConfirm] = import_react69.useState(false);
266611
267641
  const exitTimerRef = import_react69.useRef(null);
@@ -266663,30 +267693,30 @@ function ChatApp({
266663
267693
  handleSubmit
266664
267694
  } = session;
266665
267695
  const workflowPhase = planWorkflow?.phase;
266666
- const workflowUI = workflowPhase === "grilling" ? /* @__PURE__ */ jsx_runtime42.jsx(GrillQuestionMenu, {
267696
+ const workflowUI = workflowPhase === "grilling" ? /* @__PURE__ */ jsx_runtime43.jsx(GrillQuestionMenu, {
266667
267697
  ...session,
266668
267698
  grillQuestions: planWorkflow.questions,
266669
267699
  currentGrillIndex: planWorkflow.currentIndex,
266670
267700
  grillAnswers: planWorkflow.answers
266671
- }) : workflowPhase === "reviewing" ? /* @__PURE__ */ jsx_runtime42.jsx(PlanApproveMenu, {
267701
+ }) : workflowPhase === "reviewing" ? /* @__PURE__ */ jsx_runtime43.jsx(PlanApproveMenu, {
266672
267702
  ...session,
266673
267703
  planSummary: planWorkflow.planText ? extractPlanSummary(planWorkflow.planText) : session.planSummary || planWorkflow.prompt
266674
267704
  }) : null;
266675
- const authUI = authMode !== "none" ? authMode === "ask_question" && session.pendingQuestions ? /* @__PURE__ */ jsx_runtime42.jsx(AskQuestionMenu, {
267705
+ const authUI = authMode !== "none" ? authMode === "ask_question" && session.pendingQuestions ? /* @__PURE__ */ jsx_runtime43.jsx(AskQuestionMenu, {
266676
267706
  questions: session.pendingQuestions.questions,
266677
267707
  onComplete: (answers) => {
266678
267708
  session.pendingQuestions?.resolve(typeof answers === "string" ? answers : answers.join(", "));
266679
267709
  setAuthMode("none");
266680
267710
  session.setPendingQuestions(null);
266681
267711
  }
266682
- }) : authMode === "tool_permission" && session.pendingToolCall ? /* @__PURE__ */ jsx_runtime42.jsx(ToolPermissionMenu, {
267712
+ }) : authMode === "tool_permission" && session.pendingToolCall ? /* @__PURE__ */ jsx_runtime43.jsx(ToolPermissionMenu, {
266683
267713
  toolCall: session.pendingToolCall.toolCall,
266684
267714
  onComplete: (result) => {
266685
267715
  session.pendingToolCall?.resolve(result);
266686
267716
  setAuthMode("none");
266687
267717
  session.setPendingToolCall(null);
266688
267718
  }
266689
- }) : /* @__PURE__ */ jsx_runtime42.jsx(AuthMenus, {
267719
+ }) : /* @__PURE__ */ jsx_runtime43.jsx(AuthMenus, {
266690
267720
  ...session,
266691
267721
  agent,
266692
267722
  getProviderModels: session.getProviderModels
@@ -266702,7 +267732,7 @@ function ChatApp({
266702
267732
  }, 0);
266703
267733
  const rows = useTerminalRows();
266704
267734
  const columns = useTerminalColumns();
266705
- const inputBarElement = /* @__PURE__ */ jsx_runtime42.jsx(InputBar, {
267735
+ const inputBarElement = /* @__PURE__ */ jsx_runtime43.jsx(InputBar, {
266706
267736
  onSubmit: handleFormSubmit,
266707
267737
  disabled: authMode !== "none" || Boolean(workflowUI) && !session.customInputMode,
266708
267738
  onCopy: () => {
@@ -266745,15 +267775,15 @@ function ChatApp({
266745
267775
  tasks: session.tasks
266746
267776
  });
266747
267777
  if (isInline) {
266748
- return /* @__PURE__ */ jsx_runtime42.jsxs(Box_default, {
267778
+ return /* @__PURE__ */ jsx_runtime43.jsxs(Box_default, {
266749
267779
  flexDirection: "column",
266750
267780
  width: "100%",
266751
267781
  children: [
266752
- /* @__PURE__ */ jsx_runtime42.jsx(GlobalShortcuts, {
267782
+ /* @__PURE__ */ jsx_runtime43.jsx(GlobalShortcuts, {
266753
267783
  ...session,
266754
267784
  agent
266755
267785
  }),
266756
- /* @__PURE__ */ jsx_runtime42.jsx(MessageList, {
267786
+ /* @__PURE__ */ jsx_runtime43.jsx(MessageList, {
266757
267787
  staticKey,
266758
267788
  staticMessages,
266759
267789
  activeMessages,
@@ -266762,26 +267792,27 @@ function ChatApp({
266762
267792
  latestVersion,
266763
267793
  userEmail: currentEmail || userEmail,
266764
267794
  expandCommands: session.expandCommands,
266765
- fullscreen: false
267795
+ fullscreen: false,
267796
+ announcement
266766
267797
  }),
266767
267798
  inputBarElement
266768
267799
  ]
266769
267800
  });
266770
267801
  }
266771
- return /* @__PURE__ */ jsx_runtime42.jsxs(Box_default, {
267802
+ return /* @__PURE__ */ jsx_runtime43.jsxs(Box_default, {
266772
267803
  flexDirection: "column",
266773
267804
  height: rows,
266774
267805
  width: columns,
266775
267806
  overflow: "hidden",
266776
267807
  children: [
266777
- /* @__PURE__ */ jsx_runtime42.jsx(GlobalShortcuts, {
267808
+ /* @__PURE__ */ jsx_runtime43.jsx(GlobalShortcuts, {
266778
267809
  ...session,
266779
267810
  agent
266780
267811
  }),
266781
- /* @__PURE__ */ jsx_runtime42.jsx(ScrollViewport, {
267812
+ /* @__PURE__ */ jsx_runtime43.jsx(ScrollViewport, {
266782
267813
  isGenerating: session.isStreaming,
266783
267814
  isActive: authMode === "none",
266784
- children: /* @__PURE__ */ jsx_runtime42.jsx(MessageList, {
267815
+ children: /* @__PURE__ */ jsx_runtime43.jsx(MessageList, {
266785
267816
  staticKey,
266786
267817
  staticMessages,
266787
267818
  activeMessages,
@@ -266790,10 +267821,11 @@ function ChatApp({
266790
267821
  latestVersion,
266791
267822
  userEmail: currentEmail || userEmail,
266792
267823
  expandCommands: session.expandCommands,
266793
- fullscreen: true
267824
+ fullscreen: true,
267825
+ announcement
266794
267826
  })
266795
267827
  }),
266796
- /* @__PURE__ */ jsx_runtime42.jsx(Box_default, {
267828
+ /* @__PURE__ */ jsx_runtime43.jsx(Box_default, {
266797
267829
  flexDirection: "column",
266798
267830
  flexShrink: 0,
266799
267831
  width: "100%",
@@ -266802,7 +267834,7 @@ function ChatApp({
266802
267834
  ]
266803
267835
  });
266804
267836
  }
266805
- var import_react69, jsx_runtime42;
267837
+ var import_react69, jsx_runtime43;
266806
267838
  var init_app = __esm(async () => {
266807
267839
  init_pager();
266808
267840
  await __promiseAll([
@@ -266819,7 +267851,7 @@ var init_app = __esm(async () => {
266819
267851
  init_use_terminal_columns()
266820
267852
  ]);
266821
267853
  import_react69 = __toESM(require_react(), 1);
266822
- jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
267854
+ jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
266823
267855
  });
266824
267856
 
266825
267857
  // ../../packages/tui/src/index.tsx
@@ -266841,6 +267873,7 @@ var init_src7 = __esm(async () => {
266841
267873
  init_menu_items();
266842
267874
  init_auth_menus();
266843
267875
  init_ask_question_menu();
267876
+ init_header();
266844
267877
  init_use_delayed_tip();
266845
267878
  init_tips();
266846
267879
  init_menu_menu();
@@ -266858,6 +267891,7 @@ var init_src7 = __esm(async () => {
266858
267891
  init_settings_main_menu();
266859
267892
  init_tool_permission_menu();
266860
267893
  init_ollama_setup_menu();
267894
+ init_usage_select_menu();
266861
267895
  init_app();
266862
267896
  init_global_shortcuts();
266863
267897
  init_clipboard();
@@ -267445,9 +268479,6 @@ var init_direct_shell = __esm(() => {
267445
268479
  // src/utils/usage-tracker.ts
267446
268480
  import fs33 from "node:fs/promises";
267447
268481
  import path32 from "node:path";
267448
- function formatNumberWithCommas(n) {
267449
- return Math.round(n).toLocaleString("en-US");
267450
- }
267451
268482
  function getUsageFilePath() {
267452
268483
  return path32.join(getConfigDir(), "usage.json");
267453
268484
  }
@@ -267673,266 +268704,9 @@ function inferProviderFromModel(modelName) {
267673
268704
  return "ollama";
267674
268705
  return "openrouter";
267675
268706
  }
267676
- function formatStatsSection(sessionStats, weeklyStats, balance, providerName) {
267677
- const lines = [];
267678
- if (balance?.supported) {
267679
- if (balance.balance) {
267680
- lines.push("");
267681
- lines.push("Account Balance:");
267682
- lines.push(` Remaining: ${balance.balance} (Live from ${providerName || "Provider"})`);
267683
- } else if (balance.error) {
267684
- lines.push("");
267685
- lines.push("Account Balance:");
267686
- lines.push(` Live balance check unavailable (${balance.error})`);
267687
- }
267688
- }
267689
- if (sessionStats) {
267690
- lines.push("");
267691
- lines.push("This Session:");
267692
- if (sessionStats.requests === 0 && (sessionStats.totalTokens || 0) === 0) {
267693
- lines.push(" No requests recorded yet in this session.");
267694
- } else {
267695
- const reqStr = sessionStats.requests === 1 ? "1 request" : `${sessionStats.requests} requests`;
267696
- const total = sessionStats.totalTokens ?? (sessionStats.inputTokens || 0) + (sessionStats.outputTokens || 0);
267697
- const cacheSuffix = sessionStats.cacheReadTokens ? ` (incl. ${formatNumberWithCommas(sessionStats.cacheReadTokens)} cached)` : "";
267698
- lines.push(` Requests: ${reqStr}`);
267699
- lines.push(` Input: ${formatNumberWithCommas(sessionStats.inputTokens)} tokens${cacheSuffix}`);
267700
- lines.push(` Output: ${formatNumberWithCommas(sessionStats.outputTokens)} tokens`);
267701
- lines.push(` Total: ${formatNumberWithCommas(total)} tokens`);
267702
- }
267703
- }
267704
- if (weeklyStats) {
267705
- lines.push("");
267706
- lines.push("Past 7 Days (Overall):");
267707
- if (weeklyStats.requests === 0 && weeklyStats.totalTokens === 0) {
267708
- lines.push(" No token activity recorded in the last 7 days.");
267709
- } else {
267710
- const daysStr = weeklyStats.activeDays === 1 ? "1 active day" : `${weeklyStats.activeDays} active days`;
267711
- const reqStr = weeklyStats.requests === 1 ? "1 request" : `${weeklyStats.requests} requests`;
267712
- lines.push(` Activity: ${reqStr} across ${daysStr}`);
267713
- lines.push(` Input: ${formatNumberWithCommas(weeklyStats.inputTokens)} tokens`);
267714
- lines.push(` Output: ${formatNumberWithCommas(weeklyStats.outputTokens)} tokens`);
267715
- lines.push(` Total: ${formatNumberWithCommas(weeklyStats.totalTokens)} tokens`);
267716
- if (weeklyStats.topModels && weeklyStats.topModels.length > 0) {
267717
- const modelSummaries = weeklyStats.topModels.slice(0, 3).map((m) => `${m.model} (${m.percentage}%)`).join(", ");
267718
- lines.push(` Top Models: ${modelSummaries}`);
267719
- }
267720
- }
267721
- }
267722
- return lines;
267723
- }
267724
- function formatUsageCard(params) {
267725
- const {
267726
- model,
267727
- authMethod = "byok",
267728
- isAuthenticated = true,
267729
- sessionStats,
267730
- weeklyStats,
267731
- balance
267732
- } = params;
267733
- let providerKey = (params.provider || "").toLowerCase();
267734
- if (!isAuthenticated) {
267735
- return AUTH_REQUIRED_NOTICE;
267736
- }
267737
- if (authMethod === "december") {
267738
- const billingLink = PROVIDER_BILLING_LINKS2.december;
267739
- const middle = formatStatsSection(sessionStats, weeklyStats, balance, "December Cloud");
267740
- const middleStr = middle.length > 0 ? `${middle.join(`
267741
- `)}
267742
-
267743
- ` : `
267744
- `;
267745
- return `Active Model: \`${model}\` (December Wallet)
267746
- Provider: December Cloud
267747
- ${middleStr}*Usage is deducted directly from your December account credits. Request telemetry, token consumption, and monthly invoices are tracked at [${billingLink}](${billingLink})*`;
267748
- }
267749
- if (authMethod === "subscription") {
267750
- const subDisplayName = providerKey === "copilot" || providerKey === "github" ? "GitHub Copilot" : providerKey === "claude" || providerKey === "anthropic" ? "Claude Pro/Max (Claude Code)" : providerKey === "codex" || providerKey === "openai" ? "ChatGPT Plus/Team/Pro (OpenAI Codex)" : providerKey === "gemini" || providerKey === "google" || providerKey === "antigravity" ? "Google One AI Premium (Gemini/Antigravity)" : `${providerKey.toUpperCase()} Subscription`;
267751
- const middle = formatStatsSection(sessionStats, weeklyStats, balance, subDisplayName);
267752
- const middleStr = middle.length > 0 ? `${middle.join(`
267753
- `)}
267754
-
267755
- ` : `
267756
- `;
267757
- return `Active Model: \`${model}\` (Subscription)
267758
- Provider: ${subDisplayName}
267759
- ${middleStr}*Usage is covered by your active ${subDisplayName} monthly subscription quota. Prompts route directly from your machine with OAuth authentication; no per-token charges or December proxy fees apply.*`;
267760
- }
267761
- if (!providerKey || providerKey === "december_proxy") {
267762
- providerKey = inferProviderFromModel(model);
267763
- }
267764
- if (providerKey === "ollama" || model.toLowerCase().includes("ollama")) {
267765
- const link = PROVIDER_BILLING_LINKS2.ollama;
267766
- const middle = formatStatsSection(sessionStats, weeklyStats, balance, "Ollama (Local)");
267767
- const middleStr = middle.length > 0 ? `${middle.join(`
267768
- `)}
267769
-
267770
- ` : `
267771
- `;
267772
- return `Active Model: \`${model}\` (Local)
267773
- Provider: Ollama (Local)
267774
- ${middleStr}*Running completely locally on your hardware with no API keys, no external network calls, and no usage fees. View status and local models at [${link}](${link})*`;
267775
- }
267776
- const displayName = PROVIDER_DISPLAY_NAMES2[providerKey] || providerKey.toUpperCase();
267777
- const billingLink = PROVIDER_BILLING_LINKS2[providerKey] || `https://openrouter.ai/activity`;
267778
- const middle = formatStatsSection(sessionStats, weeklyStats, balance, displayName);
267779
- const middleStr = middle.length > 0 ? `${middle.join(`
267780
- `)}
267781
-
267782
- ` : `
267783
- `;
267784
- return `Active Model: \`${model}\` (BYOK)
267785
- Provider: ${displayName}
267786
- ${middleStr}*Prompts go directly to the provider API; December servers do not track, log, or bill this usage. Token consumption, quotas, and billing are managed in your ${displayName} account at [${billingLink}](${billingLink})*`;
267787
- }
267788
- var PROVIDER_BILLING_LINKS2, PROVIDER_DISPLAY_NAMES2;
267789
268707
  var init_usage_rates2 = __esm(() => {
267790
268708
  init_messages5();
267791
268709
  init_usage_tracker();
267792
- PROVIDER_BILLING_LINKS2 = {
267793
- december: "https://app.trydecember.com/settings/usage",
267794
- google: "https://aistudio.google.com/app/usage",
267795
- gemini: "https://aistudio.google.com/app/usage",
267796
- anthropic: "https://console.anthropic.com/settings/billing",
267797
- openai: "https://platform.openai.com/usage",
267798
- openrouter: "https://openrouter.ai/activity",
267799
- deepseek: "https://platform.deepseek.com/usage",
267800
- groq: "https://console.groq.com/usage",
267801
- mistral: "https://console.mistral.ai/billing/",
267802
- mistralai: "https://console.mistral.ai/billing/",
267803
- "mistral-ai": "https://console.mistral.ai/billing/",
267804
- moonshot: "https://platform.moonshot.ai/console/api-keys",
267805
- moonshotai: "https://platform.moonshot.ai/console/api-keys",
267806
- "moonshot-ai": "https://platform.moonshot.ai/console/api-keys",
267807
- moonshoot: "https://platform.moonshot.ai/console/api-keys",
267808
- kimi: "https://platform.moonshot.ai/console/api-keys",
267809
- xai: "https://console.x.ai/",
267810
- xiaomi: "https://platform.xiaomimimo.com/console/api-keys",
267811
- mimo: "https://platform.xiaomimimo.com/console/api-keys",
267812
- zai: "https://open.bigmodel.cn/usercenter/apikeys",
267813
- zhipu: "https://open.bigmodel.cn/usercenter/apikeys",
267814
- zhipuai: "https://open.bigmodel.cn/usercenter/apikeys",
267815
- nvidia: "https://build.nvidia.com/",
267816
- sambanova: "https://cloud.sambanova.ai/",
267817
- cerebras: "https://cloud.cerebras.ai/",
267818
- siliconflow: "https://cloud.siliconflow.cn/account/ak",
267819
- together: "https://api.together.ai/settings/billing",
267820
- hyperbolic: "https://app.hyperbolic.ai/settings",
267821
- fireworks: "https://app.fireworks.ai/settings/billing",
267822
- perplexity: "https://www.perplexity.ai/settings/api",
267823
- cohere: "https://dashboard.cohere.com/billing",
267824
- huggingface: "https://huggingface.co/settings/billing",
267825
- agentrouter: "https://agentrouter.org/console/token",
267826
- arcee: "https://platform.arcee.ai/api/api-keys",
267827
- meta: "https://dev.meta.ai/",
267828
- minimax: "https://platform.minimax.io/console/access",
267829
- minimaxai: "https://platform.minimax.io/console/access",
267830
- "minimax-ai": "https://platform.minimax.io/console/access",
267831
- poolside: "https://platform.poolside.ai/api-keys",
267832
- sakana: "https://console.sakana.ai/api-keys",
267833
- "sakana-ai": "https://console.sakana.ai/api-keys",
267834
- sakanaai: "https://console.sakana.ai/api-keys",
267835
- sarvam: "https://indus.sarvam.ai/",
267836
- sarvamai: "https://indus.sarvam.ai/",
267837
- "sarvam-ai": "https://indus.sarvam.ai/",
267838
- stepfun: "https://platform.stepfun.ai/interface-key",
267839
- stepfunai: "https://platform.stepfun.ai/interface-key",
267840
- "stepfun-ai": "https://platform.stepfun.ai/interface-key",
267841
- upstage: "https://console.upstage.ai",
267842
- upstageai: "https://console.upstage.ai",
267843
- solar: "https://console.upstage.ai",
267844
- thinkingmachines: "https://tinker.thinkingmachines.ai/",
267845
- tinker: "https://tinker.thinkingmachines.ai/",
267846
- inkling: "https://tinker.thinkingmachines.ai/",
267847
- abliteration: "https://abliteration.ai/console",
267848
- "abliteration-ai": "https://abliteration.ai/console",
267849
- abliterationai: "https://abliteration.ai/console",
267850
- agnes: "https://platform.agnes-ai.com/settings/apiKeys",
267851
- "agnes-ai": "https://platform.agnes-ai.com/settings/apiKeys",
267852
- agnesai: "https://platform.agnes-ai.com/settings/apiKeys",
267853
- airouter: "https://ai-router.dev/keys",
267854
- "ai-router": "https://ai-router.dev/keys",
267855
- aiand: "https://console.aiand.com/api-keys",
267856
- aki: "https://aki.io/admin/user-dashboard",
267857
- "aki-io": "https://aki.io/admin/user-dashboard",
267858
- akiio: "https://aki.io/admin/user-dashboard",
267859
- ambient: "https://app.ambient.xyz/keys",
267860
- auriko: "https://www.auriko.ai/dashboard",
267861
- baseten: "https://app.baseten.co/settings/api_keys",
267862
- ollama: "http://localhost:11434"
267863
- };
267864
- PROVIDER_DISPLAY_NAMES2 = {
267865
- december: "December Cloud",
267866
- google: "Google AI Studio",
267867
- gemini: "Google AI Studio",
267868
- anthropic: "Anthropic Console",
267869
- openai: "OpenAI Platform",
267870
- openrouter: "OpenRouter",
267871
- deepseek: "DeepSeek Platform",
267872
- groq: "Groq Cloud",
267873
- mistral: "Mistral AI",
267874
- mistralai: "Mistral AI",
267875
- "mistral-ai": "Mistral AI",
267876
- moonshot: "Moonshot AI (Kimi)",
267877
- moonshotai: "Moonshot AI (Kimi)",
267878
- "moonshot-ai": "Moonshot AI (Kimi)",
267879
- moonshoot: "Moonshot AI (Kimi)",
267880
- kimi: "Moonshot AI (Kimi)",
267881
- xai: "xAI Console",
267882
- xiaomi: "Xiaomi MiMo",
267883
- mimo: "Xiaomi MiMo",
267884
- zai: "Zhipu AI (GLM)",
267885
- zhipu: "Zhipu AI (GLM)",
267886
- zhipuai: "Zhipu AI (GLM)",
267887
- nvidia: "NVIDIA NIM",
267888
- sambanova: "SambaNova Cloud",
267889
- cerebras: "Cerebras Inference",
267890
- siliconflow: "SiliconFlow (SiliconCloud)",
267891
- together: "Together AI",
267892
- hyperbolic: "Hyperbolic",
267893
- fireworks: "Fireworks AI",
267894
- perplexity: "Perplexity AI",
267895
- cohere: "Cohere",
267896
- huggingface: "Hugging Face",
267897
- agentrouter: "AgentRouter",
267898
- arcee: "Arcee AI",
267899
- meta: "Meta",
267900
- minimax: "MiniMax",
267901
- minimaxai: "MiniMax",
267902
- "minimax-ai": "MiniMax",
267903
- poolside: "Poolside",
267904
- sakana: "Sakana AI",
267905
- "sakana-ai": "Sakana AI",
267906
- sakanaai: "Sakana AI",
267907
- sarvam: "Sarvam AI",
267908
- sarvamai: "Sarvam AI",
267909
- "sarvam-ai": "Sarvam AI",
267910
- stepfun: "StepFun (Global)",
267911
- stepfunai: "StepFun (Global)",
267912
- "stepfun-ai": "StepFun (Global)",
267913
- upstage: "Upstage Solar",
267914
- upstageai: "Upstage Solar",
267915
- solar: "Upstage Solar",
267916
- thinkingmachines: "Thinking Machines (Tinker)",
267917
- tinker: "Thinking Machines (Tinker)",
267918
- inkling: "Thinking Machines (Tinker)",
267919
- abliteration: "Abliteration AI",
267920
- "abliteration-ai": "Abliteration AI",
267921
- abliterationai: "Abliteration AI",
267922
- agnes: "Agnes AI",
267923
- "agnes-ai": "Agnes AI",
267924
- agnesai: "Agnes AI",
267925
- airouter: "AI Router",
267926
- "ai-router": "AI Router",
267927
- aiand: "AI&",
267928
- aki: "AKI.IO",
267929
- "aki-io": "AKI.IO",
267930
- akiio: "AKI.IO",
267931
- ambient: "Ambient",
267932
- auriko: "Auriko",
267933
- baseten: "Baseten",
267934
- ollama: "Ollama (Local)"
267935
- };
267936
268710
  });
267937
268711
 
267938
268712
  // src/utils/error-parser.ts
@@ -270741,6 +271515,7 @@ function useAgentSession({
270741
271515
  setExpandCommands((prev) => !prev);
270742
271516
  }, []);
270743
271517
  const [detectedSubscriptions, setDetectedSubscriptions] = import_react71.useState({});
271518
+ const [usageData, setUsageData] = import_react71.useState(null);
270744
271519
  import_react71.useEffect(() => {
270745
271520
  Promise.resolve().then(() => (init_subscription_manager(), {})).then(({}) => detectAllSubscriptions()).then((detected) => {
270746
271521
  if (detected)
@@ -271340,6 +272115,108 @@ function useAgentSession({
271340
272115
  setGrillAnswers,
271341
272116
  setPlanWorkflow
271342
272117
  ]);
272118
+ const fetchUsageData = import_react71.useCallback(async () => {
272119
+ const currentModel = agent?.modelOptions?.model || "gemini-3.6-flash";
272120
+ const rawProvider = selectedProvider || agent?.llm?.id || "";
272121
+ const provider = rawProvider || (authMethod === "december" ? "december" : undefined);
272122
+ const allMsgs = [
272123
+ ...useCliStore.getState().staticMessages,
272124
+ ...useCliStore.getState().activeMessages
272125
+ ];
272126
+ let sessionInputTokens = 0;
272127
+ let sessionOutputTokens = 0;
272128
+ let sessionCacheTokens = 0;
272129
+ let sessionRequests = 0;
272130
+ for (const msg of allMsgs) {
272131
+ if (msg.usage) {
272132
+ sessionInputTokens += msg.usage.promptTokens || 0;
272133
+ sessionOutputTokens += msg.usage.completionTokens || 0;
272134
+ sessionCacheTokens += msg.usage.cacheReadInputTokens || 0;
272135
+ sessionRequests++;
272136
+ }
272137
+ }
272138
+ let weeklyStats;
272139
+ try {
272140
+ weeklyStats = await getWeeklyUsageSummary();
272141
+ } catch {}
272142
+ const now = new Date;
272143
+ const dailyUsage = [];
272144
+ try {
272145
+ const ledger = await loadUsageLedger();
272146
+ for (let i = 6;i >= 0; i--) {
272147
+ const d = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);
272148
+ const dateKey = d.toISOString().slice(0, 10);
272149
+ const day = ledger.days[dateKey];
272150
+ const tokens = (day?.inputTokens || 0) + (day?.outputTokens || 0);
272151
+ const dayName = d.toLocaleDateString("en-US", { weekday: "short" });
272152
+ const formattedDate = d.toLocaleDateString("en-US", {
272153
+ month: "short",
272154
+ day: "numeric"
272155
+ });
272156
+ dailyUsage.push({
272157
+ date: dateKey,
272158
+ dayName,
272159
+ formattedDate,
272160
+ tokens,
272161
+ isToday: i === 0
272162
+ });
272163
+ }
272164
+ } catch {}
272165
+ let balanceInfo;
272166
+ const config = await loadConfig();
272167
+ if (authMethod === "december" && config.decemberToken) {
272168
+ try {
272169
+ const serverUrl = process.env.SERVER_URL || "https://api.trydecember.com";
272170
+ const overviewRes = await fetch(`${serverUrl}/api/v1/billing/overview`, {
272171
+ headers: { Authorization: `Bearer ${config.decemberToken}` },
272172
+ signal: AbortSignal.timeout(2000)
272173
+ });
272174
+ if (overviewRes.ok) {
272175
+ const overviewJson = await overviewRes.json();
272176
+ const balanceCents = overviewJson.data?.creditBalance ?? 0;
272177
+ balanceInfo = {
272178
+ supported: true,
272179
+ balance: `$${(balanceCents / 100).toFixed(2)}`,
272180
+ currency: "USD"
272181
+ };
272182
+ }
272183
+ } catch {}
272184
+ } else if (authMethod === "byok" || !authMethod) {
272185
+ const activeKey = apiKey || config.providers?.[provider || ""] || (provider ? process.env[`${provider.toUpperCase()}_API_KEY`] : undefined);
272186
+ if (activeKey) {
272187
+ try {
272188
+ balanceInfo = await fetchProviderBalance(provider, activeKey, 2000);
272189
+ } catch {}
272190
+ }
272191
+ }
272192
+ const providerKey = (provider || "google").toLowerCase();
272193
+ const data = {
272194
+ model: currentModel,
272195
+ provider: providerKey,
272196
+ providerDisplayName: getCleanProviderDisplayName(providerKey, currentModel),
272197
+ billingUrl: PROVIDER_BILLING_LINKS[providerKey],
272198
+ balance: balanceInfo,
272199
+ sessionStats: {
272200
+ requests: sessionRequests,
272201
+ inputTokens: sessionInputTokens,
272202
+ outputTokens: sessionOutputTokens,
272203
+ cacheReadTokens: sessionCacheTokens,
272204
+ totalTokens: sessionInputTokens + sessionOutputTokens
272205
+ },
272206
+ weeklyStats,
272207
+ dailyUsage: dailyUsage.length > 0 ? dailyUsage : undefined
272208
+ };
272209
+ setUsageData(data);
272210
+ return data;
272211
+ }, [agent, selectedProvider, authMethod, apiKey]);
272212
+ const handleOpenBilling = import_react71.useCallback(async (url) => {
272213
+ if (url) {
272214
+ try {
272215
+ await Promise.resolve().then(() => init_open());
272216
+ await openUrl(url);
272217
+ } catch {}
272218
+ }
272219
+ }, []);
271343
272220
  const handleSubmit = import_react71.useCallback(async (text) => {
271344
272221
  if (text.trim() === "/exit") {
271345
272222
  setShouldExit(true);
@@ -272072,86 +272949,8 @@ ${decStatus}
272072
272949
  return;
272073
272950
  }
272074
272951
  if (text.trim() === "/usage") {
272075
- const currentModel = agent.modelOptions?.model || "gemini-3.6-flash";
272076
- const rawProvider = selectedProvider || agent.llm?.id || "";
272077
- const provider = rawProvider || (authMethod === "december" ? "december" : undefined);
272078
- const allMsgs = [
272079
- ...useCliStore.getState().staticMessages,
272080
- ...useCliStore.getState().activeMessages
272081
- ];
272082
- let sessionInputTokens = 0;
272083
- let sessionOutputTokens = 0;
272084
- let sessionCacheTokens = 0;
272085
- let sessionRequests = 0;
272086
- for (const msg of allMsgs) {
272087
- if (msg.usage) {
272088
- sessionInputTokens += msg.usage.promptTokens || 0;
272089
- sessionOutputTokens += msg.usage.completionTokens || 0;
272090
- sessionCacheTokens += msg.usage.cacheReadInputTokens || 0;
272091
- sessionRequests++;
272092
- }
272093
- }
272094
- let weeklyStats;
272095
- try {
272096
- weeklyStats = await getWeeklyUsageSummary();
272097
- } catch {}
272098
- let balanceInfo;
272099
- const config = await loadConfig();
272100
- if (authMethod === "december" && config.decemberToken) {
272101
- try {
272102
- const serverUrl = process.env.SERVER_URL || "https://api.trydecember.com";
272103
- const overviewRes = await fetch(`${serverUrl}/api/v1/billing/overview`, {
272104
- headers: { Authorization: `Bearer ${config.decemberToken}` },
272105
- signal: AbortSignal.timeout(2000)
272106
- });
272107
- if (overviewRes.ok) {
272108
- const overviewJson = await overviewRes.json();
272109
- const balanceCents = overviewJson.data?.creditBalance ?? 0;
272110
- balanceInfo = {
272111
- supported: true,
272112
- balance: `$${(balanceCents / 100).toFixed(2)}`,
272113
- currency: "USD"
272114
- };
272115
- }
272116
- } catch {}
272117
- } else if (authMethod === "byok" || !authMethod) {
272118
- const activeKey = apiKey || config.providers?.[provider || ""] || (provider ? process.env[`${provider.toUpperCase()}_API_KEY`] : undefined);
272119
- if (activeKey) {
272120
- try {
272121
- balanceInfo = await fetchProviderBalance(provider, activeKey, 2000);
272122
- } catch {}
272123
- }
272124
- }
272125
- const card = formatUsageCard({
272126
- model: currentModel,
272127
- authMethod,
272128
- provider,
272129
- isAuthenticated,
272130
- sessionStats: {
272131
- requests: sessionRequests,
272132
- inputTokens: sessionInputTokens,
272133
- outputTokens: sessionOutputTokens,
272134
- cacheReadTokens: sessionCacheTokens,
272135
- totalTokens: sessionInputTokens + sessionOutputTokens
272136
- },
272137
- weeklyStats,
272138
- balance: balanceInfo
272139
- });
272140
- setActiveMessages((prev) => [
272141
- ...prev,
272142
- {
272143
- id: getNextMsgId(),
272144
- role: "assistant",
272145
- blocks: [
272146
- {
272147
- type: "text",
272148
- content: `
272149
- ${card}
272150
- `
272151
- }
272152
- ]
272153
- }
272154
- ]);
272952
+ await fetchUsageData();
272953
+ setAuthMode("usage");
272155
272954
  return;
272156
272955
  }
272157
272956
  if (text.trim() === "/feedback") {
@@ -272165,8 +272964,6 @@ ${card}
272165
272964
  {
272166
272965
  type: "text",
272167
272966
  content: `
272168
- Opening GitHub issues...
272169
-
272170
272967
  If it doesn't open automatically, please click here:
272171
272968
  [${url}](${url})
272172
272969
 
@@ -272356,6 +273153,7 @@ If it doesn't open automatically, please click here:
272356
273153
  }
272357
273154
  }, [
272358
273155
  agent,
273156
+ fetchUsageData,
272359
273157
  isAuthenticated,
272360
273158
  isStreaming,
272361
273159
  generateGrillQuestions,
@@ -272681,7 +273479,13 @@ If it doesn't open automatically, please click here:
272681
273479
  setPendingToolCall,
272682
273480
  activeModel,
272683
273481
  setActiveModel,
272684
- detectedSubscriptions
273482
+ detectedSubscriptions,
273483
+ usageData,
273484
+ setUsageData,
273485
+ handleRefreshUsage: fetchUsageData,
273486
+ handleOpenBilling,
273487
+ onRefresh: fetchUsageData,
273488
+ onOpenBilling: handleOpenBilling
272685
273489
  };
272686
273490
  }
272687
273491
  var import_react71;
@@ -272699,7 +273503,6 @@ var init_use_agent_session = __esm(async () => {
272699
273503
  init_openrouter_models();
272700
273504
  init_project_context();
272701
273505
  init_provider_factory();
272702
- init_usage_rates2();
272703
273506
  init_usage_tracker();
272704
273507
  init_use_settings_handlers();
272705
273508
  await __promiseAll([
@@ -272848,6 +273651,16 @@ Options:
272848
273651
  --cwd <dir> Set the working directory root
272849
273652
  `;
272850
273653
  }
273654
+ // src/constants/release-highlights.json
273655
+ var release_highlights_default = {
273656
+ version: "0.4.1",
273657
+ title: "What's New in v0.4.1",
273658
+ bullets: [
273659
+ "*(cache)* Implement client and server side caching with redis",
273660
+ "*(auth)* Redis session cache, rate limiting, and token auth"
273661
+ ],
273662
+ url: "https://trydecember.com/docs/changelog"
273663
+ };
272851
273664
 
272852
273665
  // src/index.ts
272853
273666
  init_env_sanitizer();
@@ -273076,7 +273889,7 @@ Executing Headless Task: "${parsedArgs.prompt}"
273076
273889
  inkModule,
273077
273890
  reactModule,
273078
273891
  { FileSessionRepository },
273079
- { getProviderConfig, loadConfig, getAuthStatus },
273892
+ { getProviderConfig, loadConfig, saveConfig, getAuthStatus },
273080
273893
  { suppressConsole },
273081
273894
  { useAgentSession },
273082
273895
  { localOperations, setActiveScopeDir },
@@ -273168,6 +273981,16 @@ Executing Headless Task: "${parsedArgs.prompt}"
273168
273981
  } else {
273169
273982
  agent.loadContext().catch(() => {});
273170
273983
  }
273984
+ await Promise.resolve().then(() => init_bin_discovery());
273985
+ const isFirstRun = !config.lastSeenVersion || compareVersions(package_default.version, config.lastSeenVersion) > 0;
273986
+ let announcement = null;
273987
+ if (isFirstRun) {
273988
+ if (release_highlights_default && Array.isArray(release_highlights_default.bullets) && release_highlights_default.bullets.length > 0) {
273989
+ announcement = release_highlights_default;
273990
+ }
273991
+ config.lastSeenVersion = package_default.version;
273992
+ saveConfig(config).catch(() => {});
273993
+ }
273171
273994
  function AppWrapper(props) {
273172
273995
  const [latestVersion, setLatestVersion] = React.useState(undefined);
273173
273996
  React.useEffect(() => {
@@ -273186,6 +274009,7 @@ Executing Headless Task: "${parsedArgs.prompt}"
273186
274009
  return React.createElement(ChatApp, {
273187
274010
  ...props,
273188
274011
  latestVersion,
274012
+ announcement,
273189
274013
  onUpdateSuccess: handleUpdateSuccess,
273190
274014
  session
273191
274015
  });
@@ -273193,10 +274017,12 @@ Executing Headless Task: "${parsedArgs.prompt}"
273193
274017
  const userEmail = config.decemberToken ? config.email : undefined;
273194
274018
  const isFullscreen = !parsedArgs.isInline;
273195
274019
  if (process.stdout.isTTY) {
273196
- process.stdout.write("\x1B[?2004h");
274020
+ const enterSequences = isFullscreen ? "\x1B[?2004h\x1B[?1000h\x1B[?1006h" : "\x1B[?2004h";
274021
+ const exitSequences = isFullscreen ? "\x1B[?2004l\x1B[?1000l\x1B[?1006l" : "\x1B[?2004l";
274022
+ process.stdout.write(enterSequences);
273197
274023
  const cleanupTerminal = () => {
273198
274024
  try {
273199
- process.stdout.write("\x1B[?2004l");
274025
+ process.stdout.write(exitSequences);
273200
274026
  } catch {}
273201
274027
  };
273202
274028
  process.on("exit", cleanupTerminal);