@anthonyhaussman/opencode-agy-auth 1.0.11-alpha.0 → 1.0.11-alpha.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/dist/index.js +288 -54
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -212,6 +212,23 @@ async function retrieveUserQuota(accessToken, projectId, userAgentModel) {
|
|
|
212
212
|
return null;
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
+
async function retrieveUserQuotaSummary(accessToken, projectId, userAgentModel) {
|
|
216
|
+
const url2 = `${AGY_CODE_ASSIST_ENDPOINT}/v1internal:retrieveUserQuotaSummary`;
|
|
217
|
+
const headers = buildCodeAssistHeaders(accessToken, userAgentModel);
|
|
218
|
+
try {
|
|
219
|
+
const response = await agyFetch(url2, {
|
|
220
|
+
method: "POST",
|
|
221
|
+
headers,
|
|
222
|
+
body: JSON.stringify({ project: projectId })
|
|
223
|
+
});
|
|
224
|
+
if (!response.ok) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
return await response.json();
|
|
228
|
+
} catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
215
232
|
function buildCodeAssistHeaders(accessToken, userAgentModel) {
|
|
216
233
|
const userAgent = buildAgyCliUserAgent(userAgentModel);
|
|
217
234
|
return {
|
|
@@ -14142,6 +14159,62 @@ async function fetchTokenRefresh(refreshToken) {
|
|
|
14142
14159
|
return agyFetch(tokenUrl, init);
|
|
14143
14160
|
}
|
|
14144
14161
|
|
|
14162
|
+
// src/plugin/quota-utils.ts
|
|
14163
|
+
function clamp(value, min, max) {
|
|
14164
|
+
if (value < min) {
|
|
14165
|
+
return min;
|
|
14166
|
+
}
|
|
14167
|
+
if (value > max) {
|
|
14168
|
+
return max;
|
|
14169
|
+
}
|
|
14170
|
+
return value;
|
|
14171
|
+
}
|
|
14172
|
+
function pad(value, width) {
|
|
14173
|
+
if (value.length >= width) {
|
|
14174
|
+
return value;
|
|
14175
|
+
}
|
|
14176
|
+
return value.padEnd(width, " ");
|
|
14177
|
+
}
|
|
14178
|
+
function buildProgressBar(fraction, width = 20) {
|
|
14179
|
+
const clamped = clamp(fraction, 0, 1);
|
|
14180
|
+
const filled = clamped >= 1 ? width : Math.max(0, Math.min(width, Math.max(clamped > 0 ? 1 : 0, Math.floor(clamped * width))));
|
|
14181
|
+
const empty = width - filled;
|
|
14182
|
+
return `${"\u2593".repeat(filled)}${"\u2591".repeat(empty)}`;
|
|
14183
|
+
}
|
|
14184
|
+
function formatRemainingAmount(value) {
|
|
14185
|
+
if (!value) {
|
|
14186
|
+
return void 0;
|
|
14187
|
+
}
|
|
14188
|
+
const parsed = Number.parseInt(value, 10);
|
|
14189
|
+
if (!Number.isFinite(parsed)) {
|
|
14190
|
+
return value;
|
|
14191
|
+
}
|
|
14192
|
+
return parsed.toLocaleString("en-US");
|
|
14193
|
+
}
|
|
14194
|
+
function formatRelativeResetTime(resetTime) {
|
|
14195
|
+
if (!resetTime) {
|
|
14196
|
+
return void 0;
|
|
14197
|
+
}
|
|
14198
|
+
const resetAt = new Date(resetTime).getTime();
|
|
14199
|
+
if (Number.isNaN(resetAt)) {
|
|
14200
|
+
return void 0;
|
|
14201
|
+
}
|
|
14202
|
+
const diffMs = resetAt - Date.now();
|
|
14203
|
+
if (diffMs <= 0) {
|
|
14204
|
+
return "reset pending";
|
|
14205
|
+
}
|
|
14206
|
+
const totalMinutes = Math.ceil(diffMs / (1e3 * 60));
|
|
14207
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
14208
|
+
const minutes = totalMinutes % 60;
|
|
14209
|
+
if (hours > 0 && minutes > 0) {
|
|
14210
|
+
return `resets in ${hours}h ${minutes}m`;
|
|
14211
|
+
}
|
|
14212
|
+
if (hours > 0) {
|
|
14213
|
+
return `resets in ${hours}h`;
|
|
14214
|
+
}
|
|
14215
|
+
return `resets in ${minutes}m`;
|
|
14216
|
+
}
|
|
14217
|
+
|
|
14145
14218
|
// src/plugin/quota.ts
|
|
14146
14219
|
var AGY_QUOTA_TOOL_NAME = "agy_quota";
|
|
14147
14220
|
function createAgyQuotaTool({
|
|
@@ -14269,60 +14342,6 @@ function formatUsageRemaining(bucket) {
|
|
|
14269
14342
|
}
|
|
14270
14343
|
return "unknown";
|
|
14271
14344
|
}
|
|
14272
|
-
function formatRemainingAmount(value) {
|
|
14273
|
-
if (!value) {
|
|
14274
|
-
return void 0;
|
|
14275
|
-
}
|
|
14276
|
-
const parsed = Number.parseInt(value, 10);
|
|
14277
|
-
if (!Number.isFinite(parsed)) {
|
|
14278
|
-
return value;
|
|
14279
|
-
}
|
|
14280
|
-
return parsed.toLocaleString("en-US");
|
|
14281
|
-
}
|
|
14282
|
-
function formatRelativeResetTime(resetTime) {
|
|
14283
|
-
if (!resetTime) {
|
|
14284
|
-
return void 0;
|
|
14285
|
-
}
|
|
14286
|
-
const resetAt = new Date(resetTime).getTime();
|
|
14287
|
-
if (Number.isNaN(resetAt)) {
|
|
14288
|
-
return void 0;
|
|
14289
|
-
}
|
|
14290
|
-
const diffMs = resetAt - Date.now();
|
|
14291
|
-
if (diffMs <= 0) {
|
|
14292
|
-
return "reset pending";
|
|
14293
|
-
}
|
|
14294
|
-
const totalMinutes = Math.ceil(diffMs / (1e3 * 60));
|
|
14295
|
-
const hours = Math.floor(totalMinutes / 60);
|
|
14296
|
-
const minutes = totalMinutes % 60;
|
|
14297
|
-
if (hours > 0 && minutes > 0) {
|
|
14298
|
-
return `resets in ${hours}h ${minutes}m`;
|
|
14299
|
-
}
|
|
14300
|
-
if (hours > 0) {
|
|
14301
|
-
return `resets in ${hours}h`;
|
|
14302
|
-
}
|
|
14303
|
-
return `resets in ${minutes}m`;
|
|
14304
|
-
}
|
|
14305
|
-
function buildProgressBar(fraction, width = 20) {
|
|
14306
|
-
const clamped = clamp(fraction, 0, 1);
|
|
14307
|
-
const filled = clamped >= 1 ? width : Math.max(0, Math.min(width, Math.max(clamped > 0 ? 1 : 0, Math.floor(clamped * width))));
|
|
14308
|
-
const empty = width - filled;
|
|
14309
|
-
return `${"\u2593".repeat(filled)}${"\u2591".repeat(empty)}`;
|
|
14310
|
-
}
|
|
14311
|
-
function pad(value, width) {
|
|
14312
|
-
if (value.length >= width) {
|
|
14313
|
-
return value;
|
|
14314
|
-
}
|
|
14315
|
-
return value.padEnd(width, " ");
|
|
14316
|
-
}
|
|
14317
|
-
function clamp(value, min, max) {
|
|
14318
|
-
if (value < min) {
|
|
14319
|
-
return min;
|
|
14320
|
-
}
|
|
14321
|
-
if (value > max) {
|
|
14322
|
-
return max;
|
|
14323
|
-
}
|
|
14324
|
-
return value;
|
|
14325
|
-
}
|
|
14326
14345
|
function normalizeTokenType(bucket) {
|
|
14327
14346
|
const value = bucket.tokenType?.trim();
|
|
14328
14347
|
return value ? value.toUpperCase() : "REQUESTS";
|
|
@@ -14435,6 +14454,205 @@ function splitModelVariant(modelId) {
|
|
|
14435
14454
|
};
|
|
14436
14455
|
}
|
|
14437
14456
|
|
|
14457
|
+
// src/plugin/quota-summary.ts
|
|
14458
|
+
var AGY_QUOTA_SUMMARY_TOOL_NAME = "agy_quota_summary";
|
|
14459
|
+
function createAgyQuotaSummaryTool({
|
|
14460
|
+
client,
|
|
14461
|
+
getAuthResolver,
|
|
14462
|
+
getConfiguredProjectId,
|
|
14463
|
+
getUserAgentModel
|
|
14464
|
+
}) {
|
|
14465
|
+
return tool({
|
|
14466
|
+
description: "Retrieve Agy Code Assist quota summary with weekly and 5-hour limits grouped by model family.",
|
|
14467
|
+
args: {},
|
|
14468
|
+
async execute() {
|
|
14469
|
+
const getAuth = getAuthResolver();
|
|
14470
|
+
if (!getAuth) {
|
|
14471
|
+
return "Agy quota summary is unavailable before Google auth is initialized. Authenticate with the Google provider and retry.";
|
|
14472
|
+
}
|
|
14473
|
+
const auth = await getAuth();
|
|
14474
|
+
if (!isOAuthAuth(auth)) {
|
|
14475
|
+
return "Agy quota summary requires OAuth with Google. Run `opencode auth login` and choose `Google OAuth (Antigravity CLI)` or `Google OAuth (Gemini CLI)`.";
|
|
14476
|
+
}
|
|
14477
|
+
let authRecord = resolveCachedAuth(auth);
|
|
14478
|
+
if (accessTokenExpired(authRecord)) {
|
|
14479
|
+
const refreshed = await refreshAccessToken(authRecord, client);
|
|
14480
|
+
if (!refreshed?.access) {
|
|
14481
|
+
return "Agy quota summary lookup failed because the access token could not be refreshed. Re-authenticate and retry.";
|
|
14482
|
+
}
|
|
14483
|
+
authRecord = refreshed;
|
|
14484
|
+
}
|
|
14485
|
+
if (!authRecord.access) {
|
|
14486
|
+
return "Agy quota summary lookup failed because no access token is available. Re-authenticate and retry.";
|
|
14487
|
+
}
|
|
14488
|
+
try {
|
|
14489
|
+
const projectContext = await ensureProjectContext(
|
|
14490
|
+
authRecord,
|
|
14491
|
+
client,
|
|
14492
|
+
getConfiguredProjectId(),
|
|
14493
|
+
getUserAgentModel()
|
|
14494
|
+
);
|
|
14495
|
+
if (!projectContext.effectiveProjectId) {
|
|
14496
|
+
return "Agy quota summary lookup failed because no Google Cloud project could be resolved.";
|
|
14497
|
+
}
|
|
14498
|
+
const summary = await retrieveUserQuotaSummary(
|
|
14499
|
+
authRecord.access,
|
|
14500
|
+
projectContext.effectiveProjectId,
|
|
14501
|
+
getUserAgentModel()
|
|
14502
|
+
);
|
|
14503
|
+
if (!summary) {
|
|
14504
|
+
return `No Agy quota summary available for project \`${projectContext.effectiveProjectId}\`.`;
|
|
14505
|
+
}
|
|
14506
|
+
return formatAgyQuotaSummaryOutput(
|
|
14507
|
+
projectContext.effectiveProjectId,
|
|
14508
|
+
summary
|
|
14509
|
+
);
|
|
14510
|
+
} catch (error45) {
|
|
14511
|
+
const message = error45 instanceof Error ? error45.message : "unknown error";
|
|
14512
|
+
return `Agy quota summary lookup failed: ${message}`;
|
|
14513
|
+
}
|
|
14514
|
+
}
|
|
14515
|
+
});
|
|
14516
|
+
}
|
|
14517
|
+
var BAR_WIDTH = 50;
|
|
14518
|
+
function windowLabel(window) {
|
|
14519
|
+
switch (window?.toUpperCase()) {
|
|
14520
|
+
case "WEEKLY":
|
|
14521
|
+
return "Weekly Limit";
|
|
14522
|
+
case "FIVE_HOUR":
|
|
14523
|
+
return "Five Hour Limit";
|
|
14524
|
+
default:
|
|
14525
|
+
return "Other Limit";
|
|
14526
|
+
}
|
|
14527
|
+
}
|
|
14528
|
+
function formatSummaryBucket(bucket, indent) {
|
|
14529
|
+
if (bucket.disabled) {
|
|
14530
|
+
const desc = bucket.description?.trim() || "weekly limit exhausted";
|
|
14531
|
+
return [`${indent}Disabled: ${desc}`];
|
|
14532
|
+
}
|
|
14533
|
+
const lines = [];
|
|
14534
|
+
const fraction = bucket.remainingFraction;
|
|
14535
|
+
const hasFraction = typeof fraction === "number" && Number.isFinite(fraction);
|
|
14536
|
+
if (hasFraction) {
|
|
14537
|
+
const clamped = clamp(fraction, 0, 1);
|
|
14538
|
+
const percent = (clamped * 100).toFixed(2);
|
|
14539
|
+
const bar = buildProgressBar(clamped, BAR_WIDTH);
|
|
14540
|
+
lines.push(`${indent}[${bar}] ${percent}%`);
|
|
14541
|
+
const remaining = formatRemainingAmount(bucket.remainingAmount);
|
|
14542
|
+
if (remaining) {
|
|
14543
|
+
const pctWhole = (clamped * 100).toFixed(0);
|
|
14544
|
+
lines.push(`${indent}${pctWhole}% remaining \xB7 ${remaining} left`);
|
|
14545
|
+
} else {
|
|
14546
|
+
const pctWhole = (clamped * 100).toFixed(0);
|
|
14547
|
+
lines.push(`${indent}${pctWhole}% remaining`);
|
|
14548
|
+
}
|
|
14549
|
+
} else {
|
|
14550
|
+
const remaining = formatRemainingAmount(bucket.remainingAmount);
|
|
14551
|
+
lines.push(remaining ? `${indent}${remaining} remaining` : `${indent}unknown remaining`);
|
|
14552
|
+
}
|
|
14553
|
+
const resetLabel = formatRelativeResetTime(bucket.resetTime);
|
|
14554
|
+
if (resetLabel) {
|
|
14555
|
+
lines.push(`${indent}${resetLabel.replace("resets in ", "Refreshes in ")}`);
|
|
14556
|
+
}
|
|
14557
|
+
return lines;
|
|
14558
|
+
}
|
|
14559
|
+
function groupBucketsByWindow(buckets) {
|
|
14560
|
+
const groups = /* @__PURE__ */ new Map();
|
|
14561
|
+
const order = ["WEEKLY", "FIVE_HOUR"];
|
|
14562
|
+
for (const bucket of buckets) {
|
|
14563
|
+
const key = bucket.window?.toUpperCase() || "UNKNOWN";
|
|
14564
|
+
const existing = groups.get(key);
|
|
14565
|
+
if (existing) {
|
|
14566
|
+
existing.push(bucket);
|
|
14567
|
+
} else {
|
|
14568
|
+
groups.set(key, [bucket]);
|
|
14569
|
+
}
|
|
14570
|
+
}
|
|
14571
|
+
const sorted = /* @__PURE__ */ new Map();
|
|
14572
|
+
for (const key of order) {
|
|
14573
|
+
const group = groups.get(key);
|
|
14574
|
+
if (group) {
|
|
14575
|
+
sorted.set(key, group);
|
|
14576
|
+
}
|
|
14577
|
+
}
|
|
14578
|
+
for (const [key, group] of groups) {
|
|
14579
|
+
if (!sorted.has(key)) {
|
|
14580
|
+
sorted.set(key, group);
|
|
14581
|
+
}
|
|
14582
|
+
}
|
|
14583
|
+
return sorted;
|
|
14584
|
+
}
|
|
14585
|
+
function formatSummaryGroup(group) {
|
|
14586
|
+
const lines = [];
|
|
14587
|
+
const name = group.displayName?.trim();
|
|
14588
|
+
if (name) {
|
|
14589
|
+
lines.push(name);
|
|
14590
|
+
}
|
|
14591
|
+
const desc = group.description?.trim();
|
|
14592
|
+
if (desc) {
|
|
14593
|
+
lines.push(` Models within this group: ${desc}`);
|
|
14594
|
+
}
|
|
14595
|
+
const buckets = group.buckets;
|
|
14596
|
+
if (buckets?.length) {
|
|
14597
|
+
const windowGroups = groupBucketsByWindow(buckets);
|
|
14598
|
+
let firstWindow = true;
|
|
14599
|
+
for (const [, windowBuckets] of windowGroups) {
|
|
14600
|
+
if (!firstWindow) {
|
|
14601
|
+
lines.push("");
|
|
14602
|
+
}
|
|
14603
|
+
for (const bucket of windowBuckets) {
|
|
14604
|
+
const label = windowLabel(bucket.window);
|
|
14605
|
+
lines.push(` ${label}`);
|
|
14606
|
+
lines.push(...formatSummaryBucket(bucket, " "));
|
|
14607
|
+
firstWindow = false;
|
|
14608
|
+
}
|
|
14609
|
+
}
|
|
14610
|
+
}
|
|
14611
|
+
return lines;
|
|
14612
|
+
}
|
|
14613
|
+
function formatTopLevelBuckets(buckets) {
|
|
14614
|
+
const lines = [];
|
|
14615
|
+
const windowGroups = groupBucketsByWindow(buckets);
|
|
14616
|
+
let firstWindow = true;
|
|
14617
|
+
for (const [, windowBuckets] of windowGroups) {
|
|
14618
|
+
if (!firstWindow) {
|
|
14619
|
+
lines.push("");
|
|
14620
|
+
}
|
|
14621
|
+
for (const bucket of windowBuckets) {
|
|
14622
|
+
const label = windowLabel(bucket.window);
|
|
14623
|
+
lines.push(label);
|
|
14624
|
+
lines.push(...formatSummaryBucket(bucket, " "));
|
|
14625
|
+
firstWindow = false;
|
|
14626
|
+
}
|
|
14627
|
+
}
|
|
14628
|
+
return lines;
|
|
14629
|
+
}
|
|
14630
|
+
function formatAgyQuotaSummaryOutput(projectId, summary) {
|
|
14631
|
+
const lines = [
|
|
14632
|
+
`Agy quota summary for project \`${projectId}\``,
|
|
14633
|
+
""
|
|
14634
|
+
];
|
|
14635
|
+
const groups = summary.groups;
|
|
14636
|
+
if (groups?.length) {
|
|
14637
|
+
for (let i = 0; i < groups.length; i++) {
|
|
14638
|
+
const group = groups[i];
|
|
14639
|
+
if (!group) {
|
|
14640
|
+
continue;
|
|
14641
|
+
}
|
|
14642
|
+
if (i > 0) {
|
|
14643
|
+
lines.push("");
|
|
14644
|
+
lines.push("");
|
|
14645
|
+
}
|
|
14646
|
+
lines.push(...formatSummaryGroup(group));
|
|
14647
|
+
}
|
|
14648
|
+
} else if (summary.buckets?.length) {
|
|
14649
|
+
lines.push(...formatTopLevelBuckets(summary.buckets));
|
|
14650
|
+
} else {
|
|
14651
|
+
lines.push("No quota information available.");
|
|
14652
|
+
}
|
|
14653
|
+
return lines.join("\n");
|
|
14654
|
+
}
|
|
14655
|
+
|
|
14438
14656
|
// src/plugin/notify.ts
|
|
14439
14657
|
var MODEL_CAPACITY_TOAST_COOLDOWN_MS = 3e4;
|
|
14440
14658
|
var modelCapacityToastCooldownByKey = /* @__PURE__ */ new Map();
|
|
@@ -17243,6 +17461,12 @@ var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the c
|
|
|
17243
17461
|
Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
|
|
17244
17462
|
Do not call other tools.
|
|
17245
17463
|
`;
|
|
17464
|
+
var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
|
|
17465
|
+
var AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
|
|
17466
|
+
|
|
17467
|
+
Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
|
|
17468
|
+
Do not call other tools.
|
|
17469
|
+
`;
|
|
17246
17470
|
var latestAgyAuthResolver;
|
|
17247
17471
|
var latestAgyConfiguredProjectId;
|
|
17248
17472
|
var latestAgyUserAgentModel;
|
|
@@ -17489,6 +17713,10 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
|
|
|
17489
17713
|
description: "Show Agy Code Assist quota usage",
|
|
17490
17714
|
template: AGY_QUOTA_COMMAND_TEMPLATE
|
|
17491
17715
|
};
|
|
17716
|
+
config2.command[AGY_QUOTA_SUMMARY_COMMAND] = {
|
|
17717
|
+
description: "Show Agy Code Assist quota summary with weekly and 5-hour limits",
|
|
17718
|
+
template: AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE
|
|
17719
|
+
};
|
|
17492
17720
|
config2.provider = config2.provider || {};
|
|
17493
17721
|
config2.provider[AGY_PROVIDER_ID] = {
|
|
17494
17722
|
npm: "@ai-sdk/google",
|
|
@@ -17505,6 +17733,12 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
|
|
|
17505
17733
|
getAuthResolver: () => latestAgyAuthResolver,
|
|
17506
17734
|
getConfiguredProjectId: () => latestAgyConfiguredProjectId,
|
|
17507
17735
|
getUserAgentModel: () => latestAgyUserAgentModel
|
|
17736
|
+
}),
|
|
17737
|
+
[AGY_QUOTA_SUMMARY_TOOL_NAME]: createAgyQuotaSummaryTool({
|
|
17738
|
+
client,
|
|
17739
|
+
getAuthResolver: () => latestAgyAuthResolver,
|
|
17740
|
+
getConfiguredProjectId: () => latestAgyConfiguredProjectId,
|
|
17741
|
+
getUserAgentModel: () => latestAgyUserAgentModel
|
|
17508
17742
|
})
|
|
17509
17743
|
},
|
|
17510
17744
|
auth: {
|