@indigoai-us/hq-cli 5.345.127 → 5.345.129
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.
- package/CHANGELOG.md +47 -0
- package/assets/scaffold/core/scripts/handoff-knowledge-commit.sh +123 -0
- package/assets/scaffold/core/scripts/hq-detach.sh +169 -0
- package/dist/command-catalog.generated.d.ts +40 -2
- package/dist/command-catalog.generated.js +48 -2
- package/dist/commands/auth.js +19 -2
- package/dist/commands/core-bucket-c-handoff-knowledge-fast.d.ts +2 -0
- package/dist/commands/core-bucket-c-handoff-knowledge-fast.js +10 -0
- package/dist/commands/core-bucket-c-handoff-knowledge-native.d.ts +46 -0
- package/dist/commands/core-bucket-c-handoff-knowledge-native.js +284 -0
- package/dist/commands/core-bucket-c-hq-detach-fast.d.ts +2 -0
- package/dist/commands/core-bucket-c-hq-detach-fast.js +10 -0
- package/dist/commands/core-bucket-c-hq-detach-native.d.ts +43 -0
- package/dist/commands/core-bucket-c-hq-detach-native.js +241 -0
- package/dist/commands/core-bucket-c-work-mesh-offer-native.js +8 -2
- package/dist/commands/core.js +12 -0
- package/dist/commands/daemon.js +2 -0
- package/dist/commands/lanes-accounts.js +3 -1
- package/dist/commands/lanes-shared.d.ts +7 -0
- package/dist/commands/lanes.js +139 -17
- package/dist/commands/mesh.js +32 -19
- package/dist/commands/skill.js +9 -4
- package/dist/fast-scaffold.js +28 -0
- package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +3 -5
- package/dist/lib/bot/inbox-poll-backoff-flag.js +20 -12
- package/dist/lib/bot/inbox-wake.d.ts +18 -0
- package/dist/lib/bot/inbox-wake.js +125 -0
- package/dist/lib/bot/run.d.ts +8 -0
- package/dist/lib/bot/run.js +51 -7
- package/dist/lib/bot/runtime/messages-stream.js +31 -3
- package/dist/lib/capacity/lane-login.js +1 -0
- package/dist/lib/daemon/catalog.d.ts +4 -0
- package/dist/lib/daemon/catalog.js +6 -3
- package/dist/lib/daemon/flag-monitor.d.ts +4 -1
- package/dist/lib/daemon/flag-monitor.js +12 -6
- package/dist/lib/daemon/flag.d.ts +2 -0
- package/dist/lib/daemon/flag.js +11 -5
- package/dist/lib/daemon/hq-child-bootstrap.mjs +47 -7
- package/dist/lib/daemon/kill-switch-flags.d.ts +5 -0
- package/dist/lib/daemon/kill-switch-flags.js +5 -0
- package/dist/lib/daemon/lanes-reconcile-loader.d.ts +7 -0
- package/dist/lib/daemon/lanes-reconcile-loader.js +24 -0
- package/dist/lib/daemon/lanes-reconcile-watcher.d.ts +17 -0
- package/dist/lib/daemon/lanes-reconcile-watcher.js +80 -0
- package/dist/lib/daemon/remote-control.d.ts +8 -5
- package/dist/lib/daemon/remote-control.js +8 -7
- package/dist/lib/daemon/run.d.ts +4 -1
- package/dist/lib/daemon/run.js +133 -20
- package/dist/lib/doctor/json-output.d.ts +15 -3
- package/dist/lib/doctor/json-output.js +13 -1
- package/dist/lib/lanes/accounts.js +2 -2
- package/dist/lib/lanes/daemon-reconcile.d.ts +3 -0
- package/dist/lib/lanes/daemon-reconcile.js +8 -0
- package/dist/lib/lanes/host-capacity.d.ts +4 -0
- package/dist/lib/lanes/host-capacity.js +10 -1
- package/dist/lib/lanes/index.d.ts +2 -2
- package/dist/lib/lanes/index.js +1 -1
- package/dist/lib/lanes/loop.d.ts +8 -0
- package/dist/lib/lanes/loop.js +35 -0
- package/dist/lib/lanes/quota-notice.d.ts +11 -11
- package/dist/lib/lanes/quota-notice.js +20 -29
- package/dist/lib/lanes/quota.d.ts +69 -50
- package/dist/lib/lanes/quota.js +146 -127
- package/dist/lib/lanes/reconcile-result.d.ts +10 -0
- package/dist/lib/lanes/reconcile-result.js +11 -0
- package/dist/lib/lanes/reconcile.d.ts +14 -0
- package/dist/lib/lanes/reconcile.js +77 -23
- package/dist/lib/lanes/watcher.d.ts +8 -0
- package/dist/lib/lanes/watcher.js +62 -20
- package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +1 -1
- package/dist/lib/mesh/live/daemon/work-subscribe.js +8 -1
- package/dist/lib/mesh/live/paths.d.ts +2 -0
- package/dist/lib/mesh/live/paths.js +2 -0
- package/dist/lib/mesh/story-status.d.ts +2 -2
- package/dist/lib/mesh/story-status.js +2 -1
- package/dist/utils/resident-package-preload.js +18 -4
- package/package.json +1 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tell a lane's senior
|
|
2
|
+
* Tell a lane's senior that a provider usage limit ended that lane.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* A 429 never holds the account (owner decision 2026-10-14): the lane that
|
|
5
|
+
* hit it ends resumable and the senior decides. One message per lane exit,
|
|
6
|
+
* keyed by lane id and record version, so a re-read of the same exit or a
|
|
7
|
+
* retried append does not send it twice.
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
10
|
-
import { type
|
|
11
|
-
export interface
|
|
9
|
+
import type { QuotaSignal } from "./quota.js";
|
|
10
|
+
import { type LaneRecord } from "./types.js";
|
|
11
|
+
export interface QuotaNotice {
|
|
12
12
|
message_id: string;
|
|
13
13
|
text: string;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
16
|
-
export declare function
|
|
15
|
+
/** The notice for a lane that ended on a usage limit or a needs-credits refusal. */
|
|
16
|
+
export declare function quotaLaneNotice(lane: Pick<LaneRecord, "lane_id" | "version" | "provider" | "account" | "model" | "state" | "terminal_reason" | "quota_reset_at">, quota: QuotaSignal | null): QuotaNotice;
|
|
17
17
|
/**
|
|
18
18
|
* Deliver the notice to the lane's senior inbox. A session senior gets it in
|
|
19
19
|
* its monitor-session inbox, a lane senior in that lane's dropbox. The notice
|
|
20
20
|
* is always written to stderr as well, so a senior with no inbox still has it
|
|
21
21
|
* in the watcher log. Returns where it was delivered.
|
|
22
22
|
*/
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function deliverQuotaNotice(hqRoot: string, lane: Pick<LaneRecord, "lane_id" | "senior">, notice: QuotaNotice, at: string): "session_inbox" | "lane_inbox" | "stderr_only";
|
|
24
24
|
//# sourceMappingURL=quota-notice.d.ts.map
|
|
@@ -1,39 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tell a lane's senior
|
|
2
|
+
* Tell a lane's senior that a provider usage limit ended that lane.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* A 429 never holds the account (owner decision 2026-10-14): the lane that
|
|
5
|
+
* hit it ends resumable and the senior decides. One message per lane exit,
|
|
6
|
+
* keyed by lane id and record version, so a re-read of the same exit or a
|
|
7
|
+
* retried append does not send it twice.
|
|
8
8
|
*/
|
|
9
9
|
import * as fs from "node:fs";
|
|
10
10
|
import * as path from "node:path";
|
|
11
11
|
import { monitorSessionDir } from "../monitor.js";
|
|
12
12
|
import { appendDropboxMessageOnce, appendDropboxMessageOnceAtPath } from "./dropbox.js";
|
|
13
13
|
import { LANE_PROVIDERS } from "./types.js";
|
|
14
|
-
/**
|
|
15
|
-
export function
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const said = account.provider_text ? `Provider said: "${account.provider_text}".` : "Provider gave no message text.";
|
|
21
|
-
const clear = `If the account is not actually exhausted (check /usage), clear the hold with: hq lanes accounts clear-quota ${provider} ${accountId}`;
|
|
14
|
+
/** The notice for a lane that ended on a usage limit or a needs-credits refusal. */
|
|
15
|
+
export function quotaLaneNotice(lane, quota) {
|
|
16
|
+
const providerReset = quota?.provider_reset_at ?? quota?.quota_reset_at ?? lane.quota_reset_at;
|
|
17
|
+
const what = lane.terminal_reason === "account_model_unavailable"
|
|
18
|
+
? `cannot run model ${lane.model ?? "(unknown)"}${quota?.marker ? ` (${quota.marker})` : ""}`
|
|
19
|
+
: "hit the provider usage limit";
|
|
22
20
|
const lines = [
|
|
23
|
-
`
|
|
24
|
-
|
|
21
|
+
`Lane ${lane.lane_id} ${what} on ${lane.provider} account ${lane.account ?? "(none)"} and stopped as ${lane.state}.`,
|
|
22
|
+
providerReset ? `The provider says the limit resets at ${providerReset}.` : "The provider did not name a reset time.",
|
|
25
23
|
];
|
|
26
|
-
if (
|
|
27
|
-
lines.push(`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
lines.push("The provider named no reset time, so this is the default hold.");
|
|
31
|
-
}
|
|
32
|
-
lines.push(clear);
|
|
33
|
-
return {
|
|
34
|
-
message_id: `quota-hold:${provider}:${accountId}:${holdUntil}`,
|
|
35
|
-
text: lines.join("\n"),
|
|
36
|
-
};
|
|
24
|
+
if (quota?.provider_text)
|
|
25
|
+
lines.push(`Provider said: "${quota.provider_text}".`);
|
|
26
|
+
lines.push("No account hold was set; other lanes keep using this account.", `To continue this lane: hq lanes resume ${lane.lane_id} (pass --account <id> to use another account).`);
|
|
27
|
+
return { message_id: `quota-limit:${lane.lane_id}:${lane.version}`, text: lines.join(" ") };
|
|
37
28
|
}
|
|
38
29
|
/**
|
|
39
30
|
* Deliver the notice to the lane's senior inbox. A session senior gets it in
|
|
@@ -41,9 +32,9 @@ export function quotaHoldNotice(state, provider, accountId, laneId) {
|
|
|
41
32
|
* is always written to stderr as well, so a senior with no inbox still has it
|
|
42
33
|
* in the watcher log. Returns where it was delivered.
|
|
43
34
|
*/
|
|
44
|
-
export function
|
|
45
|
-
process.stderr.write(`hq lanes: ${notice.text
|
|
46
|
-
const message = { at, message_id: notice.message_id, kind: "
|
|
35
|
+
export function deliverQuotaNotice(hqRoot, lane, notice, at) {
|
|
36
|
+
process.stderr.write(`hq lanes: ${notice.text}\n`);
|
|
37
|
+
const message = { at, message_id: notice.message_id, kind: "quota_limit", text: notice.text };
|
|
47
38
|
if (lane.senior.kind === "lane" && lane.senior.id) {
|
|
48
39
|
appendDropboxMessageOnce(hqRoot, lane.senior.id, message);
|
|
49
40
|
return "lane_inbox";
|
|
@@ -17,26 +17,14 @@
|
|
|
17
17
|
* per (account, model), plus an account-wide reset when the text is a
|
|
18
18
|
* usage limit rather than a switch-model refusal.
|
|
19
19
|
*
|
|
20
|
-
* A
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* "You've hit your weekly limit · resets Oct 16 at 1am (America/Denver)"
|
|
26
|
-
* while the owner's /usage showed the week at 43%.)
|
|
20
|
+
* A recorded 429 never holds the account (owner decision 2026-10-14, after
|
|
21
|
+
* the 2026-10-13 incident where one 429 on account a blocked every Claude
|
|
22
|
+
* lane until Friday). The reset times and provider text stay here as
|
|
23
|
+
* information for `hq lanes capacity`, `hq lanes accounts list` and the
|
|
24
|
+
* senior notice; only a needs-credits marker skips an account, for that model.
|
|
27
25
|
*/
|
|
28
26
|
import type { LaneProvider } from "./types.js";
|
|
29
27
|
export declare const QUOTA_STATE_REL: string;
|
|
30
|
-
/**
|
|
31
|
-
* Claude quota holds are off. Removed by owner directive on 2026-10-14: a
|
|
32
|
-
* false weekly-limit 429 held every Claude lane for days while the account
|
|
33
|
-
* still had capacity. A Claude 429 still fails that lane over to another
|
|
34
|
-
* account; it never blocks the account for later lanes, and stored Claude
|
|
35
|
-
* holds are ignored on read. `HQ_LANES_CLAUDE_QUOTA_HOLDS=1` turns the old
|
|
36
|
-
* behavior back on; the test suite sets it to keep the hold machinery covered.
|
|
37
|
-
*/
|
|
38
|
-
export declare const CLAUDE_QUOTA_HOLDS_ENV = "HQ_LANES_CLAUDE_QUOTA_HOLDS";
|
|
39
|
-
export declare function providerHasQuotaHolds(provider: LaneProvider): boolean;
|
|
40
28
|
export declare const QUOTA_SCHEMA_VERSION = "hq-lanes-quota.v1";
|
|
41
29
|
export interface ModelQuota {
|
|
42
30
|
quota_reset_at?: string;
|
|
@@ -46,26 +34,27 @@ export interface ModelQuota {
|
|
|
46
34
|
}
|
|
47
35
|
/**
|
|
48
36
|
* `parsed`: the provider's own reset. `derived`: the default hold for a 429
|
|
49
|
-
* with no parseable reset. `unconfirmed
|
|
50
|
-
* provider reset more than a day away that a second 429 has not confirmed.
|
|
37
|
+
* with no parseable reset. `unconfirmed` is read from older quota files only.
|
|
51
38
|
*/
|
|
52
39
|
export type QuotaResetSource = "parsed" | "derived" | "unconfirmed";
|
|
53
|
-
/** A provider reset further away than this needs a second 429 before it holds. */
|
|
54
|
-
export declare const QUOTA_CONFIRM_HORIZON_MS: number;
|
|
55
40
|
export interface AccountQuota {
|
|
56
41
|
/** Set when the 429 is an account-wide usage limit with a reset time. */
|
|
57
42
|
all_models_quota_reset_at?: string;
|
|
58
43
|
/**
|
|
59
|
-
* Whether `all_models_quota_reset_at`
|
|
60
|
-
*
|
|
44
|
+
* Whether `all_models_quota_reset_at` is the provider's own reset
|
|
45
|
+
* (`parsed`) or a shorter hold HQ chose (`derived`): the configured
|
|
46
|
+
* default hold for a 429 with no reset, or the capped first-strike hold
|
|
47
|
+
* when the provider's reset is further away than that.
|
|
61
48
|
*/
|
|
62
49
|
reset_source?: QuotaResetSource;
|
|
63
50
|
/**
|
|
64
|
-
* The provider's
|
|
65
|
-
*
|
|
51
|
+
* The provider's own reset time from the most recent 429, kept even when
|
|
52
|
+
* the recorded reset is shorter. Information only; nothing gates on it.
|
|
66
53
|
*/
|
|
67
|
-
|
|
68
|
-
/**
|
|
54
|
+
provider_reset_at?: string;
|
|
55
|
+
/** When the most recent account-wide 429 was observed. */
|
|
56
|
+
last_quota_hit_at?: string;
|
|
57
|
+
/** Raw provider text from the most recent account-wide 429. */
|
|
69
58
|
provider_text?: string;
|
|
70
59
|
models: Record<string, ModelQuota>;
|
|
71
60
|
}
|
|
@@ -83,18 +72,36 @@ export interface QuotaSignal {
|
|
|
83
72
|
account_wide?: boolean;
|
|
84
73
|
/** Set by applyDefaultQuotaHold: whether the reset is the provider's or the default hold. */
|
|
85
74
|
reset_source?: QuotaResetSource;
|
|
86
|
-
/** The provider's
|
|
75
|
+
/** The provider's own reset, parsed or structured, before any cap. */
|
|
76
|
+
provider_reset_at?: string;
|
|
77
|
+
/** When the 429 was observed. */
|
|
78
|
+
observed_at?: string;
|
|
79
|
+
/** The provider's raw result text, kept so the senior notice can quote it. */
|
|
87
80
|
provider_text?: string;
|
|
88
81
|
}
|
|
89
82
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
83
|
+
* Decide the hold a 429 records (incident 2026-10-13: one 429 on the wrong
|
|
84
|
+
* subscription held the only Claude account for three days).
|
|
85
|
+
*
|
|
86
|
+
* - A per-model credits refusal is untouched.
|
|
87
|
+
* - A 429 with no reset gets the provider's configured default hold
|
|
88
|
+
* (`quota_default_hold_ms`, fifteen minutes unless set), marked `derived`.
|
|
89
|
+
* - A 429 with a provider reset is capped to the same default hold on its
|
|
90
|
+
* own. The provider reset is kept on the signal as `provider_reset_at`;
|
|
91
|
+
* recordAccountQuota extends the hold to it only when a fresh probe hits a
|
|
92
|
+
* repeat 429 before that reset. A reset nearer than the cap is used as is
|
|
93
|
+
* and marked `parsed`.
|
|
96
94
|
*/
|
|
97
95
|
export declare function applyDefaultQuotaHold(signal: QuotaSignal, defaultHoldMs: number, now: Date): QuotaSignal;
|
|
96
|
+
/**
|
|
97
|
+
* True when the signal is a fresh 429 on an account whose previous 429 named
|
|
98
|
+
* a provider reset that has not arrived yet: the short first-strike hold
|
|
99
|
+
* expired (or was cleared and re-recorded), a new probe ran, and the
|
|
100
|
+
* provider refused again. The provider's reset is then believed.
|
|
101
|
+
*/
|
|
102
|
+
export declare function isRepeatQuotaHit(current: AccountQuota | undefined, signal: QuotaSignal, now: Date): boolean;
|
|
103
|
+
/** "UTC" or an IANA zone the runtime knows, e.g. America/Denver. */
|
|
104
|
+
export declare function isKnownTimeZone(zone: string): boolean;
|
|
98
105
|
export declare function quotaStatePath(hqRoot: string): string;
|
|
99
106
|
export declare function loadQuotaState(hqRoot: string): QuotaState;
|
|
100
107
|
/**
|
|
@@ -112,11 +119,6 @@ export declare function loadQuotaState(hqRoot: string): QuotaState;
|
|
|
112
119
|
* past. An explicit provider year is kept as stated.
|
|
113
120
|
*/
|
|
114
121
|
export declare function parseProviderResetTime(text: string, now: Date): string | null;
|
|
115
|
-
/**
|
|
116
|
-
* Read only `api_error_status`, `is_error`, and `result` off the last
|
|
117
|
-
* `type: "result"` object. Nothing else from the payload is returned, and
|
|
118
|
-
* this function does not log.
|
|
119
|
-
*/
|
|
120
122
|
export interface QuotaResultFields {
|
|
121
123
|
api_error_status: unknown;
|
|
122
124
|
is_error: unknown;
|
|
@@ -129,16 +131,15 @@ export interface QuotaResultFields {
|
|
|
129
131
|
}
|
|
130
132
|
/** Epoch seconds, epoch milliseconds, or an ISO string, to ISO; null otherwise. */
|
|
131
133
|
export declare function normalizeStructuredReset(value: unknown): string | null;
|
|
134
|
+
/**
|
|
135
|
+
* Read only `api_error_status`, `is_error`, `result`, and a structured
|
|
136
|
+
* reset off the last `type: "result"` object. Nothing else from the payload
|
|
137
|
+
* is returned, and this function does not log.
|
|
138
|
+
*/
|
|
132
139
|
export declare function quotaFieldsFromOutput(text: string): QuotaResultFields | null;
|
|
133
140
|
export declare function quotaSignalFromFields(fields: QuotaResultFields, model: string | undefined, now: Date): QuotaSignal | null;
|
|
134
141
|
export declare function readQuotaSignal(runDir: string, model: string | undefined, now: Date, workerOutOffset?: number): QuotaSignal | null;
|
|
135
|
-
export
|
|
136
|
-
/** When the 429 was observed. Enables the far-reset confirmation gate. */
|
|
137
|
-
now: Date;
|
|
138
|
-
/** Hold applied while a far provider reset is unconfirmed (the default hold). */
|
|
139
|
-
unconfirmedHoldMs: number;
|
|
140
|
-
}
|
|
141
|
-
export declare function recordAccountQuota(hqRoot: string, provider: LaneProvider, accountId: string, incoming: QuotaSignal, options?: RecordAccountQuotaOptions): QuotaState;
|
|
142
|
+
export declare function recordAccountQuota(hqRoot: string, provider: LaneProvider, accountId: string, incoming: QuotaSignal, now?: Date): QuotaState;
|
|
142
143
|
export interface ClearedModelQuotaReset {
|
|
143
144
|
model: string;
|
|
144
145
|
quota_reset_at: string;
|
|
@@ -166,13 +167,31 @@ export interface QuotaBlock {
|
|
|
166
167
|
model?: string;
|
|
167
168
|
}
|
|
168
169
|
/**
|
|
169
|
-
* Skip an account only for
|
|
170
|
-
*
|
|
171
|
-
*
|
|
170
|
+
* Skip an account only for a model it cannot run at all: a needs-credits
|
|
171
|
+
* marker blocks that model, with no expiry.
|
|
172
|
+
*
|
|
173
|
+
* A recorded 429 never blocks (owner decision, incident 2026-10-13). The
|
|
174
|
+
* lane that hit it ends resumable and its senior decides; other lanes keep
|
|
175
|
+
* using the account. The reset times stay in quota.json as information
|
|
176
|
+
* (`accountQuotaView`, `quotaHitInfo`).
|
|
172
177
|
*/
|
|
173
|
-
export declare function quotaBlockFor(state: QuotaState, provider: LaneProvider, accountId: string, model: string | undefined,
|
|
178
|
+
export declare function quotaBlockFor(state: QuotaState, provider: LaneProvider, accountId: string, model: string | undefined, _now: Date): QuotaBlock;
|
|
179
|
+
/** The last recorded 429 on an account, for display only. */
|
|
180
|
+
export interface QuotaHitInfo {
|
|
181
|
+
last_quota_hit_at?: string;
|
|
182
|
+
/** The provider's own reset time from the last 429, when it named one. */
|
|
183
|
+
provider_reset_at?: string;
|
|
184
|
+
/** True while the provider's reset is still ahead. Informational; nothing gates on it. */
|
|
185
|
+
provider_reset_pending: boolean;
|
|
186
|
+
}
|
|
187
|
+
export declare function quotaHitInfo(state: QuotaState, provider: LaneProvider, accountId: string, now: Date): QuotaHitInfo | undefined;
|
|
174
188
|
export interface AccountQuotaView {
|
|
175
189
|
quota_reset_at: string | null;
|
|
190
|
+
/** "parsed" when the hold is the provider's reset, "derived" when HQ shortened it. */
|
|
191
|
+
quota_reset_source?: QuotaResetSource;
|
|
192
|
+
/** The provider's own reset from the last 429, when the hold was capped below it. */
|
|
193
|
+
provider_reset_at?: string;
|
|
194
|
+
last_quota_hit_at?: string;
|
|
176
195
|
model_quota: Array<{
|
|
177
196
|
model: string;
|
|
178
197
|
quota_reset_at?: string;
|