archondev 2.19.4 → 2.19.6

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.
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  listLocalAtoms,
8
8
  loadAtom
9
- } from "./chunk-IKMCIWK3.js";
9
+ } from "./chunk-OTODLPY4.js";
10
10
  import {
11
11
  loadConfig
12
12
  } from "./chunk-SVU7MLG6.js";
@@ -763,6 +763,7 @@ async function interactiveSettings() {
763
763
  }
764
764
  await displayCurrentSettings(profile, usage, providers);
765
765
  console.log(chalk.bold("\nOptions:\n"));
766
+ console.log(chalk.dim("Type naturally (recommended) or use a shortcut:\n"));
766
767
  console.log(` ${chalk.cyan("1")}) Change billing mode (BYOK / Credits)`);
767
768
  console.log(` ${chalk.cyan("2")}) Set default models`);
768
769
  console.log(` ${chalk.cyan("x")}) Smart Routing (cost optimization)`);
@@ -771,7 +772,8 @@ async function interactiveSettings() {
771
772
  console.log(` ${chalk.cyan("5")}) Reset to defaults`);
772
773
  console.log(` ${chalk.cyan("b")}) Back to project`);
773
774
  console.log();
774
- const choice = await prompt("Enter choice");
775
+ const rawChoice = await prompt("What would you like to do?");
776
+ const choice = resolveSettingsChoice(rawChoice);
775
777
  switch (choice.toLowerCase()) {
776
778
  case "1":
777
779
  await changeBillingMode(profile.tier);
@@ -790,7 +792,7 @@ async function interactiveSettings() {
790
792
  await interactiveSettings();
791
793
  break;
792
794
  case "4":
793
- await showUsageDetails();
795
+ await showUsageDetails({ pauseForInput: true });
794
796
  await interactiveSettings();
795
797
  break;
796
798
  case "5":
@@ -801,7 +803,7 @@ async function interactiveSettings() {
801
803
  console.log(chalk.dim("\nReturning to project...\n"));
802
804
  return;
803
805
  default:
804
- console.log(chalk.yellow("Invalid choice."));
806
+ console.log(chalk.yellow("I did not catch that. Try again or describe what you need."));
805
807
  await interactiveSettings();
806
808
  }
807
809
  }
@@ -843,7 +845,8 @@ async function changeBillingMode(currentTier) {
843
845
  console.log(chalk.dim(" 10% service fee applied.\n"));
844
846
  console.log(` ${chalk.cyan("b")}) Back`);
845
847
  console.log();
846
- const choice = await prompt("Enter choice");
848
+ const rawChoice = await prompt("How do you want to pay?");
849
+ const choice = resolveBillingChoice(rawChoice);
847
850
  if (choice === "1" && !byokSelected) {
848
851
  const spinner = ora("Switching to BYOK...").start();
849
852
  const result = await updateUserTier("BYOK");
@@ -861,9 +864,11 @@ async function changeBillingMode(currentTier) {
861
864
  } else {
862
865
  spinner.fail(chalk.red(result.error ?? "Failed to update"));
863
866
  }
864
- } else if (choice.toLowerCase() !== "b") {
867
+ } else if (choice !== "b") {
865
868
  if (choice === "1" && byokSelected || choice === "2" && creditsSelected) {
866
869
  console.log(chalk.dim("Already using this billing mode."));
870
+ } else {
871
+ console.log(chalk.yellow("I did not catch that."));
867
872
  }
868
873
  }
869
874
  }
@@ -877,7 +882,8 @@ async function setDefaultModelsMenu(profile, providers) {
877
882
  console.log();
878
883
  console.log(` ${chalk.cyan("b")}) Back`);
879
884
  console.log();
880
- const choice = await prompt("Which model to change?");
885
+ const rawChoice = await prompt("Which default model should change?");
886
+ const choice = resolveDefaultModelSlotChoice(rawChoice);
881
887
  const keyMap = {
882
888
  "1": "fast-model",
883
889
  "2": "thinking-model",
@@ -889,7 +895,7 @@ async function setDefaultModelsMenu(profile, providers) {
889
895
  }
890
896
  const prefKey = keyMap[choice];
891
897
  if (!prefKey) {
892
- console.log(chalk.yellow("Invalid choice."));
898
+ console.log(chalk.yellow("I did not catch that."));
893
899
  return;
894
900
  }
895
901
  const models = getAllActiveModels();
@@ -906,8 +912,8 @@ async function setDefaultModelsMenu(profile, providers) {
906
912
  console.log(` ${chalk.cyan(String(i + 1))}) ${m.modelName} ${categoryLabel}`);
907
913
  });
908
914
  console.log();
909
- const modelChoice = await prompt("Select model number");
910
- const modelIndex = parseInt(modelChoice, 10) - 1;
915
+ const modelChoice = await prompt("Which model do you want? (number or model name)");
916
+ const modelIndex = resolveModelChoice(modelChoice, availableModels);
911
917
  if (modelIndex >= 0 && modelIndex < availableModels.length) {
912
918
  const selectedModel = availableModels[modelIndex];
913
919
  if (selectedModel) {
@@ -940,7 +946,8 @@ async function setSmartRoutingMenu(profile, providers) {
940
946
  console.log(` ${chalk.cyan("5")}) View operations by tier`);
941
947
  console.log(` ${chalk.cyan("b")}) Back`);
942
948
  console.log();
943
- const choice = await prompt("Select option");
949
+ const rawChoice = await prompt("What would you like to change?");
950
+ const choice = resolveSmartRoutingChoice(rawChoice);
944
951
  if (choice.toLowerCase() === "b") {
945
952
  return;
946
953
  }
@@ -963,7 +970,8 @@ async function setSmartRoutingMenu(profile, providers) {
963
970
  console.log(` ${chalk.cyan("3")}) google`);
964
971
  console.log(` ${chalk.cyan("0")}) Clear preference (auto)`);
965
972
  console.log();
966
- const provChoice = await prompt("Select");
973
+ const provChoiceRaw = await prompt("Which provider should be preferred?");
974
+ const provChoice = resolveProviderChoice(provChoiceRaw);
967
975
  const providerMap = {
968
976
  "0": null,
969
977
  "1": "anthropic",
@@ -997,12 +1005,12 @@ Select model for ${selectedTier.tier} tier:
997
1005
  console.log(` ${chalk.cyan(String(i + 1))}) ${m.modelName} ${categoryLabel}`);
998
1006
  });
999
1007
  console.log();
1000
- const modelChoice = await prompt("Select model number");
1008
+ const modelChoice = await prompt("Which model do you want for this tier? (number or model name)");
1001
1009
  if (modelChoice === "0") {
1002
1010
  await setTierPreference(selectedTier.key, null);
1003
1011
  return;
1004
1012
  }
1005
- const modelIndex = parseInt(modelChoice, 10) - 1;
1013
+ const modelIndex = resolveModelChoice(modelChoice, availableModels);
1006
1014
  if (modelIndex >= 0 && modelIndex < availableModels.length) {
1007
1015
  const selectedModel = availableModels[modelIndex];
1008
1016
  if (selectedModel) {
@@ -1057,7 +1065,8 @@ async function manageApiKeys() {
1057
1065
  console.log(` ${chalk.cyan("4")}) Remove a key`);
1058
1066
  console.log(` ${chalk.cyan("b")}) Back`);
1059
1067
  console.log();
1060
- const choice = await prompt("Enter choice");
1068
+ const rawChoice = await prompt("What do you want to do with API keys?");
1069
+ const choice = resolveApiKeysChoice(rawChoice);
1061
1070
  const providerMap = {
1062
1071
  "1": "anthropic",
1063
1072
  "2": "openai",
@@ -1073,8 +1082,8 @@ async function manageApiKeys() {
1073
1082
  }
1074
1083
  console.log("\nWhich provider to remove?");
1075
1084
  providers.forEach((p, i) => console.log(` ${chalk.cyan(String(i + 1))}) ${p}`));
1076
- const removeChoice = await prompt("Select");
1077
- const removeIndex = parseInt(removeChoice, 10) - 1;
1085
+ const removeChoice = await prompt("Which provider key should be removed?");
1086
+ const removeIndex = resolveProviderIndexChoice(removeChoice, providers);
1078
1087
  if (removeIndex >= 0 && removeIndex < providers.length) {
1079
1088
  const providerToRemove = providers[removeIndex];
1080
1089
  if (providerToRemove) {
@@ -1088,9 +1097,182 @@ async function manageApiKeys() {
1088
1097
  if (provider) {
1089
1098
  const { addKey } = await import("./keys-T2VPHE7Z.js");
1090
1099
  await addKey(provider);
1100
+ } else if (choice !== "b") {
1101
+ console.log(chalk.yellow("I did not catch that."));
1102
+ }
1103
+ }
1104
+ function resolveSettingsChoice(input) {
1105
+ const normalized = input.trim().toLowerCase();
1106
+ if (!normalized) return "";
1107
+ if (normalized === "1" || normalized.includes("billing") || normalized.includes("tier") || normalized.includes("pay")) return "1";
1108
+ if (normalized === "2" || normalized.includes("default model") || normalized.includes("model")) return "2";
1109
+ if (normalized === "x" || normalized === "smart" || normalized.includes("routing") || normalized.includes("cost optimization")) return "x";
1110
+ if (normalized === "3" || normalized.includes("key")) return "3";
1111
+ if (normalized === "4" || normalized.includes("usage") || normalized.includes("spend") || normalized.includes("cost details")) return "4";
1112
+ if (normalized === "5" || normalized.includes("reset") || normalized.includes("defaults")) return "5";
1113
+ if (normalized === "b" || normalized.includes("back") || normalized.includes("return")) return "b";
1114
+ return normalized;
1115
+ }
1116
+ function resolveBillingChoice(input) {
1117
+ const normalized = input.trim().toLowerCase();
1118
+ if (!normalized) return "";
1119
+ if (normalized === "1" || normalized.includes("byok") || normalized.includes("own key")) return "1";
1120
+ if (normalized === "2" || normalized.includes("credit") || normalized.includes("managed")) return "2";
1121
+ if (normalized === "b" || normalized.includes("back")) return "b";
1122
+ return normalized;
1123
+ }
1124
+ function resolveDefaultModelSlotChoice(input) {
1125
+ const normalized = input.trim().toLowerCase();
1126
+ if (!normalized) return "";
1127
+ if (normalized === "1" || normalized.includes("fast")) return "1";
1128
+ if (normalized === "2" || normalized.includes("thinking")) return "2";
1129
+ if (normalized === "3" || normalized.includes("primary")) return "3";
1130
+ if (normalized === "4" || normalized.includes("secondary")) return "4";
1131
+ if (normalized === "b" || normalized.includes("back")) return "b";
1132
+ return normalized;
1133
+ }
1134
+ function resolveModelChoice(choice, models) {
1135
+ const normalized = choice.trim().toLowerCase();
1136
+ const numeric = parseInt(normalized, 10);
1137
+ if (!Number.isNaN(numeric)) {
1138
+ return numeric - 1;
1139
+ }
1140
+ const idx = models.findIndex(
1141
+ (m) => m.modelId.toLowerCase() === normalized || m.modelName.toLowerCase() === normalized || m.modelName.toLowerCase().includes(normalized) || normalized.includes(m.modelName.toLowerCase())
1142
+ );
1143
+ return idx;
1144
+ }
1145
+ function resolveSmartRoutingChoice(input) {
1146
+ const normalized = input.trim().toLowerCase();
1147
+ if (!normalized) return "";
1148
+ if (normalized === "1" || normalized.includes("planning")) return "1";
1149
+ if (normalized === "2" || normalized.includes("reasoning")) return "2";
1150
+ if (normalized === "3" || normalized.includes("execution")) return "3";
1151
+ if (normalized === "4" || normalized.includes("provider")) return "4";
1152
+ if (normalized === "5" || normalized.includes("operation")) return "5";
1153
+ if (normalized === "b" || normalized.includes("back")) return "b";
1154
+ return normalized;
1155
+ }
1156
+ function resolveProviderChoice(input) {
1157
+ const normalized = input.trim().toLowerCase();
1158
+ if (!normalized) return "";
1159
+ if (normalized === "0" || normalized.includes("auto") || normalized.includes("clear")) return "0";
1160
+ if (normalized === "1" || normalized.includes("anthropic")) return "1";
1161
+ if (normalized === "2" || normalized.includes("openai")) return "2";
1162
+ if (normalized === "3" || normalized.includes("google") || normalized.includes("gemini")) return "3";
1163
+ return normalized;
1164
+ }
1165
+ function resolveApiKeysChoice(input) {
1166
+ const normalized = input.trim().toLowerCase();
1167
+ if (!normalized) return "";
1168
+ if (normalized === "1" || normalized.includes("add") && normalized.includes("anthropic")) return "1";
1169
+ if (normalized === "2" || normalized.includes("add") && normalized.includes("openai")) return "2";
1170
+ if (normalized === "3" || normalized.includes("add") && (normalized.includes("google") || normalized.includes("gemini"))) return "3";
1171
+ if (normalized === "4" || normalized.includes("remove") || normalized.includes("delete")) return "4";
1172
+ if (normalized === "b" || normalized.includes("back")) return "b";
1173
+ return normalized;
1174
+ }
1175
+ function resolveProviderIndexChoice(choice, providers) {
1176
+ const normalized = choice.trim().toLowerCase();
1177
+ const numeric = parseInt(normalized, 10);
1178
+ if (!Number.isNaN(numeric)) return numeric - 1;
1179
+ return providers.findIndex((p) => normalized.includes(p));
1180
+ }
1181
+ var __preferencesChoiceHelpers = {
1182
+ resolveSettingsChoice,
1183
+ resolveBillingChoice,
1184
+ resolveDefaultModelSlotChoice,
1185
+ resolveSmartRoutingChoice,
1186
+ resolveProviderChoice,
1187
+ resolveApiKeysChoice,
1188
+ resolveProviderIndexChoice,
1189
+ resolveModelChoice
1190
+ };
1191
+ function formatLocalDateTime(value) {
1192
+ const date = new Date(value);
1193
+ if (isNaN(date.getTime())) {
1194
+ return value;
1091
1195
  }
1196
+ return date.toLocaleString();
1197
+ }
1198
+ function formatUsagePeriodLabel(periodSource) {
1199
+ if (periodSource === "credit_purchase") return "Since last top-up";
1200
+ if (periodSource === "month") return "Current month to date";
1201
+ return "Current billing period";
1092
1202
  }
1093
- async function showUsageDetails() {
1203
+ function sumModelCost(byModel) {
1204
+ return (byModel ?? []).reduce((sum, row) => sum + row.cost, 0);
1205
+ }
1206
+ function renderModelBreakdown(rows, options = {}) {
1207
+ const indent = options.indent ?? " ";
1208
+ if (rows.length === 0) {
1209
+ console.log(chalk.dim(`${indent}No usage recorded.`));
1210
+ return;
1211
+ }
1212
+ const total = rows.reduce((sum, row) => sum + row.cost, 0);
1213
+ const sorted = [...rows].sort((a, b) => b.cost - a.cost);
1214
+ for (const row of sorted) {
1215
+ const modelInfo = findModel(row.model);
1216
+ const name = modelInfo?.name ?? row.model;
1217
+ const tokenTotal = row.inputTokens + row.outputTokens;
1218
+ const share = total > 0 ? (row.cost / total * 100).toFixed(1) : "0.0";
1219
+ const note = options.costNote ? ` ${chalk.dim(options.costNote)}` : "";
1220
+ console.log(`${indent}${name}: ${formatTokens(tokenTotal)} tokens | ${formatCost(row.cost)} (${share}%)${note}`);
1221
+ }
1222
+ }
1223
+ async function resolveAuthAndProfileIds(authToken, fallbackAuthId) {
1224
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1225
+ let authId = fallbackAuthId ?? null;
1226
+ if (!authId) {
1227
+ const { data, error } = await supabase.auth.getUser();
1228
+ if (error || !data.user?.id) {
1229
+ return { authId: null, profileId: null };
1230
+ }
1231
+ authId = data.user.id;
1232
+ }
1233
+ const { data: profileRow, error: profileError } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
1234
+ if (profileError || !profileRow?.id) {
1235
+ return { authId, profileId: null };
1236
+ }
1237
+ return { authId, profileId: profileRow.id };
1238
+ }
1239
+ async function fetchUsageRows(authToken, profileId, startIso, endIso) {
1240
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1241
+ const { data, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", profileId).gte("created_at", startIso).lte("created_at", endIso);
1242
+ if (error || !data) {
1243
+ return null;
1244
+ }
1245
+ return data;
1246
+ }
1247
+ function aggregateUsageRows(rows, start, end) {
1248
+ let totalInputTokens = 0;
1249
+ let totalOutputTokens = 0;
1250
+ let totalCost = 0;
1251
+ const byModelMap = /* @__PURE__ */ new Map();
1252
+ for (const row of rows) {
1253
+ const ts = new Date(row.created_at);
1254
+ if (ts < start || ts > end) continue;
1255
+ totalInputTokens += row.input_tokens;
1256
+ totalOutputTokens += row.output_tokens;
1257
+ totalCost += row.base_cost;
1258
+ const existing = byModelMap.get(row.model);
1259
+ if (existing) {
1260
+ existing.inputTokens += row.input_tokens;
1261
+ existing.outputTokens += row.output_tokens;
1262
+ existing.cost += row.base_cost;
1263
+ } else {
1264
+ byModelMap.set(row.model, {
1265
+ inputTokens: row.input_tokens,
1266
+ outputTokens: row.output_tokens,
1267
+ cost: row.base_cost
1268
+ });
1269
+ }
1270
+ }
1271
+ const byModel = Array.from(byModelMap.entries()).map(([model, stats]) => ({ model, ...stats })).sort((a, b) => b.cost - a.cost);
1272
+ return { totalInputTokens, totalOutputTokens, totalCost, byModel };
1273
+ }
1274
+ async function showUsageDetails(options = {}) {
1275
+ const { pauseForInput = false } = options;
1094
1276
  console.log(chalk.bold("\n-- Usage Details --\n"));
1095
1277
  const spinner = ora("Loading usage data...").start();
1096
1278
  const config = await loadConfig();
@@ -1112,84 +1294,49 @@ async function showUsageDetails() {
1112
1294
  }
1113
1295
  const data = await response.json();
1114
1296
  if (data.tier === "BYOK") {
1115
- if (!authId) {
1297
+ const ids = await resolveAuthAndProfileIds(authToken, authId);
1298
+ if (!ids.authId || !ids.profileId) {
1116
1299
  console.log(chalk.yellow("Unable to resolve user ID for usage details."));
1117
1300
  return;
1118
1301
  }
1119
- const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1120
- const { data: profileRow, error: profileError } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
1121
- if (profileError || !profileRow?.id) {
1122
- console.log(chalk.yellow("Unable to resolve profile for usage details."));
1123
- return;
1124
- }
1125
- const profileId = profileRow.id;
1126
1302
  const now = /* @__PURE__ */ new Date();
1127
1303
  const yearStart = new Date(now.getFullYear(), 0, 1);
1128
- const { data: usageRows, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", profileId).gte("created_at", yearStart.toISOString()).lte("created_at", now.toISOString());
1129
- if (error || !usageRows) {
1304
+ const usageRows = await fetchUsageRows(authToken, ids.profileId, yearStart.toISOString(), now.toISOString());
1305
+ if (!usageRows) {
1130
1306
  console.log(chalk.yellow("Unable to fetch BYOK usage data."));
1131
1307
  return;
1132
1308
  }
1133
- const rows = usageRows;
1134
1309
  const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1135
- const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay());
1136
- const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1310
+ const startOf24h = new Date(now.getTime() - 24 * 60 * 60 * 1e3);
1311
+ const startOf7d = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1e3);
1312
+ const startOf30d = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1e3);
1137
1313
  const periods = [
1138
1314
  { label: "Today", start: startOfToday, end: now },
1139
- { label: "Week to Date (Sun\u2013Sat)", start: startOfWeek, end: now },
1140
- { label: "Month to Date", start: startOfMonth, end: now },
1315
+ { label: "Last 24 Hours", start: startOf24h, end: now },
1316
+ { label: "Last 7 Days", start: startOf7d, end: now },
1317
+ { label: "Last 30 Days", start: startOf30d, end: now },
1141
1318
  { label: "Year to Date", start: yearStart, end: now }
1142
1319
  ];
1143
- const aggregate = (start, end) => {
1144
- let totalInputTokens = 0;
1145
- let totalOutputTokens = 0;
1146
- let totalCost = 0;
1147
- const byModelMap = /* @__PURE__ */ new Map();
1148
- for (const row of rows) {
1149
- const ts = new Date(row.created_at);
1150
- if (ts < start || ts > end) continue;
1151
- totalInputTokens += row.input_tokens;
1152
- totalOutputTokens += row.output_tokens;
1153
- totalCost += row.base_cost;
1154
- const existing = byModelMap.get(row.model);
1155
- if (existing) {
1156
- existing.inputTokens += row.input_tokens;
1157
- existing.outputTokens += row.output_tokens;
1158
- existing.cost += row.base_cost;
1159
- } else {
1160
- byModelMap.set(row.model, {
1161
- inputTokens: row.input_tokens,
1162
- outputTokens: row.output_tokens,
1163
- cost: row.base_cost
1164
- });
1165
- }
1166
- }
1167
- const byModel = Array.from(byModelMap.entries()).map(([model, stats]) => ({ model, ...stats })).sort((a, b) => b.cost - a.cost);
1168
- return { totalInputTokens, totalOutputTokens, totalCost, byModel };
1169
- };
1170
1320
  console.log(chalk.blue("BYOK Usage (local time):"));
1321
+ console.log(chalk.dim("Estimated provider spend by model (you are billed directly by provider)."));
1171
1322
  for (const period of periods) {
1172
- const summary = aggregate(period.start, period.end);
1323
+ const summary = aggregateUsageRows(usageRows, period.start, period.end);
1173
1324
  console.log();
1174
1325
  console.log(chalk.bold(`${period.label}:`));
1175
1326
  console.log(` ${period.start.toLocaleDateString()} \u2192 ${period.end.toLocaleDateString()}`);
1176
1327
  console.log(` Tokens: ${formatTokens(summary.totalInputTokens + summary.totalOutputTokens)} (in ${formatTokens(summary.totalInputTokens)} / out ${formatTokens(summary.totalOutputTokens)})`);
1177
- console.log(` Cost: ${formatCost(summary.totalCost)} ${chalk.dim("(paid directly to provider)")}`);
1178
- if (summary.byModel.length > 0) {
1179
- console.log(chalk.dim(" By Model:"));
1180
- for (const model of summary.byModel) {
1181
- const modelInfo = findModel(model.model);
1182
- const name = modelInfo?.name ?? model.model;
1183
- const tokenTotal = model.inputTokens + model.outputTokens;
1184
- console.log(` ${name}: ${formatTokens(tokenTotal)} tokens (${formatCost(model.cost)})`);
1185
- }
1186
- } else {
1187
- console.log(chalk.dim(" No usage recorded."));
1188
- }
1328
+ console.log(` Estimated Spend: ${formatCost(summary.totalCost)} ${chalk.dim("(paid directly to provider)")}`);
1329
+ console.log(chalk.dim(" By Model:"));
1330
+ renderModelBreakdown(summary.byModel, { indent: " " });
1189
1331
  }
1190
1332
  } else {
1191
- console.log(chalk.blue("Current Billing Period:"));
1192
- console.log(` ${data.periodStart} to ${data.periodEnd}`);
1333
+ const periodLabel = formatUsagePeriodLabel(data.periodSource);
1334
+ const byModel = [...data.byModel ?? []].sort((a, b) => b.cost - a.cost);
1335
+ const modelBilledTotal = sumModelCost(byModel);
1336
+ const modelBaseTotal = data.totalBaseCost;
1337
+ const modelFeeTotal = Math.max(0, modelBilledTotal - modelBaseTotal);
1338
+ console.log(chalk.blue(`${periodLabel}:`));
1339
+ console.log(` ${formatLocalDateTime(data.periodStart)} \u2192 ${formatLocalDateTime(data.periodEnd)}`);
1193
1340
  console.log();
1194
1341
  console.log(chalk.blue("Token Usage:"));
1195
1342
  console.log(` Input: ${formatTokens(data.totalInputTokens)} tokens`);
@@ -1197,24 +1344,29 @@ async function showUsageDetails() {
1197
1344
  console.log(` Total: ${formatTokens(data.totalInputTokens + data.totalOutputTokens)} tokens`);
1198
1345
  console.log();
1199
1346
  console.log(chalk.blue("Cost:"));
1200
- console.log(` Base Cost: ${formatCost(data.totalBaseCost)}`);
1201
1347
  if (data.tier === "CREDITS") {
1202
- const withFee = data.totalBaseCost * 1.1;
1203
- console.log(` With 10% Fee: ${formatCost(withFee)}`);
1348
+ console.log(` Base Model Cost: ${formatCost(modelBaseTotal)}`);
1349
+ console.log(` Platform Fee: ${formatCost(modelFeeTotal)}`);
1350
+ console.log(` Credits Deducted:${formatCost(modelBilledTotal)}`);
1351
+ } else {
1352
+ console.log(` Estimated Cost: ${formatCost(modelBaseTotal)}`);
1204
1353
  }
1205
- if (data.byModel && data.byModel.length > 0) {
1354
+ if (byModel.length > 0) {
1206
1355
  console.log();
1207
1356
  console.log(chalk.blue("By Model:"));
1208
- for (const stats of data.byModel) {
1209
- const modelInfo = findModel(stats.model);
1210
- const name = modelInfo?.name ?? stats.model;
1211
- console.log(` ${name}: ${formatTokens(stats.inputTokens + stats.outputTokens)} tokens (${formatCost(stats.cost)})`);
1212
- }
1357
+ renderModelBreakdown(
1358
+ byModel.map((row) => ({
1359
+ model: row.model,
1360
+ inputTokens: row.inputTokens,
1361
+ outputTokens: row.outputTokens,
1362
+ cost: row.cost
1363
+ }))
1364
+ );
1213
1365
  }
1214
1366
  if (data.byOperation && data.byOperation.length > 0) {
1215
1367
  console.log();
1216
1368
  console.log(chalk.blue("By Operation:"));
1217
- for (const stats of data.byOperation) {
1369
+ for (const stats of [...data.byOperation].sort((a, b) => b.cost - a.cost)) {
1218
1370
  console.log(` ${stats.operation}: ${formatTokens(stats.tokenCount)} tokens (${formatCost(stats.cost)})`);
1219
1371
  }
1220
1372
  }
@@ -1223,8 +1375,12 @@ async function showUsageDetails() {
1223
1375
  spinner.stop();
1224
1376
  console.log(chalk.yellow("Error fetching usage data."));
1225
1377
  }
1226
- console.log();
1227
- await prompt("Press Enter to continue");
1378
+ if (pauseForInput) {
1379
+ console.log();
1380
+ await prompt("Press Enter to continue");
1381
+ } else {
1382
+ console.log();
1383
+ }
1228
1384
  }
1229
1385
 
1230
1386
  export {
@@ -1236,5 +1392,6 @@ export {
1236
1392
  resetPreferences,
1237
1393
  listModels,
1238
1394
  interactiveSettings,
1395
+ __preferencesChoiceHelpers,
1239
1396
  showUsageDetails
1240
1397
  };