crosscheck-mcp 0.2.20 → 0.2.21

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.
@@ -466,12 +466,20 @@ var ProviderError = class extends Error {
466
466
  * actually fix. Distinct from `transient`: this is never worth
467
467
  * retrying the SAME model, but IS worth trying a different one. */
468
468
  modelAccessFailure;
469
+ /** True for "the key works, the account is out of credit / over a spend
470
+ * limit." Rides alongside kind "auth" rather than replacing it, because
471
+ * every retry and fallback decision downstream is already tuned to that
472
+ * kind — but the two are completely different things to a human, and
473
+ * reporting "API key rejected" for an unpaid invoice sends people to
474
+ * regenerate a key that was never the problem. */
475
+ billing;
469
476
  constructor(kind, message, opts) {
470
477
  super(message);
471
478
  this.kind = kind;
472
479
  this.status = opts?.status;
473
480
  this.transient = opts?.transient ?? defaultTransient(kind);
474
481
  this.modelAccessFailure = opts?.modelAccessFailure ?? false;
482
+ this.billing = opts?.billing ?? false;
475
483
  if (opts?.retryAfterS !== void 0) {
476
484
  this.retryAfterS = opts.retryAfterS;
477
485
  }
@@ -509,7 +517,7 @@ function httpFailureToProviderError(provider, status, bodyText, retryAfterS, mod
509
517
  return new ProviderError(
510
518
  "auth",
511
519
  `${provider}: out of credits or billing isn't set up (HTTP ${status}). Your API key is reaching ${provider}, but the account has no usable balance \u2014 add credits / enable billing in your ${provider} console, then retry. Detail: ${detail}`,
512
- { status }
520
+ { status, billing: true }
513
521
  );
514
522
  }
515
523
  if (status === 401 || status === 403) {
@@ -1351,7 +1359,7 @@ import { z } from "zod";
1351
1359
 
1352
1360
  // src/server-meta.ts
1353
1361
  var SERVER_NAME = "crosscheck-agent";
1354
- var SERVER_VERSION = true ? "0.2.20" : "0.0.0-dev";
1362
+ var SERVER_VERSION = true ? "0.2.21" : "0.0.0-dev";
1355
1363
 
1356
1364
  // src/tools/audit.ts
1357
1365
  import { readdirSync, readFileSync as readFileSync3, statSync } from "fs";
@@ -1857,7 +1865,9 @@ async function attachUsageBlock(result, answers, opts) {
1857
1865
  purpose: a.usage?.purpose ?? null,
1858
1866
  wall_ms: a.elapsed_ms ?? 0,
1859
1867
  cpu_ms: a.cpu_ms ?? 0,
1860
- cache_hit: Boolean(a.cache_hit)
1868
+ cache_hit: Boolean(a.cache_hit),
1869
+ ...a.error_kind ? { error_kind: a.error_kind } : {},
1870
+ ...a.error_billing ? { error_billing: true } : {}
1861
1871
  }))
1862
1872
  };
1863
1873
  result["timing"] = timing;
@@ -2158,11 +2168,13 @@ async function askOne(provider, messages, opts) {
2158
2168
  const cpuMs = Math.trunc((cpu.user + cpu.system) / 1e3);
2159
2169
  const kind = e instanceof ProviderError ? e.kind : "other";
2160
2170
  const msg = e instanceof Error ? e.message : String(e);
2171
+ const billing = e instanceof ProviderError && e.billing;
2161
2172
  return {
2162
2173
  provider: provider.name,
2163
2174
  model: provider.model,
2164
2175
  error: msg,
2165
2176
  error_kind: kind,
2177
+ ...billing ? { error_billing: true } : {},
2166
2178
  attempts: 0,
2167
2179
  usage: emptyUsage(provider.name, provider.model, opts.purpose),
2168
2180
  cache_hit: false,
@@ -11770,7 +11782,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
11770
11782
  var DEFAULT_PACKAGE = "crosscheck-cli";
11771
11783
  var FETCH_TIMEOUT_MS = 3e3;
11772
11784
  function engineVersion() {
11773
- return true ? "0.2.20" : "0.0.0-dev";
11785
+ return true ? "0.2.21" : "0.0.0-dev";
11774
11786
  }
11775
11787
  function defaultUpdateCachePath() {
11776
11788
  const base = process.env["CROSSCHECK_DATA_DIR"] || path9.join(os.homedir() || os.tmpdir(), ".crosscheck");