@openlimiter/connectors 0.2.0 → 1.2.0
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/dist/antigravity.d.ts +50 -1
- package/dist/antigravity.d.ts.map +1 -1
- package/dist/antigravity.js +150 -19
- package/dist/antigravity.js.map +1 -1
- package/dist/claude.d.ts +72 -6
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +467 -35
- package/dist/claude.js.map +1 -1
- package/dist/codex.d.ts +23 -1
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +112 -13
- package/dist/codex.js.map +1 -1
- package/dist/contract-gate.d.ts +56 -0
- package/dist/contract-gate.d.ts.map +1 -0
- package/dist/contract-gate.js +100 -0
- package/dist/contract-gate.js.map +1 -0
- package/dist/fixtures.d.ts +274 -2
- package/dist/fixtures.d.ts.map +1 -1
- package/dist/fixtures.js +947 -17
- package/dist/fixtures.js.map +1 -1
- package/dist/gemini-cli.d.ts +13 -0
- package/dist/gemini-cli.d.ts.map +1 -0
- package/dist/gemini-cli.js +86 -0
- package/dist/gemini-cli.js.map +1 -0
- package/dist/grok.d.ts +13 -0
- package/dist/grok.d.ts.map +1 -0
- package/dist/grok.js +143 -0
- package/dist/grok.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/kimi.d.ts +13 -0
- package/dist/kimi.d.ts.map +1 -0
- package/dist/kimi.js +141 -0
- package/dist/kimi.js.map +1 -0
- package/dist/manual.d.ts +3 -1
- package/dist/manual.d.ts.map +1 -1
- package/dist/manual.js +7 -3
- package/dist/manual.js.map +1 -1
- package/dist/opencode.d.ts +103 -1
- package/dist/opencode.d.ts.map +1 -1
- package/dist/opencode.js +428 -21
- package/dist/opencode.js.map +1 -1
- package/dist/openrouter.d.ts +3 -1
- package/dist/openrouter.d.ts.map +1 -1
- package/dist/openrouter.js +7 -3
- package/dist/openrouter.js.map +1 -1
- package/dist/shared.d.ts +105 -1
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +190 -0
- package/dist/shared.js.map +1 -1
- package/package.json +4 -3
package/dist/antigravity.d.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import type { ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
1
|
+
import type { ConnectionTool, ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
2
|
+
/**
|
|
3
|
+
* The Antigravity quota reader.
|
|
4
|
+
*
|
|
5
|
+
* The shape below is the one a working reader observed against a real Google AI
|
|
6
|
+
* Pro account on 2026-08-07, recorded in
|
|
7
|
+
* `Product Idea/reference-implementation`. Design evidence, not verification
|
|
8
|
+
* evidence: Google publishes nothing about this surface, so the provider stays
|
|
9
|
+
* UNVERIFIED whatever we observe.
|
|
10
|
+
*
|
|
11
|
+
* The response is not a percentage in a field. It is a list of GROUPS, each
|
|
12
|
+
* holding a list of BUCKETS, each bucket carrying `remainingFraction` between
|
|
13
|
+
* zero and one, a window name, and an RFC3339 reset. Usage is one minus that
|
|
14
|
+
* fraction. The reader used to parse `quota.used_percent`, a shape from an
|
|
15
|
+
* early prototype that has never been seen on the wire.
|
|
16
|
+
*/
|
|
2
17
|
export declare const antigravityLabels: {
|
|
3
18
|
readonly credentialOrigin: "official-local-tool";
|
|
4
19
|
readonly dataInterfaceStatus: "internal-endpoint";
|
|
@@ -10,6 +25,40 @@ export declare const antigravityInput: {
|
|
|
10
25
|
readonly pathTemplate: "{providerState}/quota.json";
|
|
11
26
|
readonly readMode: "read_only";
|
|
12
27
|
};
|
|
28
|
+
/** What this reader reads. JSON, because the endpoint answers JSON. */
|
|
29
|
+
export declare const antigravityEncoding: "json";
|
|
30
|
+
/**
|
|
31
|
+
* The bucket prefix naming the pool this provider tracks.
|
|
32
|
+
*
|
|
33
|
+
* Matched against the prefix of `bucketId` EXACTLY, never as a substring. A
|
|
34
|
+
* hypothetical `3p-gemini-fallback` bucket would satisfy a naive containment
|
|
35
|
+
* test and let a third party pool overwrite the real one, which is a wrong
|
|
36
|
+
* number rather than a missing one.
|
|
37
|
+
*/
|
|
38
|
+
export declare const ANTIGRAVITY_TRACKED_POOL = "gemini";
|
|
39
|
+
/**
|
|
40
|
+
* The window names this build understands, and how long each one is.
|
|
41
|
+
*
|
|
42
|
+
* Google spells them "5h" and "weekly". A window name outside this table is not
|
|
43
|
+
* dropped: the whole payload is refused. Dropping it would remove a window that
|
|
44
|
+
* might be the binding one and leave the meter confidently reporting a LOWER
|
|
45
|
+
* number than the truth, which is the exact failure this product exists to
|
|
46
|
+
* prevent.
|
|
47
|
+
*/
|
|
48
|
+
export declare const ANTIGRAVITY_WINDOWS: Readonly<Record<string, number>>;
|
|
49
|
+
/**
|
|
50
|
+
* Every documented window in the tracked pool, as its own meter.
|
|
51
|
+
*
|
|
52
|
+
* The shell may still derive one binding percentage for advice and the tray,
|
|
53
|
+
* but the dashboard must not discard the other window to get there.
|
|
54
|
+
*
|
|
55
|
+
* The third party pool that rides the same subscription is deliberately not
|
|
56
|
+
* modelled. It is a real second wallet, and reporting it under this provider's
|
|
57
|
+
* single meter would conflate two pools into one number. It needs its own
|
|
58
|
+
* identity in the registry before it can have one here.
|
|
59
|
+
*/
|
|
13
60
|
export declare function parseAntigravityPayload(payload: unknown, now: string): RawMeter[] | null;
|
|
61
|
+
/** The local application that owns this credential. */
|
|
62
|
+
export declare const ANTIGRAVITY_TOOL: ConnectionTool;
|
|
14
63
|
export declare const antigravityConnector: ConnectorContract;
|
|
15
64
|
//# sourceMappingURL=antigravity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"antigravity.d.ts","sourceRoot":"","sources":["../src/antigravity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAGjB,QAAQ,EACT,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"antigravity.d.ts","sourceRoot":"","sources":["../src/antigravity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAGjB,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAW3B;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,iBAAiB;;;;;CAKM,CAAC;AAErC,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,EAAG,MAAe,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,WAAW,CAAC;AAEjD;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGhE,CAAC;AA6DF;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,QAAQ,EAAE,GAAG,IAAI,CAkCnB;AAED,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,EAAE,cAA8B,CAAC;AAE9D,eAAO,MAAM,oBAAoB,EAAE,iBAmBlC,CAAC"}
|
package/dist/antigravity.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { boundedFraction, connectorConnection, futureInstantFromRfc3339, plausibleResetHorizon, rawMeter, record, shortExpiry } from "./shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* The Antigravity quota reader.
|
|
4
|
+
*
|
|
5
|
+
* The shape below is the one a working reader observed against a real Google AI
|
|
6
|
+
* Pro account on 2026-08-07, recorded in
|
|
7
|
+
* `Product Idea/reference-implementation`. Design evidence, not verification
|
|
8
|
+
* evidence: Google publishes nothing about this surface, so the provider stays
|
|
9
|
+
* UNVERIFIED whatever we observe.
|
|
10
|
+
*
|
|
11
|
+
* The response is not a percentage in a field. It is a list of GROUPS, each
|
|
12
|
+
* holding a list of BUCKETS, each bucket carrying `remainingFraction` between
|
|
13
|
+
* zero and one, a window name, and an RFC3339 reset. Usage is one minus that
|
|
14
|
+
* fraction. The reader used to parse `quota.used_percent`, a shape from an
|
|
15
|
+
* early prototype that has never been seen on the wire.
|
|
16
|
+
*/
|
|
2
17
|
export const antigravityLabels = {
|
|
3
18
|
credentialOrigin: "official-local-tool",
|
|
4
19
|
dataInterfaceStatus: "internal-endpoint",
|
|
@@ -10,39 +25,155 @@ export const antigravityInput = {
|
|
|
10
25
|
pathTemplate: "{providerState}/quota.json",
|
|
11
26
|
readMode: "read_only"
|
|
12
27
|
};
|
|
28
|
+
/** What this reader reads. JSON, because the endpoint answers JSON. */
|
|
29
|
+
export const antigravityEncoding = "json";
|
|
30
|
+
/**
|
|
31
|
+
* The bucket prefix naming the pool this provider tracks.
|
|
32
|
+
*
|
|
33
|
+
* Matched against the prefix of `bucketId` EXACTLY, never as a substring. A
|
|
34
|
+
* hypothetical `3p-gemini-fallback` bucket would satisfy a naive containment
|
|
35
|
+
* test and let a third party pool overwrite the real one, which is a wrong
|
|
36
|
+
* number rather than a missing one.
|
|
37
|
+
*/
|
|
38
|
+
export const ANTIGRAVITY_TRACKED_POOL = "gemini";
|
|
39
|
+
/**
|
|
40
|
+
* The window names this build understands, and how long each one is.
|
|
41
|
+
*
|
|
42
|
+
* Google spells them "5h" and "weekly". A window name outside this table is not
|
|
43
|
+
* dropped: the whole payload is refused. Dropping it would remove a window that
|
|
44
|
+
* might be the binding one and leave the meter confidently reporting a LOWER
|
|
45
|
+
* number than the truth, which is the exact failure this product exists to
|
|
46
|
+
* prevent.
|
|
47
|
+
*/
|
|
48
|
+
export const ANTIGRAVITY_WINDOWS = {
|
|
49
|
+
"5h": 18_000,
|
|
50
|
+
weekly: 604_800
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Every bucket of one group, or null if any one of them cannot be believed.
|
|
54
|
+
*
|
|
55
|
+
* Whole rather than per bucket, for the reason above: a partially read group is
|
|
56
|
+
* a group whose worst window may be the one that failed to read.
|
|
57
|
+
*/
|
|
58
|
+
function readBuckets(buckets, now) {
|
|
59
|
+
const windows = [];
|
|
60
|
+
for (const entry of buckets) {
|
|
61
|
+
const bucket = record(entry);
|
|
62
|
+
if (bucket === null)
|
|
63
|
+
return null;
|
|
64
|
+
const fraction = boundedFraction(bucket["remainingFraction"]);
|
|
65
|
+
if (fraction === null)
|
|
66
|
+
return null;
|
|
67
|
+
const name = bucket["window"];
|
|
68
|
+
if (typeof name !== "string")
|
|
69
|
+
return null;
|
|
70
|
+
const seconds = ANTIGRAVITY_WINDOWS[name.toLowerCase()];
|
|
71
|
+
if (seconds === undefined)
|
|
72
|
+
return null;
|
|
73
|
+
const resetAt = futureInstantFromRfc3339(bucket["resetTime"], now, plausibleResetHorizon(seconds));
|
|
74
|
+
if (resetAt === null)
|
|
75
|
+
return null;
|
|
76
|
+
/* One decimal, which is the precision the reference reader keeps and more
|
|
77
|
+
than a quota bar can show. Clamped, because floating point subtraction
|
|
78
|
+
of a fraction can land a hair outside the range. */
|
|
79
|
+
const percent = Math.round(Math.max(0, Math.min(100, (1 - fraction) * 100)) * 10) / 10;
|
|
80
|
+
windows.push({
|
|
81
|
+
meter: name.toLowerCase() === "5h" ? "FIVE_HOUR" : "SEVEN_DAY",
|
|
82
|
+
percent,
|
|
83
|
+
seconds,
|
|
84
|
+
resetAt
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return windows.length === 0 ? null : windows;
|
|
88
|
+
}
|
|
89
|
+
/** The prefix of every bucket id in a group, or null if any is unreadable. */
|
|
90
|
+
function poolPrefixes(buckets) {
|
|
91
|
+
const prefixes = new Set();
|
|
92
|
+
for (const entry of buckets) {
|
|
93
|
+
const bucket = record(entry);
|
|
94
|
+
if (bucket === null)
|
|
95
|
+
return null;
|
|
96
|
+
const id = bucket["bucketId"];
|
|
97
|
+
if (typeof id !== "string")
|
|
98
|
+
return null;
|
|
99
|
+
const separator = id.indexOf("-");
|
|
100
|
+
if (separator <= 0)
|
|
101
|
+
return null;
|
|
102
|
+
prefixes.add(id.slice(0, separator));
|
|
103
|
+
}
|
|
104
|
+
return prefixes;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Every documented window in the tracked pool, as its own meter.
|
|
108
|
+
*
|
|
109
|
+
* The shell may still derive one binding percentage for advice and the tray,
|
|
110
|
+
* but the dashboard must not discard the other window to get there.
|
|
111
|
+
*
|
|
112
|
+
* The third party pool that rides the same subscription is deliberately not
|
|
113
|
+
* modelled. It is a real second wallet, and reporting it under this provider's
|
|
114
|
+
* single meter would conflate two pools into one number. It needs its own
|
|
115
|
+
* identity in the registry before it can have one here.
|
|
116
|
+
*/
|
|
13
117
|
export function parseAntigravityPayload(payload, now) {
|
|
14
118
|
const root = record(payload);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
119
|
+
const groups = root?.["groups"];
|
|
120
|
+
if (!Array.isArray(groups))
|
|
121
|
+
return null;
|
|
122
|
+
let tracked = null;
|
|
123
|
+
for (const entry of groups) {
|
|
124
|
+
const group = record(entry);
|
|
125
|
+
if (group === null)
|
|
126
|
+
return null;
|
|
127
|
+
const buckets = group["buckets"];
|
|
128
|
+
if (!Array.isArray(buckets))
|
|
129
|
+
return null;
|
|
130
|
+
const prefixes = poolPrefixes(buckets);
|
|
131
|
+
if (prefixes === null)
|
|
132
|
+
return null;
|
|
133
|
+
if (!prefixes.has(ANTIGRAVITY_TRACKED_POOL))
|
|
134
|
+
continue;
|
|
135
|
+
/* Two groups claiming the same pool is ambiguous, and picking one would be
|
|
136
|
+
picking at random. */
|
|
137
|
+
if (tracked !== null)
|
|
138
|
+
return null;
|
|
139
|
+
tracked = readBuckets(buckets, now);
|
|
140
|
+
if (tracked === null)
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
if (tracked === null)
|
|
144
|
+
return null;
|
|
18
145
|
const expiresAt = shortExpiry(now);
|
|
19
|
-
if (
|
|
146
|
+
if (expiresAt === null)
|
|
20
147
|
return null;
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
148
|
+
return tracked.map((candidate) => rawMeter({
|
|
149
|
+
provider: "ANTIGRAVITY",
|
|
150
|
+
meter: candidate.meter,
|
|
151
|
+
value: candidate.percent,
|
|
152
|
+
window: { kind: "rolling", durationSeconds: candidate.seconds },
|
|
153
|
+
resetAt: candidate.resetAt,
|
|
154
|
+
source: "internal_payload",
|
|
155
|
+
precision: "estimated",
|
|
156
|
+
observedAt: now,
|
|
157
|
+
expiresAt,
|
|
158
|
+
labels: antigravityLabels
|
|
159
|
+
}));
|
|
33
160
|
}
|
|
161
|
+
/** The local application that owns this credential. */
|
|
162
|
+
export const ANTIGRAVITY_TOOL = "Antigravity";
|
|
34
163
|
export const antigravityConnector = {
|
|
35
164
|
id: "antigravity",
|
|
36
165
|
displayName: "Antigravity",
|
|
166
|
+
encoding: "json",
|
|
37
167
|
labels: antigravityLabels,
|
|
38
168
|
detect(environment) {
|
|
39
169
|
return environment["ANTIGRAVITY_USAGE_PAYLOAD"] === "1";
|
|
40
170
|
},
|
|
41
171
|
async read(context) {
|
|
42
172
|
const meters = parseAntigravityPayload(context.payload, context.now);
|
|
173
|
+
const connection = connectorConnection(meters !== null, context.payload, ANTIGRAVITY_TOOL);
|
|
43
174
|
return meters === null
|
|
44
|
-
? { ok: false, reason: "unknown" }
|
|
45
|
-
: { ok: true, meters };
|
|
175
|
+
? { ok: false, reason: "unknown", connection }
|
|
176
|
+
: { ok: true, meters, connection };
|
|
46
177
|
}
|
|
47
178
|
};
|
|
48
179
|
//# sourceMappingURL=antigravity.js.map
|
package/dist/antigravity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../src/antigravity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../src/antigravity.ts"],"names":[],"mappings":"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"}
|
package/dist/claude.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
1
|
+
import type { ConnectionTool, ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
2
2
|
export declare const claudeLabels: {
|
|
3
3
|
readonly credentialOrigin: "official-local-tool";
|
|
4
4
|
readonly dataInterfaceStatus: "native-statusline-payload";
|
|
@@ -11,14 +11,80 @@ export declare const claudeInput: {
|
|
|
11
11
|
readonly readMode: "read_only";
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* The longest a window this reader was never told the length of may run.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* A bucket whose key spells out no cadence still needs SOME plausibility bound,
|
|
17
|
+
* or a corrupt reset becomes a countdown to the year 2038. A month is the
|
|
18
|
+
* longest subscription window any provider in this product uses, so a reset
|
|
19
|
+
* beyond it is a corrupt field rather than a long wait.
|
|
20
|
+
*/
|
|
21
|
+
export declare const CLAUDE_UNKNOWN_WINDOW_SECONDS = 2678400;
|
|
22
|
+
/** The prefix every model scoped weekly bucket's code is built on. */
|
|
23
|
+
export declare const CLAUDE_MODEL_WEEKLY_PREFIX = "SEVEN_DAY_";
|
|
24
|
+
/** Longest source string this reader will turn into a meter code. */
|
|
25
|
+
export declare const MAX_METER_CODE_SOURCE_CHARS = 64;
|
|
26
|
+
/**
|
|
27
|
+
* Parse a Claude usage document, in either shape the same credential produces.
|
|
28
|
+
*
|
|
29
|
+
* SHAPE ONE, the statusline payload, from
|
|
30
|
+
* https://code.claude.com/docs/en/statusline and observed on Claude Code
|
|
31
|
+
* 2.1.261 on 2026-09-04:
|
|
32
|
+
*
|
|
33
|
+
* ```json
|
|
34
|
+
* {
|
|
35
|
+
* "rate_limits": {
|
|
36
|
+
* "five_hour": { "used_percentage": 23.5, "resets_at": 1738425600 },
|
|
37
|
+
* "seven_day": { "used_percentage": 41.2, "resets_at": 1738857600 },
|
|
38
|
+
* "seven_day_oauth_apps": { "used_percentage": 3.1, "resets_at": 1738857600 },
|
|
39
|
+
* "seven_day_opus": { "used_percentage": 61.0, "resets_at": 1738857600 },
|
|
40
|
+
* "seven_day_sonnet": { "used_percentage": 12.4, "resets_at": 1738857600 },
|
|
41
|
+
* "model_scoped": [
|
|
42
|
+
* { "display_name": "Fable 5", "utilization": 12, "resets_at": "2026-09-11T00:00:00Z" }
|
|
43
|
+
* ]
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* SHAPE TWO, the `api/oauth/usage` document, which is what `openlimiter ingest`
|
|
49
|
+
* is handed. Its windows sit at the root, state `utilization` and an ISO reset,
|
|
50
|
+
* and it carries two things the statusline does not: an `extra_usage` pool
|
|
51
|
+
* stated in money, and a `limits` list of model scoped weekly buckets:
|
|
52
|
+
*
|
|
53
|
+
* ```json
|
|
54
|
+
* {
|
|
55
|
+
* "five_hour": { "utilization": 90, "resets_at": "2026-09-04T17:00:00Z" },
|
|
56
|
+
* "seven_day": { "utilization": 18, "resets_at": "2026-09-09T00:00:00Z" },
|
|
57
|
+
* "extra_usage": { "used_amount": 12.47, "limit_amount": 20, "currency": "USD" },
|
|
58
|
+
* "limits": [
|
|
59
|
+
* {
|
|
60
|
+
* "kind": "weekly_scoped",
|
|
61
|
+
* "percent": 61,
|
|
62
|
+
* "resets_at": "2026-09-09T00:00:00Z",
|
|
63
|
+
* "scope": { "model": { "display_name": "Opus" } }
|
|
64
|
+
* }
|
|
65
|
+
* ]
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* Refusing the second shape was finding F-201: a real document, from a real
|
|
70
|
+
* account, over a healthy connection, answered null because this parser knew
|
|
71
|
+
* only `used_percentage` and only epoch seconds.
|
|
72
|
+
*
|
|
73
|
+
* Three absences the documentation states, and none of them is an error:
|
|
74
|
+
*
|
|
75
|
+
* 1. `rate_limits` appears only for Claude.ai subscribers on Pro or Max, and
|
|
76
|
+
* only after the first API response in the session. A payload without it and
|
|
77
|
+
* without any usage document field is an ordinary payload from a free
|
|
78
|
+
* account or a session that has not called the API yet.
|
|
79
|
+
* 2. Each bucket may be independently absent, so one present bucket is one
|
|
80
|
+
* meter and is a complete answer.
|
|
81
|
+
* 3. No bucket present is the honest unknown, not zero.
|
|
18
82
|
*
|
|
19
|
-
* A
|
|
20
|
-
*
|
|
83
|
+
* A bucket that fails validation is dropped and the rest still count, because
|
|
84
|
+
* one corrupt reset is not a reason to forget the whole session.
|
|
21
85
|
*/
|
|
22
86
|
export declare function parseClaudePayload(payload: unknown, now: string): RawMeter[] | null;
|
|
87
|
+
/** The local application that owns this credential. */
|
|
88
|
+
export declare const CLAUDE_TOOL: ConnectionTool;
|
|
23
89
|
export declare const claudeConnector: ConnectorContract;
|
|
24
90
|
//# sourceMappingURL=claude.d.ts.map
|
package/dist/claude.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAGjB,QAAQ,EAIT,MAAM,mBAAmB,CAAC;AAY3B,eAAO,MAAM,YAAY;;;;;CAKW,CAAC;AAErC,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAKX;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,UAAY,CAAC;AAgCvD,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAiY9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI,CAmCnF;AAED,uDAAuD;AACvD,eAAO,MAAM,WAAW,EAAE,cAA8B,CAAC;AAEzD,eAAO,MAAM,eAAe,EAAE,iBAmB7B,CAAC"}
|