@askalf/dario 5.2.2 → 5.2.3

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.
@@ -63,6 +63,30 @@ export declare function billingBucketFromClaim(claim: string | null | undefined)
63
63
  * non-subscription billing classification or the `unknown` sentinel below.
64
64
  */
65
65
  export declare const SUBSCRIPTION_CLAIMS: ReadonlySet<string>;
66
+ /**
67
+ * One-line per-request usage summary for verbose (-v / -vv) logs.
68
+ *
69
+ * dario already parses `input_tokens` / `cache_read_input_tokens` /
70
+ * `cache_creation_input_tokens` off every response into analytics and the
71
+ * `--log-file`, but never printed them to the console — so anyone debugging
72
+ * subscription burn (dario#678) only ever saw the request body and the
73
+ * billing *bucket*, never the cache accounting that actually governs cost.
74
+ * This surfaces it next to the existing `billing:` line so a plain `-vv`
75
+ * capture is self-diagnosing.
76
+ *
77
+ * `cachedPct` = cache_read / (input + cache_read + cache_create): the share of
78
+ * *prompt* tokens served from cache rather than freshly billed. On a repeated
79
+ * prompt a LOW value means the prefix is being re-created (a >5-minute gap
80
+ * expired the 5m TTL, or the cached prefix changed) — the exact signal the
81
+ * cache-TTL discussion turns on. Output tokens are excluded from the ratio
82
+ * (they are never cacheable). Pure + total-zero-safe for unit testing.
83
+ */
84
+ export declare function formatUsageLogLine(requestCount: number, u: {
85
+ inputTokens?: number;
86
+ outputTokens?: number;
87
+ cacheReadTokens?: number;
88
+ cacheCreateTokens?: number;
89
+ }): string;
66
90
  /**
67
91
  * The sentinel `claim` dario assigns when a response carried no rate-limit
68
92
  * header at all (non-200s, stream aborts, early rejects — see `pool.ts`
package/dist/analytics.js CHANGED
@@ -62,6 +62,33 @@ export const SUBSCRIPTION_CLAIMS = new Set([
62
62
  'five_hour_overage_included',
63
63
  'seven_day_overage_included',
64
64
  ]);
65
+ /**
66
+ * One-line per-request usage summary for verbose (-v / -vv) logs.
67
+ *
68
+ * dario already parses `input_tokens` / `cache_read_input_tokens` /
69
+ * `cache_creation_input_tokens` off every response into analytics and the
70
+ * `--log-file`, but never printed them to the console — so anyone debugging
71
+ * subscription burn (dario#678) only ever saw the request body and the
72
+ * billing *bucket*, never the cache accounting that actually governs cost.
73
+ * This surfaces it next to the existing `billing:` line so a plain `-vv`
74
+ * capture is self-diagnosing.
75
+ *
76
+ * `cachedPct` = cache_read / (input + cache_read + cache_create): the share of
77
+ * *prompt* tokens served from cache rather than freshly billed. On a repeated
78
+ * prompt a LOW value means the prefix is being re-created (a >5-minute gap
79
+ * expired the 5m TTL, or the cached prefix changed) — the exact signal the
80
+ * cache-TTL discussion turns on. Output tokens are excluded from the ratio
81
+ * (they are never cacheable). Pure + total-zero-safe for unit testing.
82
+ */
83
+ export function formatUsageLogLine(requestCount, u) {
84
+ const inp = u.inputTokens ?? 0;
85
+ const out = u.outputTokens ?? 0;
86
+ const cr = u.cacheReadTokens ?? 0;
87
+ const cc = u.cacheCreateTokens ?? 0;
88
+ const promptTotal = inp + cr + cc;
89
+ const pct = promptTotal > 0 ? Math.round((cr / promptTotal) * 100) : 0;
90
+ return `[dario] #${requestCount} usage: in=${inp} out=${out} cache_read=${cr} cache_create=${cc} (${pct}% of prompt from cache)`;
91
+ }
65
92
  /**
66
93
  * The sentinel `claim` dario assigns when a response carried no rate-limit
67
94
  * header at all (non-200s, stream aborts, early rejects — see `pool.ts`
package/dist/proxy.js CHANGED
@@ -13,7 +13,7 @@ import { buildCCRequest, applyCcPromptCaching, parseEffortSuffix, reverseMapResp
13
13
  import { stampCch, hasCchSeed } from './cch.js';
14
14
  import { describeTemplate, detectDrift, checkCCCompat } from './live-fingerprint.js';
15
15
  import { AccountPool, computeStickyKey, parseRateLimits, modelFamily, isInAuthCooldown, authCooldownMs, reconcilePoolAccounts } from './pool.js';
16
- import { Analytics, billingBucketFromClaim, SUBSCRIPTION_CLAIMS } from './analytics.js';
16
+ import { Analytics, billingBucketFromClaim, formatUsageLogLine, SUBSCRIPTION_CLAIMS } from './analytics.js';
17
17
  import { OverageGuard, buildHaltErrorBody } from './overage-guard.js';
18
18
  import { notify as osNotify } from './notify.js';
19
19
  import { loadAllAccounts, loadAccount, refreshAccountToken, resyncLoginFromCredentialsIfStale, ensureLoginCredentialsInPool } from './accounts.js';
@@ -3217,6 +3217,11 @@ export async function startProxy(opts = {}) {
3217
3217
  preserve_tools: preserveToolsEffective,
3218
3218
  stream: true,
3219
3219
  });
3220
+ if (verbose)
3221
+ console.log(formatUsageLogLine(requestCount, {
3222
+ inputTokens: streamInputTokens, outputTokens: streamOutputTokens,
3223
+ cacheReadTokens: streamCacheReadTokens, cacheCreateTokens: streamCacheCreateTokens,
3224
+ }));
3220
3225
  }
3221
3226
  else {
3222
3227
  // Buffer and forward
@@ -3280,6 +3285,8 @@ export async function startProxy(opts = {}) {
3280
3285
  preserve_tools: preserveToolsEffective,
3281
3286
  stream: false,
3282
3287
  });
3288
+ if (verbose && bufferedUsage)
3289
+ console.log(formatUsageLogLine(requestCount, bufferedUsage));
3283
3290
  if (verbose)
3284
3291
  console.log(`[dario] #${requestCount} ${upstream.status}`);
3285
3292
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "5.2.2",
3
+ "version": "5.2.3",
4
4
  "description": "Use your Claude Pro/Max subscription in any tool — Cursor, Cline, Aider, the Agent SDK, your scripts — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint.",
5
5
  "type": "module",
6
6
  "bin": {