agent-relay-server 0.89.0 → 0.89.2
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/docs/openapi.json +1 -1
- package/package.json +1 -1
- package/src/db/provider-quotas.ts +32 -1
- package/src/quota-advisory.ts +18 -2
package/docs/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Agent Relay API",
|
|
5
|
-
"version": "0.89.
|
|
5
|
+
"version": "0.89.2",
|
|
6
6
|
"description": "Real-time message bus for inter-agent communication. Agent-first: this spec is designed for machine consumption — agents can self-discover the full API surface via GET /api/spec.",
|
|
7
7
|
"license": {
|
|
8
8
|
"name": "MIT",
|
package/package.json
CHANGED
|
@@ -5,6 +5,9 @@ import { parseStringArray } from "./shared.ts";
|
|
|
5
5
|
import type { AgentCard, ProviderQuotaError, ProviderQuotaMatrix, ProviderQuotaRecord, ProviderQuotaSnapshot, ProviderQuotaUpdateInput, QuotaState } from "../types";
|
|
6
6
|
|
|
7
7
|
const PROVIDER_QUOTA_STALE_AFTER_MS = 10 * 60_000;
|
|
8
|
+
const QUOTA_UTILIZATION_EPSILON = 1e-9;
|
|
9
|
+
const QUOTA_RESET_BOUNDARY_ADVANCE_MS = 5_000;
|
|
10
|
+
const QUOTA_RESET_UTILIZATION_MAX = 0.01;
|
|
8
11
|
|
|
9
12
|
export interface ProviderQuotaAdvisoryInput {
|
|
10
13
|
provider: string;
|
|
@@ -193,6 +196,30 @@ function quotaWindowKey(window: QuotaState["windows"][number]): string {
|
|
|
193
196
|
return `${window.name}:${window.unit}`;
|
|
194
197
|
}
|
|
195
198
|
|
|
199
|
+
function quotaResetBoundaryAdvanced(existing: QuotaState["windows"][number], incoming: QuotaState["windows"][number]): boolean {
|
|
200
|
+
return quotaResetBoundaryMoved(existing, incoming)
|
|
201
|
+
&& incoming.resetsAt! - existing.resetsAt! > QUOTA_RESET_BOUNDARY_ADVANCE_MS;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function quotaResetBoundaryMoved(existing: QuotaState["windows"][number], incoming: QuotaState["windows"][number]): boolean {
|
|
205
|
+
return typeof existing.resetsAt === "number"
|
|
206
|
+
&& Number.isFinite(existing.resetsAt)
|
|
207
|
+
&& typeof incoming.resetsAt === "number"
|
|
208
|
+
&& Number.isFinite(incoming.resetsAt)
|
|
209
|
+
&& incoming.resetsAt > existing.resetsAt;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function quotaWindowLooksReset(existing: QuotaState["windows"][number], incoming: QuotaState["windows"][number]): boolean {
|
|
213
|
+
return incoming.utilization <= QUOTA_RESET_UTILIZATION_MAX
|
|
214
|
+
&& quotaResetBoundaryMoved(existing, incoming);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function quotaWindowUtilizationRegressed(existing: QuotaState["windows"][number], incoming: QuotaState["windows"][number]): boolean {
|
|
218
|
+
return incoming.utilization + QUOTA_UTILIZATION_EPSILON < existing.utilization
|
|
219
|
+
&& !quotaResetBoundaryAdvanced(existing, incoming)
|
|
220
|
+
&& !quotaWindowLooksReset(existing, incoming);
|
|
221
|
+
}
|
|
222
|
+
|
|
196
223
|
function publicQuotaState(quota: StoredQuotaState): QuotaState {
|
|
197
224
|
return {
|
|
198
225
|
windows: quota.windows.map((window) => ({ ...window })),
|
|
@@ -283,6 +310,10 @@ function mergeQuotaWindows(existing: StoredQuotaState | undefined, incoming: Quo
|
|
|
283
310
|
mergedTimes.set(key, existingUpdatedAt);
|
|
284
311
|
return window;
|
|
285
312
|
}
|
|
313
|
+
if (quotaWindowUtilizationRegressed(window, incomingWindow)) {
|
|
314
|
+
mergedTimes.set(key, existingUpdatedAt);
|
|
315
|
+
return window;
|
|
316
|
+
}
|
|
286
317
|
acceptedIncomingWindow = true;
|
|
287
318
|
updatedAt = Math.max(updatedAt, incoming.updatedAt);
|
|
288
319
|
source = incoming.source;
|
|
@@ -427,7 +458,7 @@ export function upsertProviderQuota(input: ProviderQuotaUpdateInput, now = Date.
|
|
|
427
458
|
provider,
|
|
428
459
|
accountKey,
|
|
429
460
|
previousQuota: existingQuota ? publicQuotaState(existingQuota) : undefined,
|
|
430
|
-
quota:
|
|
461
|
+
quota: publicQuotaState(mergedQuota.quota),
|
|
431
462
|
sourceAgentIds,
|
|
432
463
|
previousAdvisoryState: existing?.quota_advisory_state,
|
|
433
464
|
now,
|
package/src/quota-advisory.ts
CHANGED
|
@@ -32,6 +32,7 @@ type AgentRecipientRow = {
|
|
|
32
32
|
|
|
33
33
|
const RESET_ROUNDING_PERCENT = 99;
|
|
34
34
|
const QUOTA_THRESHOLD_EPSILON = 1e-9;
|
|
35
|
+
const QUOTA_RESET_BOUNDARY_ADVANCE_MS = 5_000;
|
|
35
36
|
|
|
36
37
|
export function installQuotaAdvisoryHandler(): void {
|
|
37
38
|
setProviderQuotaAdvisoryHandler(handleProviderQuotaAdvisory);
|
|
@@ -46,7 +47,7 @@ function handleProviderQuotaAdvisory(input: ProviderQuotaAdvisoryInput): string
|
|
|
46
47
|
const previousWindow = input.previousQuota?.windows.find((candidate) => candidate.name === window.name);
|
|
47
48
|
const remaining = quotaRemaining(window.utilization);
|
|
48
49
|
const remainingPercent = percent(remaining);
|
|
49
|
-
|
|
50
|
+
let previous = nextState[window.name];
|
|
50
51
|
const reset = hasLastQuotaAdvisory(previous) && isQuotaReset(remaining, previousWindow, window, config.resetRemaining);
|
|
51
52
|
if (reset) {
|
|
52
53
|
notifyQuotaAdvisory({
|
|
@@ -65,8 +66,12 @@ function handleProviderQuotaAdvisory(input: ProviderQuotaAdvisoryInput): string
|
|
|
65
66
|
continue;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
if (previous && hasLastQuotaAdvisory(previous) && quotaAdvisoryResetBoundaryAdvanced(previous, window)) {
|
|
70
|
+
delete nextState[window.name];
|
|
71
|
+
previous = undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
68
74
|
if (remaining - config.warnRemaining > QUOTA_THRESHOLD_EPSILON) {
|
|
69
|
-
if (previous) delete nextState[window.name];
|
|
70
75
|
continue;
|
|
71
76
|
}
|
|
72
77
|
|
|
@@ -101,6 +106,17 @@ function hasLastQuotaAdvisory(previous: QuotaAdvisoryWindowState | undefined): b
|
|
|
101
106
|
return previous?.lastQuotaAdvisoryStage !== undefined || previous?.lastQuotaAdvisoryBand !== undefined;
|
|
102
107
|
}
|
|
103
108
|
|
|
109
|
+
function quotaAdvisoryResetBoundaryAdvanced(
|
|
110
|
+
previous: QuotaAdvisoryWindowState,
|
|
111
|
+
window: QuotaState["windows"][number],
|
|
112
|
+
): boolean {
|
|
113
|
+
return typeof previous.lastResetsAt === "number"
|
|
114
|
+
&& Number.isFinite(previous.lastResetsAt)
|
|
115
|
+
&& typeof window.resetsAt === "number"
|
|
116
|
+
&& Number.isFinite(window.resetsAt)
|
|
117
|
+
&& window.resetsAt - previous.lastResetsAt > QUOTA_RESET_BOUNDARY_ADVANCE_MS;
|
|
118
|
+
}
|
|
119
|
+
|
|
104
120
|
function lastQuotaAdvisoryStage(
|
|
105
121
|
previous: QuotaAdvisoryWindowState | undefined,
|
|
106
122
|
criticalRemaining: number,
|