Skip to content

Commit 108d0d5

Browse files
fix(usage): skip Devin quota reads when disabled and harden merge
Disabled Devin instances no longer read credentials or call GetUserStatus. Out-of-range reset timestamps no longer crash the provider check, and account dedup keeps an icon reported by a later environment. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 35d0acb commit 108d0d5

5 files changed

Lines changed: 37 additions & 2 deletions

File tree

‎packages/provider-acp-registry/src/server/devinUsageLimits.test.ts‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,35 @@ describe("readDevinUsageLimits", () => {
109109
},
110110
],
111111
},
112+
{
113+
name: "reports the daily window without a reset when its timestamp is out of range",
114+
planStatus: {
115+
planInfo: {
116+
billingStrategy: "BILLING_STRATEGY_QUOTA",
117+
devinInfo: { webappHost: "app.devin.ai" },
118+
},
119+
weeklyQuotaRemainingPercent: 50,
120+
dailyQuotaResetAtUnix: "99999999999999",
121+
weeklyQuotaResetAtUnix: "1794124800",
122+
},
123+
expectedWindows: [
124+
{
125+
id: "devin_daily",
126+
kind: "session",
127+
label: "Devin · Daily",
128+
windowDurationMins: 1440,
129+
usedPercent: 100,
130+
},
131+
{
132+
id: "devin_weekly",
133+
kind: "weekly",
134+
label: "Devin · Weekly",
135+
windowDurationMins: 10080,
136+
usedPercent: 50,
137+
resetsAt: "2026-11-08T08:00:00.000Z",
138+
},
139+
],
140+
},
112141
])("$name", ({ planStatus, expectedWindows }) =>
113142
Effect.gen(function* () {
114143
const dataHome = yield* withCredentialsDir(CREDENTIALS_TOML);

‎packages/provider-acp-registry/src/server/devinUsageLimits.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as Digest from "effect/crypto/Digest";
33
import * as DateTime from "effect/DateTime";
44
import * as Effect from "effect/Effect";
55
import * as FileSystem from "effect/FileSystem";
6+
import * as Option from "effect/Option";
67
import * as Path from "effect/Path";
78
import * as Schema from "effect/Schema";
89
import * as Hex from "effect/encoding/Hex";
@@ -50,7 +51,7 @@ const GetUserStatusResponse = Schema.Struct({
5051
const resetAtIso = (value: number | string | undefined): string | undefined => {
5152
const seconds = typeof value === "string" ? Number(value) : value;
5253
return seconds !== undefined && Number.isFinite(seconds) && seconds > 0
53-
? DateTime.formatIso(DateTime.makeUnsafe(seconds * 1000))
54+
? Option.getOrUndefined(Option.map(DateTime.make(seconds * 1000), DateTime.formatIso))
5455
: undefined;
5556
};
5657

‎packages/provider-acp-registry/src/server/driver.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,9 @@ export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryD
598598
// ACP exposes no quota data; Devin is the one registry agent whose own API
599599
// reports usage limits.
600600
const checkUsageLimits =
601-
effectiveConfig.source === "registry" && effectiveConfig.agentId === "devin"
601+
effectiveConfig.enabled &&
602+
effectiveConfig.source === "registry" &&
603+
effectiveConfig.agentId === "devin"
602604
? readDevinUsageLimits({ environment: processEnvironment }).pipe(
603605
Effect.provideService(FileSystem.FileSystem, fileSystem),
604606
Effect.provideService(Path.Path, pathService),

‎packages/shared/src/usageLimits.test.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ describe("pools", () => {
297297
providers: [
298298
{
299299
...go,
300+
iconUrl: "https://example.com/opencode-go.svg",
300301
usageLimits: {
301302
...go.usageLimits!,
302303
checkedAt: "2026-09-03T11:30:00.000Z",
@@ -314,6 +315,7 @@ describe("pools", () => {
314315
{ environmentId: "env-a", label: "Laptop" },
315316
{ environmentId: "env-b", label: "Desktop" },
316317
]);
318+
expect(accounts[0]?.iconUrl).toBe("https://example.com/opencode-go.svg");
317319
expect(collectLimitPools(accounts, now)[0]?.windows[0]?.members).toHaveLength(1);
318320
expect(accounts[0]?.limits.windows[0]?.usedPercent).toBe(4);
319321

‎packages/shared/src/usageLimits.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ export function collectLimitAccounts(presentations: LimitPresentations): readonl
303303
displayName: previous.displayName ?? next.displayName,
304304
plan: planSources.get(key)?.plan ?? previous.plan ?? next.plan,
305305
accentColor: previous.accentColor ?? next.accentColor,
306+
iconUrl: previous.iconUrl ?? next.iconUrl,
306307
environments,
307308
sourceLabel: environments.length > 0 ? null : (previous.sourceLabel ?? next.sourceLabel),
308309
redeem:

0 commit comments

Comments
 (0)