@anthonyhaussman/opencode-agy-auth 1.0.11-alpha.0 → 1.0.11-alpha.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/dist/index.js +294 -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,65 @@ 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 (Number.isNaN(value)) {
|
|
14165
|
+
return min;
|
|
14166
|
+
}
|
|
14167
|
+
if (value < min) {
|
|
14168
|
+
return min;
|
|
14169
|
+
}
|
|
14170
|
+
if (value > max) {
|
|
14171
|
+
return max;
|
|
14172
|
+
}
|
|
14173
|
+
return value;
|
|
14174
|
+
}
|
|
14175
|
+
function pad(value, width) {
|
|
14176
|
+
if (value.length >= width) {
|
|
14177
|
+
return value;
|
|
14178
|
+
}
|
|
14179
|
+
return value.padEnd(width, " ");
|
|
14180
|
+
}
|
|
14181
|
+
function buildProgressBar(fraction, width = 20) {
|
|
14182
|
+
const clamped = clamp(fraction, 0, 1);
|
|
14183
|
+
const filled = clamped >= 1 ? width : Math.max(0, Math.min(width, Math.max(clamped > 0 ? 1 : 0, Math.floor(clamped * width))));
|
|
14184
|
+
const empty = width - filled;
|
|
14185
|
+
return `${"\u2593".repeat(filled)}${"\u2591".repeat(empty)}`;
|
|
14186
|
+
}
|
|
14187
|
+
function formatRemainingAmount(value) {
|
|
14188
|
+
if (!value) {
|
|
14189
|
+
return void 0;
|
|
14190
|
+
}
|
|
14191
|
+
const parsed = Number(value);
|
|
14192
|
+
if (!Number.isFinite(parsed)) {
|
|
14193
|
+
return value;
|
|
14194
|
+
}
|
|
14195
|
+
return parsed.toLocaleString("en-US");
|
|
14196
|
+
}
|
|
14197
|
+
function formatRelativeResetTime(resetTime) {
|
|
14198
|
+
if (!resetTime) {
|
|
14199
|
+
return void 0;
|
|
14200
|
+
}
|
|
14201
|
+
const resetAt = new Date(resetTime).getTime();
|
|
14202
|
+
if (Number.isNaN(resetAt)) {
|
|
14203
|
+
return void 0;
|
|
14204
|
+
}
|
|
14205
|
+
const diffMs = resetAt - Date.now();
|
|
14206
|
+
if (diffMs <= 0) {
|
|
14207
|
+
return "reset pending";
|
|
14208
|
+
}
|
|
14209
|
+
const totalMinutes = Math.ceil(diffMs / (1e3 * 60));
|
|
14210
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
14211
|
+
const minutes = totalMinutes % 60;
|
|
14212
|
+
if (hours > 0 && minutes > 0) {
|
|
14213
|
+
return `resets in ${hours}h ${minutes}m`;
|
|
14214
|
+
}
|
|
14215
|
+
if (hours > 0) {
|
|
14216
|
+
return `resets in ${hours}h`;
|
|
14217
|
+
}
|
|
14218
|
+
return `resets in ${minutes}m`;
|
|
14219
|
+
}
|
|
14220
|
+
|
|
14145
14221
|
// src/plugin/quota.ts
|
|
14146
14222
|
var AGY_QUOTA_TOOL_NAME = "agy_quota";
|
|
14147
14223
|
function createAgyQuotaTool({
|
|
@@ -14269,60 +14345,6 @@ function formatUsageRemaining(bucket) {
|
|
|
14269
14345
|
}
|
|
14270
14346
|
return "unknown";
|
|
14271
14347
|
}
|
|
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
14348
|
function normalizeTokenType(bucket) {
|
|
14327
14349
|
const value = bucket.tokenType?.trim();
|
|
14328
14350
|
return value ? value.toUpperCase() : "REQUESTS";
|
|
@@ -14435,6 +14457,208 @@ function splitModelVariant(modelId) {
|
|
|
14435
14457
|
};
|
|
14436
14458
|
}
|
|
14437
14459
|
|
|
14460
|
+
// src/plugin/quota-summary.ts
|
|
14461
|
+
var AGY_QUOTA_SUMMARY_TOOL_NAME = "agy_quota_summary";
|
|
14462
|
+
function createAgyQuotaSummaryTool({
|
|
14463
|
+
client,
|
|
14464
|
+
getAuthResolver,
|
|
14465
|
+
getConfiguredProjectId,
|
|
14466
|
+
getUserAgentModel
|
|
14467
|
+
}) {
|
|
14468
|
+
return tool({
|
|
14469
|
+
description: "Retrieve Agy Code Assist quota summary with weekly and 5-hour limits grouped by model family.",
|
|
14470
|
+
args: {},
|
|
14471
|
+
async execute() {
|
|
14472
|
+
const getAuth = getAuthResolver();
|
|
14473
|
+
if (!getAuth) {
|
|
14474
|
+
return "Agy quota summary is unavailable before Google auth is initialized. Authenticate with the Google provider and retry.";
|
|
14475
|
+
}
|
|
14476
|
+
const auth = await getAuth();
|
|
14477
|
+
if (!isOAuthAuth(auth)) {
|
|
14478
|
+
return "Agy quota summary requires OAuth with Google. Run `opencode auth login` and choose `Google OAuth (Antigravity CLI)` or `Google OAuth (Gemini CLI)`.";
|
|
14479
|
+
}
|
|
14480
|
+
let authRecord = resolveCachedAuth(auth);
|
|
14481
|
+
if (accessTokenExpired(authRecord)) {
|
|
14482
|
+
const refreshed = await refreshAccessToken(authRecord, client);
|
|
14483
|
+
if (!refreshed?.access) {
|
|
14484
|
+
return "Agy quota summary lookup failed because the access token could not be refreshed. Re-authenticate and retry.";
|
|
14485
|
+
}
|
|
14486
|
+
authRecord = refreshed;
|
|
14487
|
+
}
|
|
14488
|
+
if (!authRecord.access) {
|
|
14489
|
+
return "Agy quota summary lookup failed because no access token is available. Re-authenticate and retry.";
|
|
14490
|
+
}
|
|
14491
|
+
try {
|
|
14492
|
+
const projectContext = await ensureProjectContext(
|
|
14493
|
+
authRecord,
|
|
14494
|
+
client,
|
|
14495
|
+
getConfiguredProjectId(),
|
|
14496
|
+
getUserAgentModel()
|
|
14497
|
+
);
|
|
14498
|
+
if (!projectContext.effectiveProjectId) {
|
|
14499
|
+
return "Agy quota summary lookup failed because no Google Cloud project could be resolved.";
|
|
14500
|
+
}
|
|
14501
|
+
const summary = await retrieveUserQuotaSummary(
|
|
14502
|
+
authRecord.access,
|
|
14503
|
+
projectContext.effectiveProjectId,
|
|
14504
|
+
getUserAgentModel()
|
|
14505
|
+
);
|
|
14506
|
+
if (!summary) {
|
|
14507
|
+
return `No Agy quota summary available for project \`${projectContext.effectiveProjectId}\`.`;
|
|
14508
|
+
}
|
|
14509
|
+
return formatAgyQuotaSummaryOutput(
|
|
14510
|
+
projectContext.effectiveProjectId,
|
|
14511
|
+
summary
|
|
14512
|
+
);
|
|
14513
|
+
} catch (error45) {
|
|
14514
|
+
const message = error45 instanceof Error ? error45.message : "unknown error";
|
|
14515
|
+
return `Agy quota summary lookup failed: ${message}`;
|
|
14516
|
+
}
|
|
14517
|
+
}
|
|
14518
|
+
});
|
|
14519
|
+
}
|
|
14520
|
+
var BAR_WIDTH = 50;
|
|
14521
|
+
function windowLabel(window) {
|
|
14522
|
+
switch (window?.toUpperCase()) {
|
|
14523
|
+
case "WEEKLY":
|
|
14524
|
+
return "Weekly Limit";
|
|
14525
|
+
case "FIVE_HOUR":
|
|
14526
|
+
return "Five Hour Limit";
|
|
14527
|
+
default:
|
|
14528
|
+
return "Other Limit";
|
|
14529
|
+
}
|
|
14530
|
+
}
|
|
14531
|
+
function formatSummaryBucket(bucket, indent) {
|
|
14532
|
+
if (bucket.disabled) {
|
|
14533
|
+
const defaultDesc = `${windowLabel(bucket.window).toLowerCase()} exhausted`;
|
|
14534
|
+
const desc = bucket.description?.trim() || defaultDesc;
|
|
14535
|
+
return [`${indent}Disabled: ${desc}`];
|
|
14536
|
+
}
|
|
14537
|
+
const lines = [];
|
|
14538
|
+
const fraction = bucket.remainingFraction;
|
|
14539
|
+
const hasFraction = typeof fraction === "number" && Number.isFinite(fraction);
|
|
14540
|
+
if (hasFraction) {
|
|
14541
|
+
const clamped = clamp(fraction, 0, 1);
|
|
14542
|
+
const percent = (clamped * 100).toFixed(2);
|
|
14543
|
+
const bar = buildProgressBar(clamped, BAR_WIDTH);
|
|
14544
|
+
lines.push(`${indent}[${bar}] ${percent}%`);
|
|
14545
|
+
const remaining = formatRemainingAmount(bucket.remainingAmount);
|
|
14546
|
+
if (remaining) {
|
|
14547
|
+
const pctWhole = (clamped * 100).toFixed(0);
|
|
14548
|
+
lines.push(`${indent}${pctWhole}% remaining \xB7 ${remaining} left`);
|
|
14549
|
+
} else {
|
|
14550
|
+
const pctWhole = (clamped * 100).toFixed(0);
|
|
14551
|
+
lines.push(`${indent}${pctWhole}% remaining`);
|
|
14552
|
+
}
|
|
14553
|
+
} else {
|
|
14554
|
+
const remaining = formatRemainingAmount(bucket.remainingAmount);
|
|
14555
|
+
lines.push(remaining ? `${indent}${remaining} remaining` : `${indent}unknown remaining`);
|
|
14556
|
+
}
|
|
14557
|
+
const resetLabel = formatRelativeResetTime(bucket.resetTime);
|
|
14558
|
+
if (resetLabel) {
|
|
14559
|
+
const formattedReset = resetLabel.startsWith("resets in ") ? resetLabel.replace("resets in ", "Refreshes in ") : resetLabel.charAt(0).toUpperCase() + resetLabel.slice(1);
|
|
14560
|
+
lines.push(`${indent}${formattedReset}`);
|
|
14561
|
+
}
|
|
14562
|
+
return lines;
|
|
14563
|
+
}
|
|
14564
|
+
function groupBucketsByWindow(buckets) {
|
|
14565
|
+
const groups = /* @__PURE__ */ new Map();
|
|
14566
|
+
const order = ["WEEKLY", "FIVE_HOUR"];
|
|
14567
|
+
for (const bucket of buckets) {
|
|
14568
|
+
const key = bucket.window?.toUpperCase() || "UNKNOWN";
|
|
14569
|
+
const existing = groups.get(key);
|
|
14570
|
+
if (existing) {
|
|
14571
|
+
existing.push(bucket);
|
|
14572
|
+
} else {
|
|
14573
|
+
groups.set(key, [bucket]);
|
|
14574
|
+
}
|
|
14575
|
+
}
|
|
14576
|
+
const sorted = /* @__PURE__ */ new Map();
|
|
14577
|
+
for (const key of order) {
|
|
14578
|
+
const group = groups.get(key);
|
|
14579
|
+
if (group) {
|
|
14580
|
+
sorted.set(key, group);
|
|
14581
|
+
}
|
|
14582
|
+
}
|
|
14583
|
+
for (const [key, group] of groups) {
|
|
14584
|
+
if (!sorted.has(key)) {
|
|
14585
|
+
sorted.set(key, group);
|
|
14586
|
+
}
|
|
14587
|
+
}
|
|
14588
|
+
return sorted;
|
|
14589
|
+
}
|
|
14590
|
+
function formatSummaryGroup(group) {
|
|
14591
|
+
const lines = [];
|
|
14592
|
+
const name = group.displayName?.trim();
|
|
14593
|
+
if (name) {
|
|
14594
|
+
lines.push(name);
|
|
14595
|
+
}
|
|
14596
|
+
const desc = group.description?.trim();
|
|
14597
|
+
if (desc) {
|
|
14598
|
+
lines.push(` Models within this group: ${desc}`);
|
|
14599
|
+
}
|
|
14600
|
+
const buckets = group.buckets;
|
|
14601
|
+
if (buckets?.length) {
|
|
14602
|
+
const windowGroups = groupBucketsByWindow(buckets);
|
|
14603
|
+
let firstWindow = true;
|
|
14604
|
+
for (const [, windowBuckets] of windowGroups) {
|
|
14605
|
+
if (!firstWindow) {
|
|
14606
|
+
lines.push("");
|
|
14607
|
+
}
|
|
14608
|
+
for (const bucket of windowBuckets) {
|
|
14609
|
+
const baseLabel = windowLabel(bucket.window);
|
|
14610
|
+
const label = bucket.displayName ? `${baseLabel} (${bucket.displayName})` : baseLabel;
|
|
14611
|
+
lines.push(` ${label}`);
|
|
14612
|
+
lines.push(...formatSummaryBucket(bucket, " "));
|
|
14613
|
+
firstWindow = false;
|
|
14614
|
+
}
|
|
14615
|
+
}
|
|
14616
|
+
}
|
|
14617
|
+
return lines;
|
|
14618
|
+
}
|
|
14619
|
+
function formatTopLevelBuckets(buckets) {
|
|
14620
|
+
const lines = [];
|
|
14621
|
+
const windowGroups = groupBucketsByWindow(buckets);
|
|
14622
|
+
let firstWindow = true;
|
|
14623
|
+
for (const [, windowBuckets] of windowGroups) {
|
|
14624
|
+
if (!firstWindow) {
|
|
14625
|
+
lines.push("");
|
|
14626
|
+
}
|
|
14627
|
+
for (const bucket of windowBuckets) {
|
|
14628
|
+
const baseLabel = windowLabel(bucket.window);
|
|
14629
|
+
const label = bucket.displayName ? `${baseLabel} (${bucket.displayName})` : baseLabel;
|
|
14630
|
+
lines.push(label);
|
|
14631
|
+
lines.push(...formatSummaryBucket(bucket, " "));
|
|
14632
|
+
firstWindow = false;
|
|
14633
|
+
}
|
|
14634
|
+
}
|
|
14635
|
+
return lines;
|
|
14636
|
+
}
|
|
14637
|
+
function formatAgyQuotaSummaryOutput(projectId, summary) {
|
|
14638
|
+
const lines = [
|
|
14639
|
+
`Agy quota summary for project \`${projectId}\``,
|
|
14640
|
+
""
|
|
14641
|
+
];
|
|
14642
|
+
const groups = summary.groups;
|
|
14643
|
+
if (groups?.length) {
|
|
14644
|
+
for (let i = 0; i < groups.length; i++) {
|
|
14645
|
+
const group = groups[i];
|
|
14646
|
+
if (!group) {
|
|
14647
|
+
continue;
|
|
14648
|
+
}
|
|
14649
|
+
if (i > 0) {
|
|
14650
|
+
lines.push("");
|
|
14651
|
+
}
|
|
14652
|
+
lines.push(...formatSummaryGroup(group));
|
|
14653
|
+
}
|
|
14654
|
+
} else if (summary.buckets?.length) {
|
|
14655
|
+
lines.push(...formatTopLevelBuckets(summary.buckets));
|
|
14656
|
+
} else {
|
|
14657
|
+
lines.push("No quota information available.");
|
|
14658
|
+
}
|
|
14659
|
+
return lines.join("\n");
|
|
14660
|
+
}
|
|
14661
|
+
|
|
14438
14662
|
// src/plugin/notify.ts
|
|
14439
14663
|
var MODEL_CAPACITY_TOAST_COOLDOWN_MS = 3e4;
|
|
14440
14664
|
var modelCapacityToastCooldownByKey = /* @__PURE__ */ new Map();
|
|
@@ -17243,6 +17467,12 @@ var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the c
|
|
|
17243
17467
|
Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
|
|
17244
17468
|
Do not call other tools.
|
|
17245
17469
|
`;
|
|
17470
|
+
var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
|
|
17471
|
+
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.
|
|
17472
|
+
|
|
17473
|
+
Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
|
|
17474
|
+
Do not call other tools.
|
|
17475
|
+
`;
|
|
17246
17476
|
var latestAgyAuthResolver;
|
|
17247
17477
|
var latestAgyConfiguredProjectId;
|
|
17248
17478
|
var latestAgyUserAgentModel;
|
|
@@ -17489,6 +17719,10 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
|
|
|
17489
17719
|
description: "Show Agy Code Assist quota usage",
|
|
17490
17720
|
template: AGY_QUOTA_COMMAND_TEMPLATE
|
|
17491
17721
|
};
|
|
17722
|
+
config2.command[AGY_QUOTA_SUMMARY_COMMAND] = {
|
|
17723
|
+
description: "Show Agy Code Assist quota summary with weekly and 5-hour limits",
|
|
17724
|
+
template: AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE
|
|
17725
|
+
};
|
|
17492
17726
|
config2.provider = config2.provider || {};
|
|
17493
17727
|
config2.provider[AGY_PROVIDER_ID] = {
|
|
17494
17728
|
npm: "@ai-sdk/google",
|
|
@@ -17505,6 +17739,12 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
|
|
|
17505
17739
|
getAuthResolver: () => latestAgyAuthResolver,
|
|
17506
17740
|
getConfiguredProjectId: () => latestAgyConfiguredProjectId,
|
|
17507
17741
|
getUserAgentModel: () => latestAgyUserAgentModel
|
|
17742
|
+
}),
|
|
17743
|
+
[AGY_QUOTA_SUMMARY_TOOL_NAME]: createAgyQuotaSummaryTool({
|
|
17744
|
+
client,
|
|
17745
|
+
getAuthResolver: () => latestAgyAuthResolver,
|
|
17746
|
+
getConfiguredProjectId: () => latestAgyConfiguredProjectId,
|
|
17747
|
+
getUserAgentModel: () => latestAgyUserAgentModel
|
|
17508
17748
|
})
|
|
17509
17749
|
},
|
|
17510
17750
|
auth: {
|