agl 40.4.0 → 40.5.1
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 +33 -0
- package/dist_serve/bundle.js +2228 -2177
- package/dist_serve/bundle.js.map +2 -2
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/aglapi/aglapisurface.document.js +2 -2
- package/dist_ts/classes.accountsactions.d.ts +11 -1
- package/dist_ts/classes.accountsactions.js +59 -2
- package/dist_ts/classes.controller.js +5 -5
- package/dist_ts/classes.flexaccountaccess.js +3 -2
- package/dist_ts/classes.harnessreleases.d.ts +14 -4
- package/dist_ts/classes.harnessreleases.js +28 -4
- package/dist_ts/classes.inferencegateway.d.ts +28 -3
- package/dist_ts/classes.inferencegateway.js +177 -61
- package/dist_ts/classes.inferenceplacement.d.ts +5 -3
- package/dist_ts/classes.inferenceplacement.js +2 -2
- package/dist_ts/classes.inferencerouter.d.ts +349 -91
- package/dist_ts/classes.inferencerouter.js +804 -297
- package/dist_ts/classes.inferenceservice.d.ts +14 -2
- package/dist_ts/classes.inferenceservice.js +53 -14
- package/dist_ts/classes.inferencespend.d.ts +339 -0
- package/dist_ts/classes.inferencespend.js +815 -0
- package/dist_ts/classes.inferenceusagecache.d.ts +8 -0
- package/dist_ts/classes.inferenceusagecache.js +9 -5
- package/dist_ts/classes.inferenceusagetap.d.ts +50 -9
- package/dist_ts/classes.inferenceusagetap.js +185 -31
- package/dist_ts/classes.proxycontrol.d.ts +3 -2
- package/dist_ts/classes.proxycontrol.js +1 -2
- package/dist_ts/classes.proxydaemon.js +3 -2
- package/dist_ts/classes.proxystore.d.ts +6 -0
- package/dist_ts/classes.proxystore.js +11 -2
- package/dist_ts/fleet/classes.claudeworkers.d.ts +5 -4
- package/dist_ts/fleet/classes.claudeworkers.js +10 -9
- package/dist_ts/functions.claudecoderelease.d.ts +12 -6
- package/dist_ts/functions.claudecoderelease.js +13 -7
- package/dist_ts/functions.inferencecli.js +12 -8
- package/dist_ts/interfaces.auth.d.ts +1 -1
- package/dist_ts/interfaces.auth.js +3 -1
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +7 -2
- package/dist_ts_authswitch/authority-apikeys.d.ts +32 -0
- package/dist_ts_authswitch/authority-apikeys.js +65 -0
- package/dist_ts_authswitch/authority-contract.d.ts +172 -33
- package/dist_ts_authswitch/authority-contract.js +54 -1
- package/dist_ts_authswitch/authority-overview.js +8 -1
- package/dist_ts_authswitch/authority-placement.d.ts +7 -2
- package/dist_ts_authswitch/authority-placement.js +10 -3
- package/dist_ts_authswitch/authority-runtime-contract.d.ts +2 -2
- package/dist_ts_authswitch/authority-spend.d.ts +103 -0
- package/dist_ts_authswitch/authority-spend.js +110 -0
- package/dist_ts_authswitch/authority-subscription.d.ts +12 -1
- package/dist_ts_authswitch/authority-subscription.js +24 -1
- package/dist_ts_authswitch/authority-usagelimit.d.ts +7 -4
- package/dist_ts_authswitch/authority-usagelimit.js +89 -39
- package/dist_ts_authswitch/authority-usagewindows.d.ts +4 -1
- package/dist_ts_authswitch/authority-usagewindows.js +41 -16
- package/dist_ts_authswitch/classes.authoritybroker.d.ts +30 -19
- package/dist_ts_authswitch/classes.authoritybroker.js +152 -61
- package/dist_ts_authswitch/classes.authoritycli.d.ts +9 -4
- package/dist_ts_authswitch/classes.authoritycli.js +99 -30
- package/dist_ts_authswitch/classes.authorityclient.d.ts +24 -7
- package/dist_ts_authswitch/classes.authorityclient.js +45 -15
- package/dist_ts_authswitch/classes.authoritydaemon.js +39 -12
- package/dist_ts_authswitch/classes.authoritydatabase.d.ts +28 -5
- package/dist_ts_authswitch/classes.authoritydatabase.js +171 -9
- package/dist_ts_authswitch/classes.authorityimport.js +2 -2
- package/dist_ts_authswitch/classes.authoritymodels.d.ts +71 -3
- package/dist_ts_authswitch/classes.authoritymodels.js +249 -20
- package/dist_ts_authswitch/classes.authorityregistry.js +4 -2
- package/dist_ts_authswitch/classes.authorityusage.d.ts +69 -7
- package/dist_ts_authswitch/classes.authorityusage.js +118 -4
- package/dist_ts_authswitch/classes.claudenative.d.ts +23 -8
- package/dist_ts_authswitch/classes.claudenative.js +49 -21
- package/dist_ts_authswitch/classes.claudesignin.d.ts +14 -2
- package/dist_ts_authswitch/classes.claudesignin.js +72 -23
- package/dist_ts_authswitch/classes.codexmanaged.d.ts +8 -0
- package/dist_ts_authswitch/classes.codexmanaged.js +33 -18
- package/dist_ts_authswitch/classes.harnessprocesses.d.ts +8 -0
- package/dist_ts_authswitch/classes.harnessprocesses.js +41 -9
- package/dist_ts_authswitch/testsupport.d.ts +24 -5
- package/dist_ts_authswitch/testsupport.js +56 -12
- package/dist_ts_authswitch/ts_migration/0011_account_api_key_fields.d.ts +12 -0
- package/dist_ts_authswitch/ts_migration/0011_account_api_key_fields.js +21 -0
- package/dist_ts_authswitch/ts_migration/index.js +3 -1
- package/dist_ts_interfaces/functions.authorityscope.d.ts +18 -7
- package/dist_ts_interfaces/functions.authorityscope.js +35 -8
- package/dist_ts_interfaces/interfaces.d.ts +1 -1
- package/dist_ts_interfaces/interfaces.js +1 -1
- package/dist_ts_interfaces/plugins.d.ts +2 -1
- package/dist_ts_interfaces/plugins.js +7 -4
- package/dist_ts_interfaces/requests.accounts.d.ts +56 -0
- package/dist_ts_interfaces/requests.accounts.js +11 -1
- package/dist_ts_interfaces/requests.d.ts +2 -2
- package/dist_ts_interfaces/requests.js +1 -1
- package/docs/authswitch.md +75 -12
- package/package.json +5 -5
- package/readme.md +199 -22
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/aglapi/aglapisurface.document.ts +2 -2
- package/ts/classes.accountsactions.ts +75 -1
- package/ts/classes.controller.ts +4 -4
- package/ts/classes.flexaccountaccess.ts +2 -1
- package/ts/classes.harnessreleases.ts +25 -4
- package/ts/classes.inferencegateway.ts +184 -64
- package/ts/classes.inferenceplacement.ts +6 -4
- package/ts/classes.inferencerouter.ts +1026 -314
- package/ts/classes.inferenceservice.ts +56 -13
- package/ts/classes.inferencespend.ts +870 -0
- package/ts/classes.inferenceusagecache.ts +16 -4
- package/ts/classes.inferenceusagetap.ts +159 -34
- package/ts/classes.proxycontrol.ts +3 -3
- package/ts/classes.proxydaemon.ts +2 -1
- package/ts/classes.proxystore.ts +11 -1
- package/ts/fleet/classes.claudeworkers.ts +9 -8
- package/ts/functions.claudecoderelease.ts +13 -6
- package/ts/functions.inferencecli.ts +11 -7
- package/ts/interfaces.auth.ts +2 -0
- package/ts/plugins.ts +7 -0
- package/ts_authswitch/authority-apikeys.ts +85 -0
- package/ts_authswitch/authority-contract.ts +201 -34
- package/ts_authswitch/authority-overview.ts +7 -0
- package/ts_authswitch/authority-placement.ts +12 -4
- package/ts_authswitch/authority-runtime-contract.ts +2 -2
- package/ts_authswitch/authority-spend.ts +168 -0
- package/ts_authswitch/authority-subscription.ts +28 -1
- package/ts_authswitch/authority-usagelimit.ts +95 -40
- package/ts_authswitch/authority-usagewindows.ts +42 -17
- package/ts_authswitch/classes.authoritybroker.ts +161 -68
- package/ts_authswitch/classes.authoritycli.ts +112 -32
- package/ts_authswitch/classes.authorityclient.ts +66 -19
- package/ts_authswitch/classes.authoritydaemon.ts +43 -13
- package/ts_authswitch/classes.authoritydatabase.ts +178 -8
- package/ts_authswitch/classes.authorityimport.ts +1 -1
- package/ts_authswitch/classes.authoritymodels.ts +165 -19
- package/ts_authswitch/classes.authorityregistry.ts +3 -0
- package/ts_authswitch/classes.authorityusage.ts +171 -10
- package/ts_authswitch/classes.claudenative.ts +51 -22
- package/ts_authswitch/classes.claudesignin.ts +74 -24
- package/ts_authswitch/classes.codexmanaged.ts +30 -16
- package/ts_authswitch/classes.harnessprocesses.ts +39 -8
- package/ts_authswitch/native-contracts.md +82 -21
- package/ts_authswitch/readme.md +1 -1
- package/ts_authswitch/testsupport.ts +58 -11
- package/ts_authswitch/ts_migration/0011_account_api_key_fields.ts +20 -0
- package/ts_authswitch/ts_migration/index.ts +2 -0
- package/ts_interfaces/functions.authorityscope.ts +43 -8
- package/ts_interfaces/interfaces.ts +1 -1
- package/ts_interfaces/plugins.ts +6 -3
- package/ts_interfaces/requests.accounts.ts +48 -0
- package/ts_interfaces/requests.ts +4 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/accounts.plugins.ts +7 -1
- package/ts_web/accounts.templates.ts +20 -11
- package/ts_web/classes.accountsreadmodel.ts +326 -71
- package/ts_web/elements.accounts.ts +219 -20
- package/ts_web/elements.codexconnections.ts +3 -1
- package/ts_web/plugins.ts +4 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IAuthoritySocketPaths } from './classes.authorityclient.js';
|
|
2
2
|
import { InferenceRouter, type IInferenceAccountStatus, type IInferenceRoutingPolicy } from './classes.inferencerouter.js';
|
|
3
|
+
import { type IInferenceSpendStore } from './classes.inferencespend.js';
|
|
3
4
|
import { type IInferenceUsageObserverStatus } from './classes.inferenceusageobserver.js';
|
|
4
5
|
import { type IInferenceGatewayClientOptions, type IInferenceGatewayGrant, type IInferenceGatewayLease, type IInferenceGatewayLimits, type IInferenceGatewayRestoredLease, type IInferenceGatewayStatus } from './classes.inferencegateway.js';
|
|
5
6
|
import type { IInferenceAffinityStore } from './classes.inferenceaffinity.js';
|
|
@@ -17,6 +18,11 @@ export interface IInferenceServiceOptions {
|
|
|
17
18
|
placements: IInferencePlacementJournal;
|
|
18
19
|
/** Where the tokens of every answer are recorded for the usage metrics. */
|
|
19
20
|
usageLedger: IInferenceUsageLedger;
|
|
21
|
+
/**
|
|
22
|
+
* Where the spend of the answers relayed on API keys is kept until the account service acknowledged it: the proxy's
|
|
23
|
+
* own database (`ProxyStore.spend`).
|
|
24
|
+
*/
|
|
25
|
+
spendStore: IInferenceSpendStore;
|
|
20
26
|
providerFetch?: typeof fetch;
|
|
21
27
|
limits?: IInferenceGatewayLimits;
|
|
22
28
|
}
|
|
@@ -34,6 +40,11 @@ export declare class InferenceService {
|
|
|
34
40
|
* to the authority, whose answer the cache holds.
|
|
35
41
|
*/
|
|
36
42
|
private readonly observer;
|
|
43
|
+
/**
|
|
44
|
+
* The spend of the answers relayed on API keys until the account service acknowledged it: counted against each key's
|
|
45
|
+
* limit in the readings the cache hands out, and reported to the account service.
|
|
46
|
+
*/
|
|
47
|
+
private readonly spend;
|
|
37
48
|
private readonly abort;
|
|
38
49
|
private ready;
|
|
39
50
|
private started;
|
|
@@ -58,8 +69,9 @@ export declare class InferenceService {
|
|
|
58
69
|
/**
|
|
59
70
|
* The gateway's state, each pool account judged on the usage reading a request would route on now -- the account
|
|
60
71
|
* service's answer from its own cache (`InferenceUsageCache.current`), so a pool no request used since the proxy
|
|
61
|
-
* started is judged as its next request would judge it -- the
|
|
62
|
-
*
|
|
72
|
+
* started is judged as its next request would judge it -- the account each provider's next new session of a client
|
|
73
|
+
* that names no credential goes to (a subscription while one takes it, else an API key), and the latest placements the
|
|
74
|
+
* journal holds.
|
|
63
75
|
*/
|
|
64
76
|
status(signalArg: AbortSignal): Promise<IInferenceGatewayStatus & {
|
|
65
77
|
baseUrl: string;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { AuthorityState } from './classes.authoritystate.js';
|
|
3
3
|
import { FlexAccountAccess } from './classes.flexaccountaccess.js';
|
|
4
|
-
import { InferenceRouter, InferenceRoutingError } from './classes.inferencerouter.js';
|
|
4
|
+
import { InferenceRouter, InferenceRoutingError, inferencePaymentReportOptions } from './classes.inferencerouter.js';
|
|
5
5
|
import { InferenceUsageCache } from './classes.inferenceusagecache.js';
|
|
6
|
+
import { InferenceSpendOutbox } from './classes.inferencespend.js';
|
|
6
7
|
import { InferenceUsageObserver } from './classes.inferenceusageobserver.js';
|
|
7
8
|
import { InferenceGateway } from './classes.inferencegateway.js';
|
|
8
|
-
import { findAuthorityGatewayLogin, findInferencePool, isAuthorityInstallationId, parseAuthorityScope } from '../dist_ts_interfaces/index.js';
|
|
9
|
+
import { findAuthorityApiKeyLogin, findAuthorityGatewayLogin, findInferencePool, isAuthorityInstallationId, parseAuthorityScope } from '../dist_ts_interfaces/index.js';
|
|
9
10
|
/** How many of the latest placements the status shows. */
|
|
10
11
|
const recentPlacementCount = 20;
|
|
11
12
|
/** One exclusive listener owns one stable authority scope; a restart can reclaim only that scope. */
|
|
@@ -22,6 +23,11 @@ export class InferenceService {
|
|
|
22
23
|
* to the authority, whose answer the cache holds.
|
|
23
24
|
*/
|
|
24
25
|
observer;
|
|
26
|
+
/**
|
|
27
|
+
* The spend of the answers relayed on API keys until the account service acknowledged it: counted against each key's
|
|
28
|
+
* limit in the readings the cache hands out, and reported to the account service.
|
|
29
|
+
*/
|
|
30
|
+
spend;
|
|
25
31
|
abort = new AbortController();
|
|
26
32
|
ready = false;
|
|
27
33
|
started = false;
|
|
@@ -45,6 +51,22 @@ export class InferenceService {
|
|
|
45
51
|
// Routing needs a reading: an account added a moment ago is routed on once its first read landed.
|
|
46
52
|
return client.getUsage(accountIdArg, login.id, signalArg, { waitForFirstRead: true });
|
|
47
53
|
},
|
|
54
|
+
// A key's reading counts the answers whose spend the account service has not acknowledged yet.
|
|
55
|
+
view: (accountIdArg, snapshotArg) => this.spend.judged(accountIdArg, snapshotArg),
|
|
56
|
+
});
|
|
57
|
+
this.spend = new InferenceSpendOutbox({
|
|
58
|
+
store: options.spendStore,
|
|
59
|
+
// Reported on the login each answer was served on, which the outbox keeps with it: also once the key was removed.
|
|
60
|
+
report: async (accountIdArg, loginIdArg, answersArg, signalArg) => {
|
|
61
|
+
const client = this.authority.readyClient();
|
|
62
|
+
if (!this.ready || !client)
|
|
63
|
+
throw new Error('The account service is unavailable.');
|
|
64
|
+
return client.recordSpend(accountIdArg, loginIdArg, answersArg, signalArg);
|
|
65
|
+
},
|
|
66
|
+
// The account service's answer counts the report's answers: it replaces the held reading as they leave the outbox.
|
|
67
|
+
acknowledged: (accountIdArg, usageArg) => this.usage.accept(accountIdArg, usageArg),
|
|
68
|
+
// An answer recorded without a login is reported on the key's live login, or the removed key's.
|
|
69
|
+
attribute: (accountIdArg) => findAuthorityApiKeyLogin(this.authority.getProjection(), accountIdArg)?.id,
|
|
48
70
|
});
|
|
49
71
|
this.observer = new InferenceUsageObserver({
|
|
50
72
|
send: async (accountIdArg, reportArg, signalArg) => {
|
|
@@ -70,15 +92,21 @@ export class InferenceService {
|
|
|
70
92
|
},
|
|
71
93
|
usage: (accountIdArg, signalArg) => this.usage.get(accountIdArg, signalArg),
|
|
72
94
|
// The account service holds a payment problem on the account's usage, which the cache then routes on.
|
|
73
|
-
reportPaymentProblem: async (accountIdArg, observedAtArg) => {
|
|
95
|
+
reportPaymentProblem: async (accountIdArg, observedAtArg, causeArg) => {
|
|
74
96
|
const client = this.authority.readyClient();
|
|
75
97
|
const login = findAuthorityGatewayLogin(this.authority.getProjection(), accountIdArg);
|
|
76
98
|
if (!this.ready || !client || typeof login === 'string')
|
|
77
99
|
throw new Error('The account login is unavailable.');
|
|
78
|
-
const usage = await client.reportPaymentProblem(accountIdArg, login.id, observedAtArg, this.abort.signal);
|
|
100
|
+
const usage = await client.reportPaymentProblem(accountIdArg, login.id, observedAtArg, this.abort.signal, inferencePaymentReportOptions(causeArg));
|
|
79
101
|
this.usage.accept(accountIdArg, usage);
|
|
80
102
|
},
|
|
81
103
|
resolveAccess: (accountIdArg, signalArg, rejectedGenerationArg) => this.access.resolveGateway(accountIdArg, AbortSignal.any([signalArg, this.abort.signal]), rejectedGenerationArg),
|
|
104
|
+
// Recorded on the login the route was served on, as the pool was read when the request was placed.
|
|
105
|
+
spend: {
|
|
106
|
+
record: (accountIdArg, loginIdArg, recordArg) => this.spend.record(accountIdArg, loginIdArg, recordArg),
|
|
107
|
+
held: (accountIdArg) => this.spend.held(accountIdArg),
|
|
108
|
+
uncounted: (accountIdArg, modelArg) => this.spend.uncounted(accountIdArg, modelArg),
|
|
109
|
+
},
|
|
82
110
|
});
|
|
83
111
|
this.gateway = new InferenceGateway({ router: this.router, signatureKey: options.signatureKey,
|
|
84
112
|
affinity: options.affinity, placements: options.placements, usageLedger: options.usageLedger, port: options.port,
|
|
@@ -95,8 +123,10 @@ export class InferenceService {
|
|
|
95
123
|
return undefined;
|
|
96
124
|
return projection.snapshot.accounts.flatMap((account) => {
|
|
97
125
|
const pool = findInferencePool(projection, account.id);
|
|
126
|
+
const login = findAuthorityGatewayLogin(projection, account.id);
|
|
98
127
|
return pool ? [{ id: account.id, label: account.label, revision: String(account.revision), providerId: pool.provider,
|
|
99
|
-
credential: pool.credential, maxUsagePercent: account.maxUsagePercent, reserveLiftUntil: account.reserveLiftUntil, lapsesAt: account.lapsesAt
|
|
128
|
+
credential: pool.credential, maxUsagePercent: account.maxUsagePercent, reserveLiftUntil: account.reserveLiftUntil, lapsesAt: account.lapsesAt,
|
|
129
|
+
spendLimitMicroUsd: account.spendLimitMicroUsd, loginId: typeof login === 'string' ? null : login.id }] : [];
|
|
100
130
|
});
|
|
101
131
|
}
|
|
102
132
|
/**
|
|
@@ -125,6 +155,8 @@ export class InferenceService {
|
|
|
125
155
|
incarnationId: binding.incarnationId, expectedRevision: binding.revision }, signal);
|
|
126
156
|
}
|
|
127
157
|
this.ready = true;
|
|
158
|
+
// The answers a run before left unacknowledged count from the start, before any request is placed, and are sent.
|
|
159
|
+
await this.spend.start(signal);
|
|
128
160
|
return this.baseUrl;
|
|
129
161
|
}
|
|
130
162
|
catch (errorArg) {
|
|
@@ -147,17 +179,18 @@ export class InferenceService {
|
|
|
147
179
|
/**
|
|
148
180
|
* The gateway's state, each pool account judged on the usage reading a request would route on now -- the account
|
|
149
181
|
* service's answer from its own cache (`InferenceUsageCache.current`), so a pool no request used since the proxy
|
|
150
|
-
* started is judged as its next request would judge it -- the
|
|
151
|
-
*
|
|
182
|
+
* started is judged as its next request would judge it -- the account each provider's next new session of a client
|
|
183
|
+
* that names no credential goes to (a subscription while one takes it, else an API key), and the latest placements the
|
|
184
|
+
* journal holds.
|
|
152
185
|
*/
|
|
153
186
|
async status(signalArg) {
|
|
154
187
|
const pool = this.poolAccounts() ?? [];
|
|
155
|
-
|
|
188
|
+
// A key's usage is its month's spend, with the payment problem the account service holds on it.
|
|
189
|
+
const readings = new Map(await Promise.all(pool
|
|
156
190
|
.map(async (accountArg) => [accountArg.id, await this.usage.current(accountArg.id, signalArg)])));
|
|
157
191
|
const accounts = this.router.accountStatus(pool, (accountIdArg) => readings.get(accountIdArg));
|
|
158
192
|
const recent = await this.options.placements.recent(recentPlacementCount, signalArg);
|
|
159
|
-
const next = (providerArg) => accounts.find((accountArg) => accountArg.provider === providerArg && accountArg.
|
|
160
|
-
&& accountArg.placementRank === 1)?.id ?? null;
|
|
193
|
+
const next = (providerArg) => accounts.find((accountArg) => accountArg.provider === providerArg && accountArg.placementRank === 1)?.id ?? null;
|
|
161
194
|
return { ...this.gateway.status(), baseUrl: this.baseUrl ?? '', usageObservations: this.observer.status(),
|
|
162
195
|
authority: this.ready && this.authority.getProjection().state === 'ready' ? 'ready' : 'unavailable',
|
|
163
196
|
accounts,
|
|
@@ -173,20 +206,26 @@ export class InferenceService {
|
|
|
173
206
|
await this.gateway.stop();
|
|
174
207
|
}
|
|
175
208
|
finally {
|
|
176
|
-
// Hand-overs in flight end before the authority connection closes under them
|
|
209
|
+
// Hand-overs in flight end before the authority connection closes under them; the answers the gateway ended are
|
|
210
|
+
// in the outbox, which keeps what it holds for the next start.
|
|
177
211
|
try {
|
|
178
212
|
await this.observer.stop();
|
|
179
213
|
}
|
|
180
214
|
finally {
|
|
181
215
|
try {
|
|
182
|
-
await this.
|
|
216
|
+
await this.spend.stop();
|
|
183
217
|
}
|
|
184
218
|
finally {
|
|
185
|
-
|
|
219
|
+
try {
|
|
220
|
+
await this.access.stop();
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
await this.authority.stop();
|
|
224
|
+
}
|
|
186
225
|
}
|
|
187
226
|
}
|
|
188
227
|
}
|
|
189
228
|
})();
|
|
190
229
|
}
|
|
191
230
|
}
|
|
192
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pbmZlcmVuY2VzZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvY2xhc3Nlcy5pbmZlcmVuY2VzZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUU3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZUFBZSxFQUFFLHFCQUFxQixFQUNmLE1BQU0sOEJBQThCLENBQUM7QUFDckUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdkUsT0FBTyxFQUFFLHNCQUFzQixFQUFzQyxNQUFNLHFDQUFxQyxDQUFDO0FBQ2pILE9BQU8sRUFBRSxnQkFBZ0IsRUFDMEUsTUFBTSwrQkFBK0IsQ0FBQztBQUt6SSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsaUJBQWlCLEVBQUUseUJBQXlCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQWlCekksMERBQTBEO0FBQzFELE1BQU0sb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0FBRWhDLHFHQUFxRztBQUNyRyxNQUFNLE9BQU8sZ0JBQWdCO0lBa0JFLE9BQU87SUFqQnBCLE1BQU0sQ0FBa0I7SUFDdkIsU0FBUyxDQUFpQjtJQUMxQixNQUFNLENBQW9CO0lBQzFCLE9BQU8sQ0FBbUI7SUFDM0MsaUhBQWlIO0lBQ2hHLEtBQUssQ0FBc0I7SUFDNUM7OztPQUdHO0lBQ2MsUUFBUSxDQUF5QjtJQUNqQyxLQUFLLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUN2QyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ2QsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUNoQixPQUFPLENBQVU7SUFDakIsUUFBUSxDQUFpQjtJQUVqQyxZQUE2QixPQUFpQzt1QkFB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
|
|
231
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pbmZlcmVuY2VzZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvY2xhc3Nlcy5pbmZlcmVuY2VzZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUU3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZUFBZSxFQUFFLHFCQUFxQixFQUFFLDZCQUE2QixFQUNoQixNQUFNLDhCQUE4QixDQUFDO0FBQ25HLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxvQkFBb0IsRUFBNkIsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RixPQUFPLEVBQUUsc0JBQXNCLEVBQXNDLE1BQU0scUNBQXFDLENBQUM7QUFDakgsT0FBTyxFQUFFLGdCQUFnQixFQUMwRSxNQUFNLCtCQUErQixDQUFDO0FBS3pJLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSx5QkFBeUIsRUFBRSxpQkFBaUIsRUFBRSx5QkFBeUIsRUFDeEcsbUJBQW1CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQXNCekQsMERBQTBEO0FBQzFELE1BQU0sb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0FBRWhDLHFHQUFxRztBQUNyRyxNQUFNLE9BQU8sZ0JBQWdCO0lBdUJFLE9BQU87SUF0QnBCLE1BQU0sQ0FBa0I7SUFDdkIsU0FBUyxDQUFpQjtJQUMxQixNQUFNLENBQW9CO0lBQzFCLE9BQU8sQ0FBbUI7SUFDM0MsaUhBQWlIO0lBQ2hHLEtBQUssQ0FBc0I7SUFDNUM7OztPQUdHO0lBQ2MsUUFBUSxDQUF5QjtJQUNsRDs7O09BR0c7SUFDYyxLQUFLLENBQXVCO0lBQzVCLEtBQUssR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO0lBQ3ZD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
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
type TSpendAnswer = plugins.authswitchAuthority.IAuthSwitchSpendAnswer;
|
|
3
|
+
type TUsageSnapshot = plugins.authswitchAuthority.IAuthSwitchUsageSnapshot;
|
|
4
|
+
/**
|
|
5
|
+
* The `type` of every server tool a Messages request declares: each tool whose type is neither absent nor one of the
|
|
6
|
+
* client tools (`anthropicClientToolTypes`); a type that is no string is named as it reads.
|
|
7
|
+
*/
|
|
8
|
+
export declare const inferenceAnthropicServerToolTypes: (bodyArg: Record<string, unknown>) => string[];
|
|
9
|
+
/**
|
|
10
|
+
* What of an Anthropic Messages request the proxy's price table (flexharness `getAnthropicModelPrice`,
|
|
11
|
+
* `getAnthropicRequestPrice`, `getAnthropicServerToolPrice`) cannot price, in words, or `undefined` when all of it can
|
|
12
|
+
* be: the model; a service tier other than `auto` and `standard_only`, the two a request may name
|
|
13
|
+
* (https://platform.claude.com/docs/en/api/service-tiers, read 2026-10-22), as the proxy sends a key with a spend limit
|
|
14
|
+
* on the standard tier only; a speed the model has no price for (`speed: "fast"` is Fast mode); an `inference_geo` the
|
|
15
|
+
* model has no surcharge for; a server tool whose exact type has no price, Anthropic's MCP connector included. A key
|
|
16
|
+
* with a monthly spend limit takes no such request, since its answer could not be priced (Decision Q4). The answer is
|
|
17
|
+
* still priced by the model that answered and what its usage states, never by this.
|
|
18
|
+
*/
|
|
19
|
+
export declare const inferenceAnthropicUnpricedRequest: (bodyArg: Record<string, unknown>) => string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The bytes a request goes to an Anthropic API key with a spend limit as: the body the price check read
|
|
22
|
+
* (`inferenceAnthropicUnpricedRequest`), encoded again with `service_tier: "standard_only"`, so it is served on the
|
|
23
|
+
* standard tier the price table prices and never on Priority Tier, which has no published price (lane A ruling 6), and
|
|
24
|
+
* Anthropic receives exactly what was checked -- also when the client named `standard_only` itself.
|
|
25
|
+
*/
|
|
26
|
+
export declare const inferenceAnthropicCheckedBytes: (bodyArg: Record<string, unknown>) => Uint8Array<ArrayBuffer>;
|
|
27
|
+
/** What a relayed answer stated about its usage, as the gateway's usage tap read it while the answer passed. */
|
|
28
|
+
export interface IInferenceAnsweredUsage {
|
|
29
|
+
/** The model that answered, as the answer named it; absent when it named none the tap could read. */
|
|
30
|
+
model?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The answer's usage object as the provider sent it -- a stream's merged from `message_start` and the `message_delta`s
|
|
33
|
+
* after it -- absent when the answer stated none.
|
|
34
|
+
*/
|
|
35
|
+
usage?: Record<string, unknown>;
|
|
36
|
+
/** The answer arrived whole: a JSON body read to its end, or a stream through `message_stop`. */
|
|
37
|
+
complete: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** One answer's spend as the outbox keeps it, and why it could not be priced when it could not. */
|
|
40
|
+
export interface IInferenceSpendRecord {
|
|
41
|
+
answer: TSpendAnswer;
|
|
42
|
+
/** Why the answer could not be priced (`answer.microUsd` is then null). */
|
|
43
|
+
unpriced?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The spend of an answer an Anthropic API key served, priced once by the model that answered and the usage it stated
|
|
47
|
+
* (`readAnthropicMessagesUsage`, `priceModelCall`), never by the requested model, with the call fees of the server tools
|
|
48
|
+
* the request declared (`serverToolTypesArg`, `getAnthropicRequestPrice`). An answer whose model has no price, whose usage
|
|
49
|
+
* cannot be read completely or priced -- a tier, a cache lifetime, a server tool or a region the price lacks -- counts
|
|
50
|
+
* as one that could not be priced (`microUsd: null`), which holds a key with a spend limit until its month ends. A stream
|
|
51
|
+
* cut before it stated any usage records nothing: the client received no token of it; one cut later is priced on the
|
|
52
|
+
* usage it stated by then. `requestedModelArg` names the answer when it named no model.
|
|
53
|
+
*/
|
|
54
|
+
export declare const inferenceAnthropicSpend: (answeredArg: IInferenceAnsweredUsage, requestedModelArg: string, nowArg: number, serverToolTypesArg?: readonly string[]) => IInferenceSpendRecord | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* The `type` of every server tool a Responses request declares, in `tools` and in the tools its input adds
|
|
57
|
+
* (`additional_tools` and `tool_search_output` items), a namespace's own tools included: each tool that is no client
|
|
58
|
+
* tool (`openAiClientToolTypes`, a local `shell`); a type that is no string is named as it reads.
|
|
59
|
+
*/
|
|
60
|
+
export declare const inferenceOpenAiServerToolTypes: (bodyArg: Record<string, unknown>) => string[];
|
|
61
|
+
/**
|
|
62
|
+
* What of a Responses request the proxy's price table (flexharness `getOpenAiModelPrice`) cannot price, in words, or
|
|
63
|
+
* `undefined` when all of it can be: the model, by its exact id or a listed snapshot (a dated id the price lists not is
|
|
64
|
+
* unpriced); an explicit service tier the model has no price for (`auto` and none go out as `default`; `fast` names
|
|
65
|
+
* Fast mode; `scale` has no published price); a background response (`background: true`), whose answer never passes the
|
|
66
|
+
* proxy; a server tool whose exact type has no call fee (`inferenceOpenAiServerToolTypes`). An OpenAI API key with a
|
|
67
|
+
* monthly spend limit takes no such request (Decision Q4).
|
|
68
|
+
*/
|
|
69
|
+
export declare const inferenceOpenAiUnpricedRequest: (bodyArg: Record<string, unknown>) => string | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* The bytes a Responses request goes to an OpenAI API key with a spend limit as: the body the price check read
|
|
72
|
+
* (`inferenceOpenAiUnpricedRequest`), the model rewritten to `wireModelArg`, encoded again with the service tier it was
|
|
73
|
+
* checked for (`default` when the client named `auto` or none), so OpenAI serves it on a tier the price table prices.
|
|
74
|
+
*/
|
|
75
|
+
export declare const inferenceOpenAiCheckedBytes: (bodyArg: Record<string, unknown>, wireModelArg: string) => Uint8Array<ArrayBuffer>;
|
|
76
|
+
/** What a relayed Responses answer stated for its price, as the gateway's usage tap read it while the answer passed. */
|
|
77
|
+
export interface IInferenceResponsesAnswered {
|
|
78
|
+
/**
|
|
79
|
+
* How the answer ended: `answered`, its terminal event (`response.completed`, `response.incomplete`,
|
|
80
|
+
* `response.failed`) or its JSON body was read; `unreadable`, it arrived but was too large to read (over 8 MiB);
|
|
81
|
+
* `cut`, it ended before either arrived -- the client left, or the provider's stream ended or failed.
|
|
82
|
+
*/
|
|
83
|
+
outcome: 'answered' | 'unreadable' | 'cut';
|
|
84
|
+
/** The response's `status` as stated (`completed`, `incomplete`, `failed`). */
|
|
85
|
+
status?: string;
|
|
86
|
+
/** The model that answered (`response.model`). */
|
|
87
|
+
model?: string;
|
|
88
|
+
/** The service tier that served it (`response.service_tier`), as stated. */
|
|
89
|
+
serviceTier?: unknown;
|
|
90
|
+
/** The response's `usage` object as sent; absent when it stated none. */
|
|
91
|
+
usage?: Record<string, unknown>;
|
|
92
|
+
/** The ids of the answer's `web_search_call` and `file_search_call` items, each once, whatever its action. */
|
|
93
|
+
webSearchCalls: ReadonlySet<string>;
|
|
94
|
+
fileSearchCalls: ReadonlySet<string>;
|
|
95
|
+
/** A web or file search call without an id, which cannot be counted once. */
|
|
96
|
+
unidentifiedCalls: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The spend of a Responses answer an OpenAI API key served, priced once by the model that answered, the tier that served
|
|
100
|
+
* it and the usage it stated (`readOpenAiResponsesUsage`, `priceModelCall`), with every `web_search_call` item one web
|
|
101
|
+
* search and every `file_search_call` item one file search, counted once per item id whatever its action -- so AGL's
|
|
102
|
+
* figure can exceed OpenAI's bill. A completed, incomplete or failed answer that states its usage is priced; one whose
|
|
103
|
+
* model, tier or usage the price table cannot price counts as one that could not be priced (`microUsd: null`), which
|
|
104
|
+
* holds a key with a spend limit until its month ends, and so does one that arrived too large to read, or a completed
|
|
105
|
+
* or incomplete one that states no usage. A failed answer that states none, and one cut before its terminal event,
|
|
106
|
+
* record nothing (`undefined`): no usage is estimated, and the caller says so in the journal.
|
|
107
|
+
*/
|
|
108
|
+
export declare const inferenceOpenAiSpend: (answeredArg: IInferenceResponsesAnswered, requestedModelArg: string, nowArg: number) => IInferenceSpendRecord | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* One answer the proxy relayed on an API key, as its outbox keeps it until the accounts service acknowledged its cost:
|
|
111
|
+
* the spend report answer (`IAuthSwitchSpendAnswer`, its `answerId` as `id`) and the key's account. No prompt, answer
|
|
112
|
+
* content, token count or credential is part of it.
|
|
113
|
+
*/
|
|
114
|
+
export interface IInferenceSpendDocument {
|
|
115
|
+
/** The answer's id (`IAuthSwitchSpendAnswer.answerId`), a UUID. */
|
|
116
|
+
id: string;
|
|
117
|
+
/** The API key's account. */
|
|
118
|
+
accountId: string;
|
|
119
|
+
/**
|
|
120
|
+
* The key's login the answer was served on, which its report names, also once the key is removed; `null` when none
|
|
121
|
+
* could be named, so the answer waits, counted, until one can (`IInferenceSpendOutboxOptions.attribute`).
|
|
122
|
+
*/
|
|
123
|
+
loginId: string | null;
|
|
124
|
+
endedAt: string;
|
|
125
|
+
model: string;
|
|
126
|
+
serviceTier: string | null;
|
|
127
|
+
microUsd: number | null;
|
|
128
|
+
priceSource: string | null;
|
|
129
|
+
}
|
|
130
|
+
export declare class InferenceSpendModel extends plugins.nosqldb.SmartDataDbDoc<InferenceSpendModel, IInferenceSpendDocument> {
|
|
131
|
+
static exact: plugins.nosqldb.TExact<InferenceSpendModel>;
|
|
132
|
+
id: string;
|
|
133
|
+
accountId: string;
|
|
134
|
+
loginId: string | null;
|
|
135
|
+
endedAt: string;
|
|
136
|
+
model: string;
|
|
137
|
+
serviceTier: string | null;
|
|
138
|
+
microUsd: number | null;
|
|
139
|
+
priceSource: string | null;
|
|
140
|
+
}
|
|
141
|
+
/** An answer the outbox keeps, with its key's account and the login it was served on (`null`: none named yet). */
|
|
142
|
+
export interface IInferenceSpendEntry {
|
|
143
|
+
accountId: string;
|
|
144
|
+
loginId: string | null;
|
|
145
|
+
answer: TSpendAnswer;
|
|
146
|
+
}
|
|
147
|
+
/** The outbox's durable side: the answers kept in the proxy's own database until acknowledged. */
|
|
148
|
+
export interface IInferenceSpendStore {
|
|
149
|
+
/** Every answer kept. */
|
|
150
|
+
load(signalArg: AbortSignal): Promise<IInferenceSpendEntry[]>;
|
|
151
|
+
/** Keeps an answer; one kept already with the same content is kept. */
|
|
152
|
+
insert(entryArg: IInferenceSpendEntry, signalArg: AbortSignal): Promise<void>;
|
|
153
|
+
/** Forgets answers by id; one forgotten already is forgotten. */
|
|
154
|
+
delete(answerIdsArg: readonly string[], signalArg: AbortSignal): Promise<void>;
|
|
155
|
+
}
|
|
156
|
+
/** The outbox's store in the proxy's database (`agl_inference_spend`, a model of `proxyModels`). */
|
|
157
|
+
export declare class InferenceSpendStore implements IInferenceSpendStore {
|
|
158
|
+
load(signalArg: AbortSignal): Promise<IInferenceSpendEntry[]>;
|
|
159
|
+
insert(entryArg: IInferenceSpendEntry, signalArg: AbortSignal): Promise<void>;
|
|
160
|
+
delete(answerIdsArg: readonly string[], signalArg: AbortSignal): Promise<void>;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Something the outbox says in the proxy's journal: an answer that could not be priced (`unpriced`, an accounting
|
|
164
|
+
* error), a report the accounts service refused (`refused`), a key whose reports keep failing (`unreported`, said once
|
|
165
|
+
* until one goes through), answers the store could not keep (`unkept`) or acknowledged answers it could not remove
|
|
166
|
+
* (`unremoved`), each said once until the store takes writes again, an answer recorded with no login of its key
|
|
167
|
+
* (`unattributed`), and each answer that ended without its provider stating its usage, which counts nowhere (`uncounted`).
|
|
168
|
+
* Keys are named by their account's digest.
|
|
169
|
+
*/
|
|
170
|
+
export type TInferenceSpendJournalEntry = {
|
|
171
|
+
kind: 'unpriced';
|
|
172
|
+
account: string;
|
|
173
|
+
model: string;
|
|
174
|
+
reason: string;
|
|
175
|
+
} | {
|
|
176
|
+
kind: 'refused';
|
|
177
|
+
account: string;
|
|
178
|
+
answers: number;
|
|
179
|
+
error: string;
|
|
180
|
+
retryAt: string;
|
|
181
|
+
} | {
|
|
182
|
+
kind: 'unreported';
|
|
183
|
+
account: string;
|
|
184
|
+
answers: number;
|
|
185
|
+
error: string;
|
|
186
|
+
} | {
|
|
187
|
+
kind: 'unkept';
|
|
188
|
+
answers: number;
|
|
189
|
+
error: string;
|
|
190
|
+
} | {
|
|
191
|
+
kind: 'unremoved';
|
|
192
|
+
answers: number;
|
|
193
|
+
error: string;
|
|
194
|
+
} | {
|
|
195
|
+
kind: 'unattributed';
|
|
196
|
+
account: string;
|
|
197
|
+
model: string;
|
|
198
|
+
} | {
|
|
199
|
+
kind: 'uncounted';
|
|
200
|
+
account: string;
|
|
201
|
+
model: string;
|
|
202
|
+
};
|
|
203
|
+
export interface IInferenceSpendOutboxOptions {
|
|
204
|
+
store: IInferenceSpendStore;
|
|
205
|
+
/**
|
|
206
|
+
* Sends one report of answers a key served on one of its logins (`authswitch.authority.usage.spend`, one to 64 answers,
|
|
207
|
+
* each id once) and resolves with the key's usage the accounts service answered once the report committed.
|
|
208
|
+
*/
|
|
209
|
+
report: (accountIdArg: string, loginIdArg: string, answersArg: TSpendAnswer[], signalArg: AbortSignal) => Promise<TUsageSnapshot>;
|
|
210
|
+
/**
|
|
211
|
+
* Names a login of the key for answers recorded without one -- the account service's live or removed API-key login of
|
|
212
|
+
* it -- or `undefined` while it names none; such answers count and hold the key until then.
|
|
213
|
+
*/
|
|
214
|
+
attribute: (accountIdArg: string) => string | undefined;
|
|
215
|
+
/**
|
|
216
|
+
* Holds the usage an acknowledged report answered, which counts the report's answers: called in the same synchronous
|
|
217
|
+
* step that drops them from what is pending, so no reading is judged without them or with them twice.
|
|
218
|
+
*/
|
|
219
|
+
acknowledged: (accountIdArg: string, usageArg: TUsageSnapshot) => void;
|
|
220
|
+
/** Where the outbox's journal entries go; one line on standard error, the proxy's journal, when unset. */
|
|
221
|
+
journal?: (entryArg: TInferenceSpendJournalEntry) => void;
|
|
222
|
+
now?: () => number;
|
|
223
|
+
/** The first wait after a report or a store write failed for a passing reason; it doubles up to `maxRetryMs`. */
|
|
224
|
+
retryMs?: number;
|
|
225
|
+
maxRetryMs?: number;
|
|
226
|
+
/** How long answers whose report the accounts service refused wait before they are sent again. */
|
|
227
|
+
heldRetryMs?: number;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The spend of the answers the proxy relayed on API keys, kept until the accounts service acknowledged it: durable in
|
|
231
|
+
* the proxy's database (`agl_inference_spend`), never expired, and counted against each key's limit while unacknowledged
|
|
232
|
+
* (`judged`), across restarts.
|
|
233
|
+
*
|
|
234
|
+
* `record` counts an answer at once and writes it to the store at once, on a chain of store writes that never waits for
|
|
235
|
+
* a report, so an answer recorded while a report is in flight is durable before that report settles. Answers are
|
|
236
|
+
* reported whether the store kept them yet or not -- the ledger records an answer once, so either makes it durable --
|
|
237
|
+
* per key and login in batches of at most 64 unique answers, one report in flight at a time, the first as soon as an
|
|
238
|
+
* answer is recorded and every one at start. An answer held in neither after a failed store write holds its key, with
|
|
239
|
+
* a spend limit, like a refused report (`held`). The in-memory index is complete because the proxy store has one owner
|
|
240
|
+
* (`ProxyStore` refuses a second engine); a second writer of `agl_inference_spend` would break it.
|
|
241
|
+
* An acknowledgement drops the report's answers and holds the usage the service answered in one step (`acknowledged`).
|
|
242
|
+
* A refusal of the report -- `invalid_input`, or a malformed request (`isAuthSwitchMalformedRequest`) -- holds its
|
|
243
|
+
* answers: they keep counting, the key with a spend limit takes no request while any is held (`held`), the refusal goes
|
|
244
|
+
* to the journal, and the answers are sent again after `heldRetryMs` and at every start, never dropped. Every other
|
|
245
|
+
* failure, `Internal server error` included, is passing: the key's reports wait, doubling from `retryMs` to
|
|
246
|
+
* `maxRetryMs`. Answers of months before the previous one are acknowledged by the service and counted nowhere, so they
|
|
247
|
+
* leave as every acknowledged answer does.
|
|
248
|
+
*/
|
|
249
|
+
export declare class InferenceSpendOutbox {
|
|
250
|
+
private readonly options;
|
|
251
|
+
/** The answers not acknowledged yet, by key, then answer id: an id is held once, so no report names one twice. */
|
|
252
|
+
private readonly entries;
|
|
253
|
+
private readonly accounts;
|
|
254
|
+
/** Acknowledged answers still to be removed from the store. */
|
|
255
|
+
private readonly acknowledgedIds;
|
|
256
|
+
private readonly abort;
|
|
257
|
+
private readonly now;
|
|
258
|
+
private readonly retryMs;
|
|
259
|
+
private readonly maxRetryMs;
|
|
260
|
+
private readonly heldRetryMs;
|
|
261
|
+
/** The store writes of recorded answers, one at a time, apart from the reports. */
|
|
262
|
+
private keepTail;
|
|
263
|
+
private keepFailures;
|
|
264
|
+
private keepRetryAt;
|
|
265
|
+
private keepSaid;
|
|
266
|
+
private keepTimer?;
|
|
267
|
+
private forgetFailures;
|
|
268
|
+
private forgetRetryAt;
|
|
269
|
+
private forgetSaid;
|
|
270
|
+
private started;
|
|
271
|
+
private stopped;
|
|
272
|
+
private running?;
|
|
273
|
+
private again;
|
|
274
|
+
private timer?;
|
|
275
|
+
constructor(options: IInferenceSpendOutboxOptions);
|
|
276
|
+
/** Loads the answers a run before left unacknowledged and sends them all now. */
|
|
277
|
+
start(signalArg?: AbortSignal): Promise<void>;
|
|
278
|
+
/**
|
|
279
|
+
* Counts a relayed answer's spend at once, writes it to the store and reports it, naming the key's login it was served
|
|
280
|
+
* on (`loginIdArg`), until the accounts service acknowledged it; an answer that could not be priced goes to the journal
|
|
281
|
+
* as well. One recorded without a login (`null`) counts all the same, holds the key (`held`) and waits for a login to
|
|
282
|
+
* be named (`attribute`), which the journal says. Throws for an answer no report could carry, a defect of its caller.
|
|
283
|
+
*/
|
|
284
|
+
record(accountIdArg: string, loginIdArg: string | null, recordArg: IInferenceSpendRecord): void;
|
|
285
|
+
/**
|
|
286
|
+
* Says in the journal that an answer relayed on the key ended without its provider stating its usage -- the client left,
|
|
287
|
+
* the stream was cut, or the response failed stating none -- so nothing of it is counted; no usage is estimated for it
|
|
288
|
+
* (`inferenceOpenAiSpend`).
|
|
289
|
+
*/
|
|
290
|
+
uncounted(accountIdArg: string, modelArg: string): void;
|
|
291
|
+
/** The answers relayed on a key whose spend the accounts service has not acknowledged yet. */
|
|
292
|
+
pending(accountIdArg: string): plugins.authswitchSpend.IAuthSwitchSpendPending[];
|
|
293
|
+
/**
|
|
294
|
+
* Whether spend of the key is not recorded and might never be: the accounts service refused a report of its answers
|
|
295
|
+
* that is still held, an answer is held in neither the store, whose write failed, nor the accounts service's ledger,
|
|
296
|
+
* or an answer has no login of the key to be reported on yet.
|
|
297
|
+
*/
|
|
298
|
+
held(accountIdArg: string): boolean;
|
|
299
|
+
/**
|
|
300
|
+
* A key's usage as the proxy judges it now: its spend reading with the answers not acknowledged yet added, in the
|
|
301
|
+
* month now falls in (`authSwitchSpendWithPending`). Any other usage is answered as it is.
|
|
302
|
+
*/
|
|
303
|
+
judged(accountIdArg: string, usageArg: TUsageSnapshot): TUsageSnapshot;
|
|
304
|
+
/**
|
|
305
|
+
* Stops sending; what is held stays in the store for the next start. The store writes in progress finish, and what is
|
|
306
|
+
* still not kept or not removed is written once more.
|
|
307
|
+
*/
|
|
308
|
+
stop(): Promise<void>;
|
|
309
|
+
private add;
|
|
310
|
+
private say;
|
|
311
|
+
/** Runs the outbox's work now, or once more after the run in progress. */
|
|
312
|
+
private kick;
|
|
313
|
+
/** Removes what was acknowledged from the store, then sends every report that is due. */
|
|
314
|
+
private cycle;
|
|
315
|
+
/**
|
|
316
|
+
* Writes the recorded answers not kept yet to the store, on the outbox's chain of store writes, which runs apart from
|
|
317
|
+
* the reports and never waits for one; once they are kept the reports run. After a failed write the next waits,
|
|
318
|
+
* doubling from `retryMs`, unless an answer recorded meanwhile, or the stop, tries again sooner.
|
|
319
|
+
*/
|
|
320
|
+
private keep;
|
|
321
|
+
/**
|
|
322
|
+
* One pass of the store writes: every answer not kept yet, one at a time. A write that fails is said once until the
|
|
323
|
+
* store takes writes again; the answers count meanwhile all the same.
|
|
324
|
+
*/
|
|
325
|
+
private keepOnce;
|
|
326
|
+
/** Removes the acknowledged answers from the store; a failed removal waits, doubling, said once. */
|
|
327
|
+
private forget;
|
|
328
|
+
/**
|
|
329
|
+
* The next report due: a key's held answers once their wait ended, as a report of their own, else its other answers,
|
|
330
|
+
* kept or not; of one login, oldest first, at most 64, each id once. Answers recorded without a login take the one
|
|
331
|
+
* `attribute` names now; while it names none they wait, the key's reports backing off as after a passing failure.
|
|
332
|
+
*/
|
|
333
|
+
private nextBatch;
|
|
334
|
+
private send;
|
|
335
|
+
private backoff;
|
|
336
|
+
/** Wakes the reports when the next held or waiting answer, or a removal to try again, is due. */
|
|
337
|
+
private arm;
|
|
338
|
+
}
|
|
339
|
+
export {};
|