@bli-cockpit/telemetry-core 0.1.36 → 0.1.37

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.
@@ -108,6 +108,7 @@ export declare const CollectorHeartbeatSchema: z.ZodObject<{
108
108
  hook_via_daemon_24h: z.ZodOptional<z.ZodNumber>;
109
109
  hook_via_direct_24h: z.ZodOptional<z.ZodNumber>;
110
110
  hook_skipped_trivial_24h: z.ZodOptional<z.ZodNumber>;
111
+ hook_billing_exhausted_24h: z.ZodOptional<z.ZodNumber>;
111
112
  hook_stats_reason: z.ZodOptional<z.ZodString>;
112
113
  hook_performance: z.ZodOptional<z.ZodObject<{
113
114
  schema_version: z.ZodLiteral<"memory-hook-performance.v1">;
@@ -48,6 +48,7 @@ export declare const MemoryHookCountsSchema: z.ZodObject<{
48
48
  via_daemon: z.ZodOptional<z.ZodNumber>;
49
49
  via_direct: z.ZodOptional<z.ZodNumber>;
50
50
  skipped_trivial: z.ZodOptional<z.ZodNumber>;
51
+ billing_exhausted: z.ZodOptional<z.ZodNumber>;
51
52
  }, z.core.$strict>;
52
53
  export type MemoryHookCounts = z.infer<typeof MemoryHookCountsSchema>;
53
54
  /** `YYYY-MM-DDTHH` in UTC — the bucket key, and the reason the window is exact. */
@@ -68,6 +69,7 @@ export declare const MemoryHookStatsFileSchema: z.ZodObject<{
68
69
  via_daemon: z.ZodOptional<z.ZodNumber>;
69
70
  via_direct: z.ZodOptional<z.ZodNumber>;
70
71
  skipped_trivial: z.ZodOptional<z.ZodNumber>;
72
+ billing_exhausted: z.ZodOptional<z.ZodNumber>;
71
73
  }, z.core.$strict>>>;
72
74
  }, z.core.$strict>;
73
75
  export type MemoryHookStatsFile = z.infer<typeof MemoryHookStatsFileSchema>;
@@ -92,6 +94,13 @@ export interface MemoryHookWindow {
92
94
  viaMeasured: boolean;
93
95
  /** Trivial prompts the hook declined to search for (BLI-3881). A subset of skips. */
94
96
  skippedTrivial: number;
97
+ /**
98
+ * BLI-3891: runs the provider refused because the account has no credit. A
99
+ * subset of `failed`, summed only over buckets that carry the field, so a
100
+ * window spanning an upgrade reports what was measured rather than crediting
101
+ * older runs to zero.
102
+ */
103
+ billingExhausted: number;
95
104
  /** Buckets that were inside the window and had something in them. */
96
105
  hours: number;
97
106
  }
@@ -76,6 +76,23 @@ export const MemoryHookCountsSchema = z
76
76
  * failed + skipped` still holds.
77
77
  */
78
78
  skipped_trivial: z.number().int().min(0).optional(),
79
+ /**
80
+ * BLI-3891 — the SUBSET of `failed` that was the ACCOUNT, not the code.
81
+ *
82
+ * The provider refused the embedding because there is no credit left
83
+ * (`provider_billing_exhausted`). On 2026-09-06 that state made every
84
+ * recall on every machine miss its deadline and print nothing, and the
85
+ * only number anywhere would have said "timeouts", which sends a person
86
+ * to re-fit a budget rather than to a billing page.
87
+ *
88
+ * Counted BESIDE `failed`, never instead of it, so
89
+ * `runs = printed + empty + timeouts + failed + skipped` still holds, and
90
+ * OPTIONAL for the same reason `skipped_trivial` is: a file written by an
91
+ * older memory-mcp has no such key, this schema is strict, and a required
92
+ * field would make every existing machine's history
93
+ * `hook_stats_unrecognised_shape` overnight.
94
+ */
95
+ billing_exhausted: z.number().int().min(0).optional(),
79
96
  })
80
97
  .strict();
81
98
  /** `YYYY-MM-DDTHH` in UTC — the bucket key, and the reason the window is exact. */
@@ -99,7 +116,16 @@ export function memoryHookHourBucket(at) {
99
116
  return at.toISOString().slice(0, 13);
100
117
  }
101
118
  export function emptyMemoryHookCounts() {
102
- return { runs: 0, printed: 0, empty: 0, timeouts: 0, failed: 0, skipped: 0, skipped_trivial: 0 };
119
+ return {
120
+ runs: 0,
121
+ printed: 0,
122
+ empty: 0,
123
+ timeouts: 0,
124
+ failed: 0,
125
+ skipped: 0,
126
+ skipped_trivial: 0,
127
+ billing_exhausted: 0,
128
+ };
103
129
  }
104
130
  /**
105
131
  * Sum one event's buckets over the last `hours` hours, ending at `now`.
@@ -122,6 +148,7 @@ export function summariseMemoryHookWindow(file, event, options) {
122
148
  viaDirect: 0,
123
149
  viaMeasured: false,
124
150
  skippedTrivial: 0,
151
+ billingExhausted: 0,
125
152
  hours: 0,
126
153
  };
127
154
  for (const [bucket, events] of Object.entries(file.buckets)) {
@@ -144,6 +171,10 @@ export function summariseMemoryHookWindow(file, event, options) {
144
171
  // Absent means an older writer never counted one, which sums as zero and
145
172
  // is honest: that machine genuinely skipped none, because it could not.
146
173
  total.skippedTrivial += counts.skipped_trivial ?? 0;
174
+ // Same rule (BLI-3891): absent means an older writer never counted one,
175
+ // which sums as zero and is honest — that machine genuinely had none it
176
+ // could name.
177
+ total.billingExhausted += counts.billing_exhausted ?? 0;
147
178
  total.hours += 1;
148
179
  }
149
180
  return total;
@@ -116,6 +116,7 @@ export declare const MemoryInstallReceiptSchema: z.ZodObject<{
116
116
  hook_via_daemon_24h: z.ZodOptional<z.ZodNumber>;
117
117
  hook_via_direct_24h: z.ZodOptional<z.ZodNumber>;
118
118
  hook_skipped_trivial_24h: z.ZodOptional<z.ZodNumber>;
119
+ hook_billing_exhausted_24h: z.ZodOptional<z.ZodNumber>;
119
120
  hook_stats_reason: z.ZodOptional<z.ZodString>;
120
121
  hook_performance: z.ZodOptional<z.ZodObject<{
121
122
  schema_version: z.ZodLiteral<"memory-hook-performance.v1">;
@@ -154,6 +154,15 @@ export const MemoryInstallReceiptSchema = z
154
154
  * none.
155
155
  */
156
156
  hook_skipped_trivial_24h: z.number().int().min(0).optional(),
157
+ /**
158
+ * BLI-3891: runs whose recall failed because the PROVIDER ACCOUNT has no
159
+ * credit. A subset of `hook_failed_24h`, and the reason it is on the
160
+ * receipt at all: on 2026-09-06 every machine's recall died for four hours
161
+ * and the only word any surface had for it was "missed the deadline",
162
+ * which sends a person to re-fit a budget instead of to a billing page.
163
+ * Optional like the counts above — absent reads as "not reported".
164
+ */
165
+ hook_billing_exhausted_24h: z.number().int().min(0).optional(),
157
166
  /** Named when the counts are absent because the file could not be read. */
158
167
  hook_stats_reason: ReasonLabelSchema.optional(),
159
168
  /** Observed ordinary invocations, not legacy floors or a full host trace. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/telemetry-core",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",