agent-shim 8.30.0 → 8.32.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/cli.cjs +151 -19
- package/dist/index.cjs +150 -13
- package/dist/index.mjs +143 -13
- package/dist/types/index.d.ts +125 -4
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -61796,7 +61796,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
61796
61796
|
// package.json
|
|
61797
61797
|
var package_default = {
|
|
61798
61798
|
name: "agent-shim",
|
|
61799
|
-
version: "8.
|
|
61799
|
+
version: "8.32.0",
|
|
61800
61800
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
61801
61801
|
license: "MIT",
|
|
61802
61802
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -62775,10 +62775,10 @@ function windowBlockedUntil(windows) {
|
|
|
62775
62775
|
const resets = windows.flatMap((window) => window.status === "rejected" && window.resetsAtMs !== void 0 ? [window.resetsAtMs] : []);
|
|
62776
62776
|
return resets.length === 0 ? void 0 : Math.max(...resets);
|
|
62777
62777
|
}
|
|
62778
|
-
function
|
|
62778
|
+
function windowBurn(records, which) {
|
|
62779
62779
|
const points = [];
|
|
62780
62780
|
for (const record2 of records) {
|
|
62781
|
-
const window = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders)?.
|
|
62781
|
+
const window = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders)?.[which];
|
|
62782
62782
|
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
62783
62783
|
points.push({ resetsAt: window.resetsAt, point: { atMs: Date.parse(record2.at), utilization: window.utilization } });
|
|
62784
62784
|
}
|
|
@@ -62872,11 +62872,16 @@ function assessIdentity(member, nowMs) {
|
|
|
62872
62872
|
const score = remaining * plan.capacity / (untilResetMs / MS_PER_HOUR);
|
|
62873
62873
|
const fiveRemaining = five?.utilization === void 0 ? void 0 : Math.max(0, 1 - five.utilization);
|
|
62874
62874
|
const fiveUntil = five?.resetsAtMs === void 0 ? FIVE_HOUR_WINDOW_MS : Math.max(five.resetsAtMs - nowMs, MS_PER_SECOND3);
|
|
62875
|
-
const burn =
|
|
62875
|
+
const burn = windowBurn(member.records, "fiveHour");
|
|
62876
|
+
const sevenRemaining = seven?.utilization === void 0 ? void 0 : Math.max(0, 1 - seven.utilization);
|
|
62877
|
+
const sevenUntil = seven?.resetsAtMs === void 0 ? SEVEN_DAY_WINDOW_MS : Math.max(seven.resetsAtMs - nowMs, MS_PER_SECOND3);
|
|
62878
|
+
const sevenDayBurn = windowBurn(member.records, "sevenDay");
|
|
62876
62879
|
return {
|
|
62877
62880
|
candidate: { ...base, class: "scored", score, reasons: [...windowReasons.map((reason, index) => index === windowReasons.length - 1 ? `${reason}${observedAgo}` : reason), ...planReasons] },
|
|
62878
62881
|
...fiveRemaining === void 0 ? {} : { fiveHour: { remaining: fiveRemaining, untilResetMs: fiveUntil } },
|
|
62879
|
-
...burn === void 0 ? {} : { burn }
|
|
62882
|
+
...burn === void 0 ? {} : { burn },
|
|
62883
|
+
...sevenRemaining === void 0 ? {} : { sevenDay: { remaining: sevenRemaining, untilResetMs: sevenUntil } },
|
|
62884
|
+
...sevenDayBurn === void 0 ? {} : { sevenDayBurn }
|
|
62880
62885
|
};
|
|
62881
62886
|
}
|
|
62882
62887
|
function rankPool(input2) {
|
|
@@ -62887,14 +62892,27 @@ function rankPool(input2) {
|
|
|
62887
62892
|
const candidates = assessments.map((assessment) => {
|
|
62888
62893
|
const { candidate, fiveHour, burn } = assessment;
|
|
62889
62894
|
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
62890
|
-
|
|
62895
|
+
const { sevenDay, sevenDayBurn } = assessment;
|
|
62896
|
+
if (candidate.class !== "scored") {
|
|
62891
62897
|
return { ...candidate, feasible: true };
|
|
62892
62898
|
}
|
|
62893
|
-
const
|
|
62894
|
-
if (
|
|
62899
|
+
const drySpots = [];
|
|
62900
|
+
if (fiveHour !== void 0 && pace !== void 0) {
|
|
62901
|
+
const runsDryInMs = fiveHour.remaining / pace;
|
|
62902
|
+
if (runsDryInMs < fiveHour.untilResetMs) {
|
|
62903
|
+
drySpots.push(`5h window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(fiveHour.untilResetMs)}`);
|
|
62904
|
+
}
|
|
62905
|
+
}
|
|
62906
|
+
if (sevenDay !== void 0 && sevenDayBurn !== void 0) {
|
|
62907
|
+
const runsDryInMs = sevenDay.remaining / sevenDayBurn;
|
|
62908
|
+
if (runsDryInMs < sevenDay.untilResetMs) {
|
|
62909
|
+
drySpots.push(`7d window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(sevenDay.untilResetMs)}`);
|
|
62910
|
+
}
|
|
62911
|
+
}
|
|
62912
|
+
if (drySpots.length === 0) {
|
|
62895
62913
|
return { ...candidate, feasible: true };
|
|
62896
62914
|
}
|
|
62897
|
-
return { ...candidate, feasible: false, reasons: [
|
|
62915
|
+
return { ...candidate, feasible: false, reasons: [...drySpots, ...candidate.reasons] };
|
|
62898
62916
|
});
|
|
62899
62917
|
const ordered = input2.preference === "listed" ? [...candidates] : [...candidates].sort(
|
|
62900
62918
|
(left, right) => CLASS_ORDER[left.class] - CLASS_ORDER[right.class] || Number(right.feasible) - Number(left.feasible) || (right.score ?? 0) - (left.score ?? 0) || left.identity.localeCompare(right.identity)
|
|
@@ -62902,7 +62920,8 @@ function rankPool(input2) {
|
|
|
62902
62920
|
const sticky = input2.sticky;
|
|
62903
62921
|
const stickyIndex = sticky === void 0 ? -1 : ordered.findIndex((candidate) => candidate.identity === sticky.identity);
|
|
62904
62922
|
const stickyCandidate = ordered[stickyIndex];
|
|
62905
|
-
|
|
62923
|
+
const keepSticky = stickyCandidate?.class === "scored" && stickyCandidate.feasible;
|
|
62924
|
+
if (sticky !== void 0 && keepSticky) {
|
|
62906
62925
|
const ageMs = nowMs - Date.parse(sticky.at);
|
|
62907
62926
|
const warm = ageMs <= PROMPT_CACHE_TTL_MS;
|
|
62908
62927
|
if (input2.resuming || warm) {
|
|
@@ -62911,12 +62930,14 @@ function rankPool(input2) {
|
|
|
62911
62930
|
ordered.unshift({ ...stickyCandidate, reasons: [why, ...stickyCandidate.reasons] });
|
|
62912
62931
|
}
|
|
62913
62932
|
}
|
|
62933
|
+
const movedOff = sticky !== void 0 && input2.resuming && !keepSticky ? { identity: sticky.identity, reason: stickyCandidate?.reasons[0] ?? "no longer among the pool's members" } : void 0;
|
|
62914
62934
|
const pick2 = ordered.find((candidate) => candidate.class !== "ineligible");
|
|
62915
62935
|
const returns = ordered.flatMap((candidate) => candidate.blockedUntilMs === void 0 ? [] : [{ identity: candidate.identity, atMs: candidate.blockedUntilMs }]);
|
|
62916
62936
|
const earliestReturn = returns.length === 0 ? void 0 : returns.reduce((soonest, entry) => entry.atMs < soonest.atMs ? entry : soonest);
|
|
62917
62937
|
return {
|
|
62918
62938
|
candidates: ordered,
|
|
62919
|
-
...pick2 === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick: pick2 }
|
|
62939
|
+
...pick2 === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick: pick2 },
|
|
62940
|
+
...movedOff === void 0 || pick2 === void 0 ? {} : { movedOff }
|
|
62920
62941
|
};
|
|
62921
62942
|
}
|
|
62922
62943
|
|
|
@@ -63150,6 +63171,7 @@ function createUsageStore(deps) {
|
|
|
63150
63171
|
fs20.mkdirPrivate(paths.usageSnapshotsDir);
|
|
63151
63172
|
fs20.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
63152
63173
|
`);
|
|
63174
|
+
deps.publish?.(snapshot);
|
|
63153
63175
|
return true;
|
|
63154
63176
|
};
|
|
63155
63177
|
return {
|
|
@@ -63331,6 +63353,7 @@ function collectPoolPick(params) {
|
|
|
63331
63353
|
candidates: ranking.candidates.map(candidateView),
|
|
63332
63354
|
missing: missing.map(({ identity }) => identity),
|
|
63333
63355
|
...ranking.earliestReturn === void 0 ? {} : { earliestReturn: { identity: ranking.earliestReturn.identity, at: new Date(ranking.earliestReturn.atMs).toISOString() } },
|
|
63356
|
+
...ranking.movedOff === void 0 ? {} : { movedOff: ranking.movedOff },
|
|
63334
63357
|
...sticky.problem === void 0 ? {} : { stickyProblem: sticky.problem }
|
|
63335
63358
|
};
|
|
63336
63359
|
}
|
|
@@ -65682,6 +65705,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65682
65705
|
try {
|
|
65683
65706
|
http8 = await ports.startProviderListener(lastPort);
|
|
65684
65707
|
} catch (error62) {
|
|
65708
|
+
ports.doorHealth.listenerFailed("provider", error62 instanceof Error ? error62.message : String(error62));
|
|
65685
65709
|
return fail(`could not start the provider listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65686
65710
|
}
|
|
65687
65711
|
if (previousSticky !== void 0 && http8.port !== previousSticky) {
|
|
@@ -65694,6 +65718,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65694
65718
|
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
65695
65719
|
} catch (error62) {
|
|
65696
65720
|
await http8.close();
|
|
65721
|
+
ports.doorHealth.listenerFailed("connect", error62 instanceof Error ? error62.message : String(error62));
|
|
65697
65722
|
return fail(`could not start the CONNECT surface: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65698
65723
|
}
|
|
65699
65724
|
if (previousStickyConnect !== void 0 && connect3.port !== previousStickyConnect) {
|
|
@@ -65707,6 +65732,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65707
65732
|
} catch (error62) {
|
|
65708
65733
|
await connect3.close();
|
|
65709
65734
|
await http8.close();
|
|
65735
|
+
ports.doorHealth.listenerFailed("direct", error62 instanceof Error ? error62.message : String(error62));
|
|
65710
65736
|
return fail(`could not start the direct listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
65711
65737
|
}
|
|
65712
65738
|
if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
|
|
@@ -65714,6 +65740,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65714
65740
|
}
|
|
65715
65741
|
lastDirectPort = direct.port;
|
|
65716
65742
|
writeFrontDoorState(fs20, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http8.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
65743
|
+
ports.doorHealth.generation({ providerPort: http8.port, connectPort: connect3.port, directPort: direct.port });
|
|
65717
65744
|
fs20.removeRecursive(paths.frontdoorLockFile);
|
|
65718
65745
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http8.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
65719
65746
|
let idleSince;
|
|
@@ -65726,11 +65753,13 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
65726
65753
|
const listed = listFrontDoorSessions(fs20, paths.frontdoorSessionsDir);
|
|
65727
65754
|
const pruned = pruneDeadFrontDoorSessions(fs20, paths.frontdoorSessionsDir, ports.isRunning);
|
|
65728
65755
|
ports.observeLaunchRegistry(listed, pruned);
|
|
65756
|
+
ports.checkQuotaExpiry();
|
|
65729
65757
|
const prunedPids = new Set(pruned);
|
|
65730
65758
|
if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
|
|
65731
65759
|
idleSince ??= ports.now();
|
|
65732
65760
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
65733
65761
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
65762
|
+
ports.doorHealth.idleShutdown();
|
|
65734
65763
|
await direct.close();
|
|
65735
65764
|
await connect3.close();
|
|
65736
65765
|
await http8.close();
|
|
@@ -69604,6 +69633,8 @@ var PoolPickReportSchema = external_exports.strictObject({
|
|
|
69604
69633
|
missing: external_exports.array(external_exports.string()),
|
|
69605
69634
|
/** When nothing can be picked, the soonest any member returns. */
|
|
69606
69635
|
earliestReturn: external_exports.strictObject({ identity: external_exports.string(), at: external_exports.iso.datetime() }).optional(),
|
|
69636
|
+
/** The member a resumed conversation started on but moved off, and why, when the ranking could not keep it. */
|
|
69637
|
+
movedOff: external_exports.strictObject({ identity: external_exports.string(), reason: external_exports.string() }).optional(),
|
|
69607
69638
|
/** Why the last-pick record could not be read, when that is the case. */
|
|
69608
69639
|
stickyProblem: external_exports.string().optional()
|
|
69609
69640
|
});
|
|
@@ -73910,6 +73941,9 @@ function frontDoorRcApiClient(port, ca, token) {
|
|
|
73910
73941
|
// src/frontdoor/eventSchemas.ts
|
|
73911
73942
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
73912
73943
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
73944
|
+
var USAGE_EVENT_SOURCE = "usage";
|
|
73945
|
+
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
73946
|
+
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
73913
73947
|
var DoorEventSchema = external_exports.strictObject({
|
|
73914
73948
|
source: external_exports.string().min(1),
|
|
73915
73949
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
@@ -73925,6 +73959,20 @@ var LaunchLifecycleEventSchema = external_exports.strictObject({
|
|
|
73925
73959
|
startedAt: external_exports.number(),
|
|
73926
73960
|
observedAt: external_exports.number()
|
|
73927
73961
|
});
|
|
73962
|
+
var DoorHealthEventSchema = external_exports.discriminatedUnion("kind", [
|
|
73963
|
+
external_exports.strictObject({ kind: external_exports.literal("generation"), pid: external_exports.number().int().positive(), providerPort: external_exports.number().int().positive(), connectPort: external_exports.number().int().positive(), directPort: external_exports.number().int().positive(), observedAt: external_exports.number() }),
|
|
73964
|
+
external_exports.strictObject({ kind: external_exports.literal("listenerFailed"), pid: external_exports.number().int().positive(), listener: external_exports.enum(["provider", "connect", "direct"]), message: external_exports.string(), observedAt: external_exports.number() }),
|
|
73965
|
+
external_exports.strictObject({ kind: external_exports.literal("idleShutdown"), pid: external_exports.number().int().positive(), observedAt: external_exports.number() })
|
|
73966
|
+
]);
|
|
73967
|
+
var QuotaExpiringEventSchema = external_exports.strictObject({
|
|
73968
|
+
identity: external_exports.string().min(1),
|
|
73969
|
+
provider: external_exports.string().min(1),
|
|
73970
|
+
window: external_exports.enum(["fiveHour", "sevenDay"]),
|
|
73971
|
+
/** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
|
|
73972
|
+
utilization: external_exports.number().min(0).max(1),
|
|
73973
|
+
resetsAt: external_exports.iso.datetime(),
|
|
73974
|
+
observedAt: external_exports.number()
|
|
73975
|
+
});
|
|
73928
73976
|
|
|
73929
73977
|
// src/frontdoor/eventsApi.ts
|
|
73930
73978
|
var EVENTS_API_TAG = "events";
|
|
@@ -74035,6 +74083,22 @@ function createDoorApiNodeHandler(deps) {
|
|
|
74035
74083
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
74036
74084
|
}
|
|
74037
74085
|
|
|
74086
|
+
// src/frontdoor/doorHealthEvents.ts
|
|
74087
|
+
function createDoorHealthPublisher(hub, now, pid) {
|
|
74088
|
+
const publisher = hub.publisher(DOOR_HEALTH_EVENT_SOURCE);
|
|
74089
|
+
return {
|
|
74090
|
+
generation: (ports) => {
|
|
74091
|
+
publisher.publish({ kind: "generation", pid, providerPort: ports.providerPort, connectPort: ports.connectPort, directPort: ports.directPort, observedAt: now() });
|
|
74092
|
+
},
|
|
74093
|
+
listenerFailed: (listener, message) => {
|
|
74094
|
+
publisher.publish({ kind: "listenerFailed", pid, listener, message, observedAt: now() });
|
|
74095
|
+
},
|
|
74096
|
+
idleShutdown: () => {
|
|
74097
|
+
publisher.publish({ kind: "idleShutdown", pid, observedAt: now() });
|
|
74098
|
+
}
|
|
74099
|
+
};
|
|
74100
|
+
}
|
|
74101
|
+
|
|
74038
74102
|
// src/frontdoor/eventHub.ts
|
|
74039
74103
|
var DOOR_EVENT_BUFFER_EVENTS = 100;
|
|
74040
74104
|
function createDoorEventHub() {
|
|
@@ -74141,6 +74205,65 @@ function rcFanoutOnDoorHub(fanout, hub) {
|
|
|
74141
74205
|
};
|
|
74142
74206
|
}
|
|
74143
74207
|
|
|
74208
|
+
// src/frontdoor/quotaExpiringEvents.ts
|
|
74209
|
+
var MS_PER_HOUR2 = 36e5;
|
|
74210
|
+
var MS_PER_DAY2 = 864e5;
|
|
74211
|
+
var FIVE_HOUR_WINDOW_HOURS = 5;
|
|
74212
|
+
var SEVEN_DAY_WINDOW_DAYS = 7;
|
|
74213
|
+
var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR2;
|
|
74214
|
+
var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY2;
|
|
74215
|
+
var FINAL_SPAN_DENOMINATOR = 30;
|
|
74216
|
+
var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
|
|
74217
|
+
function createQuotaExpiringPublisher(hub, deps) {
|
|
74218
|
+
const publisher = hub.publisher(QUOTA_EXPIRING_EVENT_SOURCE);
|
|
74219
|
+
const latest = /* @__PURE__ */ new Map();
|
|
74220
|
+
for (const snapshot of deps.seed) {
|
|
74221
|
+
latest.set(snapshot.identity, snapshot);
|
|
74222
|
+
}
|
|
74223
|
+
hub.subscribe([USAGE_EVENT_SOURCE], (event) => {
|
|
74224
|
+
const snapshot = UsageSnapshotSchema.parse(event.payload);
|
|
74225
|
+
latest.set(snapshot.identity, snapshot);
|
|
74226
|
+
});
|
|
74227
|
+
const announced = /* @__PURE__ */ new Set();
|
|
74228
|
+
const windowsOf = (snapshot) => {
|
|
74229
|
+
const views = [];
|
|
74230
|
+
for (const provider of Object.keys(snapshot.providers).sort()) {
|
|
74231
|
+
const unified = snapshot.providers[provider]?.rateLimit?.unified;
|
|
74232
|
+
const fiveHour = unified?.fiveHour;
|
|
74233
|
+
if (fiveHour?.utilization !== void 0 && fiveHour.resetsAt !== void 0) {
|
|
74234
|
+
views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS2, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
|
|
74235
|
+
}
|
|
74236
|
+
const sevenDay = unified?.sevenDay;
|
|
74237
|
+
if (sevenDay?.utilization !== void 0 && sevenDay.resetsAt !== void 0) {
|
|
74238
|
+
views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS2, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
|
|
74239
|
+
}
|
|
74240
|
+
}
|
|
74241
|
+
return views;
|
|
74242
|
+
};
|
|
74243
|
+
return {
|
|
74244
|
+
check: () => {
|
|
74245
|
+
const now = deps.now();
|
|
74246
|
+
for (const identity of [...latest.keys()].sort()) {
|
|
74247
|
+
const snapshot = latest.get(identity);
|
|
74248
|
+
if (snapshot === void 0) {
|
|
74249
|
+
continue;
|
|
74250
|
+
}
|
|
74251
|
+
for (const { provider, view } of windowsOf(snapshot)) {
|
|
74252
|
+
if (view.utilization >= 1 || view.resetsAtMs <= now || view.resetsAtMs - now >= view.spanMs * QUOTA_EXPIRING_WINDOW_FRACTION) {
|
|
74253
|
+
continue;
|
|
74254
|
+
}
|
|
74255
|
+
const key = `${identity}:${provider}:${view.window}:${String(view.resetsAtMs)}`;
|
|
74256
|
+
if (announced.has(key)) {
|
|
74257
|
+
continue;
|
|
74258
|
+
}
|
|
74259
|
+
announced.add(key);
|
|
74260
|
+
publisher.publish({ identity, provider, window: view.window, utilization: view.utilization, resetsAt: new Date(view.resetsAtMs).toISOString(), observedAt: now });
|
|
74261
|
+
}
|
|
74262
|
+
}
|
|
74263
|
+
}
|
|
74264
|
+
};
|
|
74265
|
+
}
|
|
74266
|
+
|
|
74144
74267
|
// src/frontdoor/launchEvents.ts
|
|
74145
74268
|
function createLaunchEventPublisher(hub, now) {
|
|
74146
74269
|
const publisher = hub.publisher(LAUNCH_EVENT_SOURCE);
|
|
@@ -78277,7 +78400,7 @@ var OPENROUTER_HOST = "openrouter.ai";
|
|
|
78277
78400
|
var OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
78278
78401
|
var OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
78279
78402
|
var HTTP_FORBIDDEN = 403;
|
|
78280
|
-
var
|
|
78403
|
+
var MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND10;
|
|
78281
78404
|
var OpenRouterKeySchema = external_exports.object({
|
|
78282
78405
|
data: external_exports.object({
|
|
78283
78406
|
limit: external_exports.number().nonnegative().nullable(),
|
|
@@ -78309,7 +78432,7 @@ async function openRouterGet(url2, schema, apiKey, http8, signal) {
|
|
|
78309
78432
|
return parsed.data;
|
|
78310
78433
|
}
|
|
78311
78434
|
function nextUtcMidnight(nowMs) {
|
|
78312
|
-
return new Date((Math.floor(nowMs /
|
|
78435
|
+
return new Date((Math.floor(nowMs / MS_PER_DAY3) + 1) * MS_PER_DAY3).toISOString();
|
|
78313
78436
|
}
|
|
78314
78437
|
var openRouterQuotaAdapter = {
|
|
78315
78438
|
source: OPENROUTER_SOURCE,
|
|
@@ -78331,7 +78454,7 @@ var openRouterQuotaAdapter = {
|
|
|
78331
78454
|
windows.push({ measures: "account-credits", period: "prepaid", utilization: used / total, limit: total, used, remaining: Math.max(total - used, 0) });
|
|
78332
78455
|
}
|
|
78333
78456
|
if (free !== void 0 && free.limit > 0) {
|
|
78334
|
-
windows.push({ measures: "free-model-requests", periodMs:
|
|
78457
|
+
windows.push({ measures: "free-model-requests", periodMs: MS_PER_DAY3, utilization: free.used / free.limit, resetsAt: nextUtcMidnight(nowMs), limit: free.limit, used: free.used, remaining: Math.max(free.remaining, 0) });
|
|
78335
78458
|
}
|
|
78336
78459
|
return ProviderQuotaSchema.parse({
|
|
78337
78460
|
observedAt: new Date(nowMs).toISOString(),
|
|
@@ -78520,6 +78643,9 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78520
78643
|
const rcCredentialStore = createRcCredentialStore(realFarmFs, paths.frontdoorRcCredentialsDir);
|
|
78521
78644
|
const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS, credentialStore: rcCredentialStore });
|
|
78522
78645
|
const doorEvents = createDoorEventHub();
|
|
78646
|
+
const usagePublisher = doorEvents.publisher(USAGE_EVENT_SOURCE);
|
|
78647
|
+
const quotaExpiring = createQuotaExpiringPublisher(doorEvents, { seed: listUsageSnapshots(realFarmFs, paths.usageSnapshotsDir), now: () => Date.now() });
|
|
78648
|
+
const doorHealth = createDoorHealthPublisher(doorEvents, () => Date.now(), process.pid);
|
|
78523
78649
|
const rcLiveUsage = createRcLiveUsage({ now: () => Date.now(), hub: doorEvents });
|
|
78524
78650
|
const rcFanout = rcFanoutOnDoorHub(createRcEventFanout(), doorEvents);
|
|
78525
78651
|
const rcHub = createRcStreamHub({
|
|
@@ -78565,7 +78691,10 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78565
78691
|
pid: process.pid,
|
|
78566
78692
|
now: () => Date.now(),
|
|
78567
78693
|
readAccount: createAccountReader(realFarmFs, paths.identitiesDir),
|
|
78568
|
-
log
|
|
78694
|
+
log,
|
|
78695
|
+
publish: (snapshot) => {
|
|
78696
|
+
usagePublisher.publish(snapshot);
|
|
78697
|
+
}
|
|
78569
78698
|
});
|
|
78570
78699
|
const quotaRefresher = createRealQuotaRefresher({ paths, store: usageStore, log });
|
|
78571
78700
|
const usageMiddleware = createUsageMiddleware({
|
|
@@ -78764,6 +78893,8 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
78764
78893
|
closeRcStreamHub: rcHub.close,
|
|
78765
78894
|
// The launch lifecycle publisher over the same backbone the typed API serves: the tick's registry facts go in here, and the door's own register, prune and end moments come out as source-tagged events.
|
|
78766
78895
|
observeLaunchRegistry: createLaunchEventPublisher(doorEvents, () => Date.now()).observe,
|
|
78896
|
+
doorHealth,
|
|
78897
|
+
checkQuotaExpiry: quotaExpiring.check,
|
|
78767
78898
|
log: (line) => {
|
|
78768
78899
|
appendLog(paths, line);
|
|
78769
78900
|
}
|
|
@@ -80582,13 +80713,13 @@ function formatLimit(limit) {
|
|
|
80582
80713
|
return `last limit: ${limit.kind} (${String(limit.status)}) at ${limit.observedAt}${limit.window === void 0 ? "" : ` on the ${limit.window} window`}${wait.length === 0 ? "" : `, ${wait.join(", ")}`}`;
|
|
80583
80714
|
}
|
|
80584
80715
|
var MONEY_DECIMALS = 2;
|
|
80585
|
-
var
|
|
80716
|
+
var MS_PER_HOUR3 = 36e5;
|
|
80586
80717
|
var HOURS_PER_DAY4 = 24;
|
|
80587
80718
|
function formatPeriod(window) {
|
|
80588
80719
|
if (window.periodMs === void 0) {
|
|
80589
80720
|
return window.period ?? "unknown period";
|
|
80590
80721
|
}
|
|
80591
|
-
const hours = window.periodMs /
|
|
80722
|
+
const hours = window.periodMs / MS_PER_HOUR3;
|
|
80592
80723
|
return hours >= HOURS_PER_DAY4 && Number.isInteger(hours / HOURS_PER_DAY4) ? `${String(hours / HOURS_PER_DAY4)}d` : `${String(hours)}h`;
|
|
80593
80724
|
}
|
|
80594
80725
|
function formatCount(value2) {
|
|
@@ -81080,10 +81211,11 @@ function resolvePoolLaunch(params) {
|
|
|
81080
81211
|
if (graph.ranking.candidates.length === 0) {
|
|
81081
81212
|
return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
|
|
81082
81213
|
}
|
|
81083
|
-
const { pick: pick2, earliestReturn } = graph.ranking;
|
|
81214
|
+
const { pick: pick2, earliestReturn, movedOff } = graph.ranking;
|
|
81084
81215
|
if (pick2 !== void 0) {
|
|
81085
81216
|
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick2.identity, nowMs);
|
|
81086
|
-
|
|
81217
|
+
const move = movedOff === void 0 ? "" : `moved off ${movedOff.identity} (${movedOff.reason}); `;
|
|
81218
|
+
return { ok: true, identity: pick2.identity, explanation: `pool ${poolName}: ${move}${pick2.reasons.slice(0, REASONS_LOGGED).join("; ")}` };
|
|
81087
81219
|
}
|
|
81088
81220
|
if (earliestReturn === void 0) {
|
|
81089
81221
|
return { ok: false, message: `agent-shim: no member of pool "${poolName}" can be picked.` };
|