agent-rev 0.3.3 → 0.3.5
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/utils/qwen-auth.js +53 -27
- package/package.json +1 -1
package/dist/utils/qwen-auth.js
CHANGED
|
@@ -42,14 +42,20 @@ async function loadToken() {
|
|
|
42
42
|
};
|
|
43
43
|
if (!token.accessToken)
|
|
44
44
|
return null;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
// Refresh proactivo: si vence en menos de 2 minutos (o ya venció)
|
|
46
|
+
const TWO_MIN = 2 * 60 * 1000;
|
|
47
|
+
if (token.expiresAt - Date.now() < TWO_MIN && token.refreshToken) {
|
|
48
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
49
|
+
if (refreshed) {
|
|
50
|
+
await saveToken(refreshed);
|
|
51
|
+
return refreshed;
|
|
52
|
+
}
|
|
53
|
+
// Si el refresh falla pero el token aún no venció del todo, seguir con él
|
|
54
|
+
if (token.expiresAt > Date.now())
|
|
55
|
+
return token;
|
|
56
|
+
return null;
|
|
51
57
|
}
|
|
52
|
-
return
|
|
58
|
+
return token;
|
|
53
59
|
}
|
|
54
60
|
catch {
|
|
55
61
|
return null;
|
|
@@ -59,7 +65,8 @@ async function saveToken(token) {
|
|
|
59
65
|
const tokenPath = await getTokenPath();
|
|
60
66
|
await fs.writeFile(tokenPath, JSON.stringify(token, null, 2), 'utf-8');
|
|
61
67
|
}
|
|
62
|
-
|
|
68
|
+
/** Calls the refresh endpoint and returns the new token (does NOT save). */
|
|
69
|
+
async function doRefreshToken(refreshToken) {
|
|
63
70
|
try {
|
|
64
71
|
const response = await fetch(QWEN_OAUTH_TOKEN_ENDPOINT, {
|
|
65
72
|
method: 'POST',
|
|
@@ -70,25 +77,29 @@ async function refreshAccessToken(refreshToken) {
|
|
|
70
77
|
client_id: QWEN_OAUTH_CLIENT_ID,
|
|
71
78
|
}),
|
|
72
79
|
});
|
|
73
|
-
if (!response.ok)
|
|
74
|
-
|
|
75
|
-
}
|
|
80
|
+
if (!response.ok)
|
|
81
|
+
return null;
|
|
76
82
|
const data = await response.json();
|
|
77
|
-
|
|
83
|
+
if (!data.access_token)
|
|
84
|
+
return null;
|
|
85
|
+
return {
|
|
78
86
|
accessToken: data.access_token,
|
|
79
87
|
refreshToken: data.refresh_token || refreshToken,
|
|
80
88
|
expiresAt: Date.now() + (data.expires_in || 3600) * 1000,
|
|
81
89
|
idToken: data.id_token,
|
|
82
90
|
resourceUrl: data.resource_url,
|
|
83
91
|
};
|
|
84
|
-
await saveToken(token);
|
|
85
|
-
return token;
|
|
86
92
|
}
|
|
87
|
-
catch
|
|
88
|
-
console.error('Error refreshing token:', error);
|
|
93
|
+
catch {
|
|
89
94
|
return null;
|
|
90
95
|
}
|
|
91
96
|
}
|
|
97
|
+
async function refreshAccessToken(refreshToken) {
|
|
98
|
+
const token = await doRefreshToken(refreshToken);
|
|
99
|
+
if (token)
|
|
100
|
+
await saveToken(token);
|
|
101
|
+
return token;
|
|
102
|
+
}
|
|
92
103
|
// Generate PKCE code verifier and challenge
|
|
93
104
|
function generatePKCE() {
|
|
94
105
|
const codeVerifier = crypto.randomBytes(32).toString('base64url');
|
|
@@ -263,7 +274,7 @@ async function callQwenAPIWithToken(token, prompt, model) {
|
|
|
263
274
|
return data.choices?.[0]?.message?.content || '';
|
|
264
275
|
}
|
|
265
276
|
export async function callQwenAPI(prompt, model = 'coder-model') {
|
|
266
|
-
|
|
277
|
+
let token = await loadToken();
|
|
267
278
|
if (!token) {
|
|
268
279
|
throw new Error('QWEN_AUTH_EXPIRED: No hay token de Qwen. Ejecutá --login primero.');
|
|
269
280
|
}
|
|
@@ -271,10 +282,17 @@ export async function callQwenAPI(prompt, model = 'coder-model') {
|
|
|
271
282
|
return await callQwenAPIWithToken(token, prompt, model);
|
|
272
283
|
}
|
|
273
284
|
catch (err) {
|
|
274
|
-
if (err.message?.startsWith('QWEN_AUTH_EXPIRED'))
|
|
275
|
-
throw
|
|
285
|
+
if (!err.message?.startsWith('QWEN_AUTH_EXPIRED'))
|
|
286
|
+
throw err;
|
|
287
|
+
// 401 — intentar refresh antes de rendirse
|
|
288
|
+
if (token.refreshToken) {
|
|
289
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
290
|
+
if (refreshed) {
|
|
291
|
+
await saveToken(refreshed);
|
|
292
|
+
return callQwenAPIWithToken(refreshed, prompt, model);
|
|
293
|
+
}
|
|
276
294
|
}
|
|
277
|
-
throw
|
|
295
|
+
throw new Error('QWEN_AUTH_EXPIRED: Sesión expirada. Ejecutá: agent-mp --login');
|
|
278
296
|
}
|
|
279
297
|
}
|
|
280
298
|
/** Call Qwen API using credentials from a specific file path (for role binaries) */
|
|
@@ -296,9 +314,10 @@ export async function callQwenAPIFromCreds(prompt, model, credsPath) {
|
|
|
296
314
|
if (!token.accessToken) {
|
|
297
315
|
throw new Error(`Invalid credentials at ${credsPath}. Run the role binary with --login first.`);
|
|
298
316
|
}
|
|
299
|
-
// Refresh
|
|
300
|
-
|
|
301
|
-
|
|
317
|
+
// Refresh proactivo: si vence en menos de 2 minutos (o ya venció)
|
|
318
|
+
const TWO_MIN = 2 * 60 * 1000;
|
|
319
|
+
if (token.expiresAt - Date.now() < TWO_MIN && token.refreshToken) {
|
|
320
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
302
321
|
if (refreshed) {
|
|
303
322
|
token = refreshed;
|
|
304
323
|
await fs.writeFile(credsPath, JSON.stringify(token, null, 2), 'utf-8');
|
|
@@ -308,10 +327,17 @@ export async function callQwenAPIFromCreds(prompt, model, credsPath) {
|
|
|
308
327
|
return await callQwenAPIWithToken(token, prompt, model);
|
|
309
328
|
}
|
|
310
329
|
catch (err) {
|
|
311
|
-
if (err.message?.startsWith('QWEN_AUTH_EXPIRED'))
|
|
312
|
-
|
|
313
|
-
|
|
330
|
+
if (!err.message?.startsWith('QWEN_AUTH_EXPIRED'))
|
|
331
|
+
throw err;
|
|
332
|
+
// 401 server-side — intentar refresh aunque expiresAt no haya vencido
|
|
333
|
+
if (token.refreshToken) {
|
|
334
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
335
|
+
if (refreshed) {
|
|
336
|
+
await fs.writeFile(credsPath, JSON.stringify(refreshed, null, 2), 'utf-8');
|
|
337
|
+
return callQwenAPIWithToken(refreshed, prompt, model);
|
|
338
|
+
}
|
|
314
339
|
}
|
|
315
|
-
|
|
340
|
+
const cliName = path.basename(path.dirname(credsPath)).replace(/^\./, '');
|
|
341
|
+
throw new Error(`QWEN_AUTH_EXPIRED: Sesión expirada. Ejecutá: ${cliName} --login`);
|
|
316
342
|
}
|
|
317
343
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"agent-rev","version":"0.3.
|
|
1
|
+
{"name":"agent-rev","version":"0.3.5","description":"agent-rev agent","type":"module","main":"./dist/index.js","files":["dist/"],"bin":{"agent-rev":"dist/index.js"},"scripts":{"build":"tsc"},"keywords":["ai","agent","cli"],"license":"MIT","dependencies":{"@anthropic-ai/sdk":"^0.39.0","@google/generative-ai":"^0.24.0","chalk":"^5.4.1","commander":"^13.1.0","open":"^11.0.0","openai":"^4.91.0"},"engines":{"node":">=18.0.0"}}
|