@zhafron/opencode-kiro-auth 1.1.2 → 1.1.3
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/plugin/accounts.d.ts +2 -0
- package/dist/plugin/accounts.js +7 -0
- package/dist/plugin.js +21 -7
- package/package.json +1 -1
|
@@ -6,11 +6,13 @@ export declare class AccountManager {
|
|
|
6
6
|
private cursor;
|
|
7
7
|
private strategy;
|
|
8
8
|
private lastToastTime;
|
|
9
|
+
private lastUsageToastTime;
|
|
9
10
|
constructor(accounts: ManagedAccount[], usage: Record<string, UsageMetadata>, strategy?: AccountSelectionStrategy);
|
|
10
11
|
static loadFromDisk(strategy?: AccountSelectionStrategy): Promise<AccountManager>;
|
|
11
12
|
getAccountCount(): number;
|
|
12
13
|
getAccounts(): ManagedAccount[];
|
|
13
14
|
shouldShowToast(debounce?: number): boolean;
|
|
15
|
+
shouldShowUsageToast(debounce?: number): boolean;
|
|
14
16
|
getMinWaitTime(): number;
|
|
15
17
|
getCurrentOrNext(): ManagedAccount | null;
|
|
16
18
|
updateUsage(id: string, meta: {
|
package/dist/plugin/accounts.js
CHANGED
|
@@ -11,6 +11,7 @@ export class AccountManager {
|
|
|
11
11
|
cursor;
|
|
12
12
|
strategy;
|
|
13
13
|
lastToastTime = 0;
|
|
14
|
+
lastUsageToastTime = 0;
|
|
14
15
|
constructor(accounts, usage, strategy = 'sticky') {
|
|
15
16
|
this.accounts = accounts;
|
|
16
17
|
this.usage = usage;
|
|
@@ -46,6 +47,12 @@ export class AccountManager {
|
|
|
46
47
|
this.lastToastTime = Date.now();
|
|
47
48
|
return true;
|
|
48
49
|
}
|
|
50
|
+
shouldShowUsageToast(debounce = 30000) {
|
|
51
|
+
if (Date.now() - this.lastUsageToastTime < debounce)
|
|
52
|
+
return false;
|
|
53
|
+
this.lastUsageToastTime = Date.now();
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
49
56
|
getMinWaitTime() {
|
|
50
57
|
const now = Date.now();
|
|
51
58
|
const waits = this.accounts.map((a) => (a.rateLimitResetTime || 0) - now).filter((t) => t > 0);
|
package/dist/plugin.js
CHANGED
|
@@ -16,6 +16,13 @@ const KIRO_API_PATTERN = /^(https?:\/\/)?q\.[a-z0-9-]+\.amazonaws\.com/;
|
|
|
16
16
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
17
17
|
const isNetworkError = (e) => e instanceof Error && /econnreset|etimedout|enotfound|network|fetch failed/i.test(e.message);
|
|
18
18
|
const extractModel = (url) => url.match(/models\/([^/:]+)/)?.[1] || null;
|
|
19
|
+
const formatUsageMessage = (usedCount, limitCount, email) => {
|
|
20
|
+
if (limitCount > 0) {
|
|
21
|
+
const percentage = Math.round((usedCount / limitCount) * 100);
|
|
22
|
+
return `Usage (${email}): ${usedCount}/${limitCount} (${percentage}%)`;
|
|
23
|
+
}
|
|
24
|
+
return `Usage (${email}): ${usedCount}`;
|
|
25
|
+
};
|
|
19
26
|
export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
20
27
|
const config = loadConfig(directory);
|
|
21
28
|
const showToast = (message, variant) => {
|
|
@@ -51,18 +58,25 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
|
51
58
|
continue;
|
|
52
59
|
}
|
|
53
60
|
if (count > 1 && am.shouldShowToast())
|
|
54
|
-
showToast(`Using ${acc.email} (${am.getAccounts().indexOf(acc) + 1}/${count})`, 'info');
|
|
61
|
+
showToast(`Using ${acc.realEmail || acc.email} (${am.getAccounts().indexOf(acc) + 1}/${count})`, 'info');
|
|
62
|
+
if (am.shouldShowUsageToast() &&
|
|
63
|
+
acc.usedCount !== undefined &&
|
|
64
|
+
acc.limitCount !== undefined) {
|
|
65
|
+
const percentage = acc.limitCount > 0 ? (acc.usedCount / acc.limitCount) * 100 : 0;
|
|
66
|
+
const variant = percentage >= 80 ? 'warning' : 'info';
|
|
67
|
+
showToast(formatUsageMessage(acc.usedCount, acc.limitCount, acc.realEmail || acc.email), variant);
|
|
68
|
+
}
|
|
55
69
|
let auth = am.toAuthDetails(acc);
|
|
56
70
|
if (accessTokenExpired(auth)) {
|
|
57
71
|
try {
|
|
58
|
-
logger.log(`Refreshing token for ${acc.email}`);
|
|
72
|
+
logger.log(`Refreshing token for ${acc.realEmail || acc.email}`);
|
|
59
73
|
auth = await refreshAccessToken(auth);
|
|
60
74
|
am.updateFromAuth(acc, auth);
|
|
61
75
|
await am.saveToDisk();
|
|
62
76
|
}
|
|
63
77
|
catch (e) {
|
|
64
78
|
const msg = e instanceof KiroTokenRefreshError ? e.message : String(e);
|
|
65
|
-
showToast(`Refresh failed for ${acc.email}: ${msg}`, 'error');
|
|
79
|
+
showToast(`Refresh failed for ${acc.realEmail || acc.email}: ${msg}`, 'error');
|
|
66
80
|
if (e instanceof KiroTokenRefreshError && e.code === 'invalid_grant') {
|
|
67
81
|
am.removeAccount(acc);
|
|
68
82
|
await am.saveToDisk();
|
|
@@ -114,7 +128,7 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
|
114
128
|
updateAccountQuota(acc, u, am);
|
|
115
129
|
am.saveToDisk();
|
|
116
130
|
})
|
|
117
|
-
.catch((e) => logger.warn(`Usage sync failed for ${acc.email}: ${e.message}`));
|
|
131
|
+
.catch((e) => logger.warn(`Usage sync failed for ${acc.realEmail || acc.email}: ${e.message}`));
|
|
118
132
|
if (prep.streaming) {
|
|
119
133
|
const s = transformKiroStream(res, model, prep.conversationId);
|
|
120
134
|
return new Response(new ReadableStream({
|
|
@@ -164,7 +178,7 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
|
164
178
|
});
|
|
165
179
|
}
|
|
166
180
|
if (res.status === 401 && retry < config.rate_limit_max_retries) {
|
|
167
|
-
logger.warn(`Unauthorized (401) on ${acc.email}, retrying...`);
|
|
181
|
+
logger.warn(`Unauthorized (401) on ${acc.realEmail || acc.email}, retrying...`);
|
|
168
182
|
retry++;
|
|
169
183
|
continue;
|
|
170
184
|
}
|
|
@@ -173,7 +187,7 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
|
173
187
|
am.markRateLimited(acc, wait);
|
|
174
188
|
await am.saveToDisk();
|
|
175
189
|
if (count > 1) {
|
|
176
|
-
showToast(`Rate limited on ${acc.email}. Switching account...`, 'warning');
|
|
190
|
+
showToast(`Rate limited on ${acc.realEmail || acc.email}. Switching account...`, 'warning');
|
|
177
191
|
continue;
|
|
178
192
|
}
|
|
179
193
|
else {
|
|
@@ -183,7 +197,7 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
|
183
197
|
}
|
|
184
198
|
}
|
|
185
199
|
if ((res.status === 402 || res.status === 403) && count > 1) {
|
|
186
|
-
showToast(`${res.status === 402 ? 'Quota exhausted' : 'Forbidden'} on ${acc.email}. Switching...`, 'warning');
|
|
200
|
+
showToast(`${res.status === 402 ? 'Quota exhausted' : 'Forbidden'} on ${acc.realEmail || acc.email}. Switching...`, 'warning');
|
|
187
201
|
am.markUnhealthy(acc, res.status === 402 ? 'Quota' : 'Forbidden');
|
|
188
202
|
await am.saveToDisk();
|
|
189
203
|
continue;
|