@askalf/dario 4.8.103 → 4.8.104

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.
@@ -118,7 +118,18 @@ export declare class Analytics extends EventEmitter {
118
118
  private computeStats;
119
119
  private perAccountStats;
120
120
  private perModelStats;
121
- private utilizationTrend;
121
+ /**
122
+ * The most recent rate-limit snapshot in the window — current 5h / 7d
123
+ * utilization (0–1) as of the last request. The Analytics tab's rate-limit
124
+ * gauge reads this; an empty window reads 0/0. Mirrors `perAccountStats`'
125
+ * `last.util*` "current" semantics.
126
+ *
127
+ * Replaces the old per-5-min-bucket `utilizationTrend` array: the TUI gauge
128
+ * (the only consumer of `summary.utilization`) reads `.lastUtil5h` /
129
+ * `.lastUtil7d`, which on the array shape were `undefined` → rendered NaN%.
130
+ * See #600.
131
+ */
132
+ private currentUtilization;
122
133
  private predict;
123
134
  }
124
135
  interface PerAccountStat {
@@ -164,12 +175,11 @@ export interface AnalyticsSummary {
164
175
  };
165
176
  perAccount: Record<string, PerAccountStat>;
166
177
  perModel: Record<string, PerModelStat>;
167
- utilization: Array<{
168
- timestamp: number;
169
- avgUtil5h: number;
170
- avgUtil7d: number;
171
- requests: number;
172
- }>;
178
+ /** Current 5h / 7d rate-limit utilization (0–1) as of the last request. */
179
+ utilization: {
180
+ lastUtil5h: number;
181
+ lastUtil7d: number;
182
+ };
173
183
  predictions: {
174
184
  estimatedExhaustionMinutes: number | null;
175
185
  tokenBurnRate: number;
package/dist/analytics.js CHANGED
@@ -175,7 +175,7 @@ export class Analytics extends EventEmitter {
175
175
  },
176
176
  perAccount: this.perAccountStats(recent),
177
177
  perModel: this.perModelStats(recent),
178
- utilization: this.utilizationTrend(recent),
178
+ utilization: this.currentUtilization(recent),
179
179
  predictions: this.predict(recent),
180
180
  };
181
181
  }
@@ -267,29 +267,22 @@ export class Analytics extends EventEmitter {
267
267
  }
268
268
  return result;
269
269
  }
270
- utilizationTrend(records) {
270
+ /**
271
+ * The most recent rate-limit snapshot in the window — current 5h / 7d
272
+ * utilization (0–1) as of the last request. The Analytics tab's rate-limit
273
+ * gauge reads this; an empty window reads 0/0. Mirrors `perAccountStats`'
274
+ * `last.util*` "current" semantics.
275
+ *
276
+ * Replaces the old per-5-min-bucket `utilizationTrend` array: the TUI gauge
277
+ * (the only consumer of `summary.utilization`) reads `.lastUtil5h` /
278
+ * `.lastUtil7d`, which on the array shape were `undefined` → rendered NaN%.
279
+ * See #600.
280
+ */
281
+ currentUtilization(records) {
271
282
  if (records.length === 0)
272
- return [];
273
- const bucketMs = 5 * 60_000;
274
- const buckets = new Map();
275
- for (const r of records) {
276
- const key = Math.floor(r.timestamp / bucketMs) * bucketMs;
277
- const existing = buckets.get(key);
278
- if (existing) {
279
- existing.push(r);
280
- }
281
- else {
282
- buckets.set(key, [r]);
283
- }
284
- }
285
- return [...buckets.entries()]
286
- .sort(([a], [b]) => a - b)
287
- .map(([ts, recs]) => ({
288
- timestamp: ts,
289
- avgUtil5h: Math.round(recs.reduce((s, r) => s + r.util5h, 0) / recs.length * 100) / 100,
290
- avgUtil7d: Math.round(recs.reduce((s, r) => s + r.util7d, 0) / recs.length * 100) / 100,
291
- requests: recs.length,
292
- }));
283
+ return { lastUtil5h: 0, lastUtil7d: 0 };
284
+ const last = records[records.length - 1];
285
+ return { lastUtil5h: last.util5h, lastUtil7d: last.util7d };
293
286
  }
294
287
  predict(records) {
295
288
  if (records.length < 3) {
@@ -78,7 +78,7 @@ export const AnalyticsTab = {
78
78
  lines.push(' ' + renderKvRow('Tokens out', formatNumber(s.window.totalOutputTokens), w - 4));
79
79
  lines.push(' ' + renderKvRow('Thinking tokens', formatNumber(s.window.totalThinkingTokens), w - 4));
80
80
  lines.push(' ' + renderKvRow('Avg latency', `${Math.round(s.window.avgLatencyMs)}ms`, w - 4));
81
- lines.push(' ' + renderKvRow('Subscription %', `${(s.window.subscriptionPercent * 100).toFixed(0)}%`, w - 4));
81
+ lines.push(' ' + renderKvRow('Subscription %', `${s.window.subscriptionPercent.toFixed(0)}%`, w - 4));
82
82
  // ── Per-model bars ─────────────────────────────────────────
83
83
  const models = Object.entries(s.perModel).sort((a, b) => b[1].requests - a[1].requests);
84
84
  if (models.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "4.8.103",
3
+ "version": "4.8.104",
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": {