agent-rev 0.3.2 → 0.3.4
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/core/engine.js +24 -3
- package/dist/utils/qwen-auth.js +54 -15
- package/package.json +1 -1
package/dist/core/engine.js
CHANGED
|
@@ -258,8 +258,13 @@ INSTRUCCIONES:
|
|
|
258
258
|
return await callQwenAPI(prompt, model);
|
|
259
259
|
}
|
|
260
260
|
catch (err) {
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
if (err.message?.startsWith('QWEN_AUTH_EXPIRED')) {
|
|
262
|
+
console.log(chalk.red('\n ✗ Sesión Qwen expirada.'));
|
|
263
|
+
console.log(chalk.yellow(' Ejecutá: /login para re-autenticarte.\n'));
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
console.log(chalk.red(`\n ✗ Error Qwen: ${err.message}`));
|
|
267
|
+
}
|
|
263
268
|
return '';
|
|
264
269
|
}
|
|
265
270
|
}
|
|
@@ -452,6 +457,11 @@ INSTRUCCIONES:
|
|
|
452
457
|
return await callQwenAPIFromCreds(rolePrompt, model, credsPath);
|
|
453
458
|
}
|
|
454
459
|
catch (err) {
|
|
460
|
+
if (err.message?.startsWith('QWEN_AUTH_EXPIRED')) {
|
|
461
|
+
console.log(chalk.red(`\n ✗ Sesión expirada para ${cliName}.`));
|
|
462
|
+
console.log(chalk.yellow(` Ejecutá: ${cliName} --login\n`));
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
455
465
|
log.warn(`${cliName} direct API call failed: ${err.message}`);
|
|
456
466
|
return null;
|
|
457
467
|
}
|
|
@@ -843,7 +853,18 @@ INSTRUCCIONES:
|
|
|
843
853
|
3. Identifica dependencias entre servicios.
|
|
844
854
|
4. Crea/actualiza ${archPath} con tabla resumen y detalle por servicio.
|
|
845
855
|
5. Crea/actualiza ${contextDir}/<servicio>/architecture.md para cada servicio.`);
|
|
846
|
-
|
|
856
|
+
let result;
|
|
857
|
+
try {
|
|
858
|
+
result = await callQwenAPI(prompt, role.model);
|
|
859
|
+
}
|
|
860
|
+
catch (err) {
|
|
861
|
+
if (err.message?.startsWith('QWEN_AUTH_EXPIRED')) {
|
|
862
|
+
console.log(chalk.red('\n ✗ Sesión Qwen expirada.'));
|
|
863
|
+
console.log(chalk.yellow(' Ejecutá: agent-mp --login (o agent-explorer --login)\n'));
|
|
864
|
+
return '';
|
|
865
|
+
}
|
|
866
|
+
throw err;
|
|
867
|
+
}
|
|
847
868
|
try {
|
|
848
869
|
const ts = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
849
870
|
await writeFile(path.join(contextDir, `explorer-${ts}.md`), `# Explorer Report\n\nTask: ${effectiveTask}\n\n${result}\n`);
|
package/dist/utils/qwen-auth.js
CHANGED
|
@@ -59,7 +59,8 @@ async function saveToken(token) {
|
|
|
59
59
|
const tokenPath = await getTokenPath();
|
|
60
60
|
await fs.writeFile(tokenPath, JSON.stringify(token, null, 2), 'utf-8');
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
/** Calls the refresh endpoint and returns the new token (does NOT save). */
|
|
63
|
+
async function doRefreshToken(refreshToken) {
|
|
63
64
|
try {
|
|
64
65
|
const response = await fetch(QWEN_OAUTH_TOKEN_ENDPOINT, {
|
|
65
66
|
method: 'POST',
|
|
@@ -70,25 +71,29 @@ async function refreshAccessToken(refreshToken) {
|
|
|
70
71
|
client_id: QWEN_OAUTH_CLIENT_ID,
|
|
71
72
|
}),
|
|
72
73
|
});
|
|
73
|
-
if (!response.ok)
|
|
74
|
-
|
|
75
|
-
}
|
|
74
|
+
if (!response.ok)
|
|
75
|
+
return null;
|
|
76
76
|
const data = await response.json();
|
|
77
|
-
|
|
77
|
+
if (!data.access_token)
|
|
78
|
+
return null;
|
|
79
|
+
return {
|
|
78
80
|
accessToken: data.access_token,
|
|
79
81
|
refreshToken: data.refresh_token || refreshToken,
|
|
80
82
|
expiresAt: Date.now() + (data.expires_in || 3600) * 1000,
|
|
81
83
|
idToken: data.id_token,
|
|
82
84
|
resourceUrl: data.resource_url,
|
|
83
85
|
};
|
|
84
|
-
await saveToken(token);
|
|
85
|
-
return token;
|
|
86
86
|
}
|
|
87
|
-
catch
|
|
88
|
-
console.error('Error refreshing token:', error);
|
|
87
|
+
catch {
|
|
89
88
|
return null;
|
|
90
89
|
}
|
|
91
90
|
}
|
|
91
|
+
async function refreshAccessToken(refreshToken) {
|
|
92
|
+
const token = await doRefreshToken(refreshToken);
|
|
93
|
+
if (token)
|
|
94
|
+
await saveToken(token);
|
|
95
|
+
return token;
|
|
96
|
+
}
|
|
92
97
|
// Generate PKCE code verifier and challenge
|
|
93
98
|
function generatePKCE() {
|
|
94
99
|
const codeVerifier = crypto.randomBytes(32).toString('base64url');
|
|
@@ -254,17 +259,35 @@ async function callQwenAPIWithToken(token, prompt, model) {
|
|
|
254
259
|
});
|
|
255
260
|
if (!response.ok) {
|
|
256
261
|
const errorText = await response.text();
|
|
262
|
+
if (response.status === 401) {
|
|
263
|
+
throw new Error(`QWEN_AUTH_EXPIRED: ${errorText}`);
|
|
264
|
+
}
|
|
257
265
|
throw new Error(`Qwen API error: ${response.status} - ${errorText}`);
|
|
258
266
|
}
|
|
259
267
|
const data = await response.json();
|
|
260
268
|
return data.choices?.[0]?.message?.content || '';
|
|
261
269
|
}
|
|
262
270
|
export async function callQwenAPI(prompt, model = 'coder-model') {
|
|
263
|
-
|
|
271
|
+
let token = await loadToken();
|
|
264
272
|
if (!token) {
|
|
265
|
-
throw new Error('No hay token de Qwen. Ejecutá
|
|
273
|
+
throw new Error('QWEN_AUTH_EXPIRED: No hay token de Qwen. Ejecutá --login primero.');
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
return await callQwenAPIWithToken(token, prompt, model);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
if (!err.message?.startsWith('QWEN_AUTH_EXPIRED'))
|
|
280
|
+
throw err;
|
|
281
|
+
// 401 — intentar refresh antes de rendirse
|
|
282
|
+
if (token.refreshToken) {
|
|
283
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
284
|
+
if (refreshed) {
|
|
285
|
+
await saveToken(refreshed);
|
|
286
|
+
return callQwenAPIWithToken(refreshed, prompt, model);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
throw new Error('QWEN_AUTH_EXPIRED: Sesión expirada. Ejecutá: agent-mp --login');
|
|
266
290
|
}
|
|
267
|
-
return callQwenAPIWithToken(token, prompt, model);
|
|
268
291
|
}
|
|
269
292
|
/** Call Qwen API using credentials from a specific file path (for role binaries) */
|
|
270
293
|
export async function callQwenAPIFromCreds(prompt, model, credsPath) {
|
|
@@ -285,13 +308,29 @@ export async function callQwenAPIFromCreds(prompt, model, credsPath) {
|
|
|
285
308
|
if (!token.accessToken) {
|
|
286
309
|
throw new Error(`Invalid credentials at ${credsPath}. Run the role binary with --login first.`);
|
|
287
310
|
}
|
|
288
|
-
// Refresh if expired
|
|
311
|
+
// Refresh if expired by timestamp
|
|
289
312
|
if (token.expiresAt <= Date.now() && token.refreshToken) {
|
|
290
|
-
const refreshed = await
|
|
313
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
291
314
|
if (refreshed) {
|
|
292
315
|
token = refreshed;
|
|
293
316
|
await fs.writeFile(credsPath, JSON.stringify(token, null, 2), 'utf-8');
|
|
294
317
|
}
|
|
295
318
|
}
|
|
296
|
-
|
|
319
|
+
try {
|
|
320
|
+
return await callQwenAPIWithToken(token, prompt, model);
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
if (!err.message?.startsWith('QWEN_AUTH_EXPIRED'))
|
|
324
|
+
throw err;
|
|
325
|
+
// 401 server-side — intentar refresh aunque expiresAt no haya vencido
|
|
326
|
+
if (token.refreshToken) {
|
|
327
|
+
const refreshed = await doRefreshToken(token.refreshToken);
|
|
328
|
+
if (refreshed) {
|
|
329
|
+
await fs.writeFile(credsPath, JSON.stringify(refreshed, null, 2), 'utf-8');
|
|
330
|
+
return callQwenAPIWithToken(refreshed, prompt, model);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const cliName = path.basename(path.dirname(credsPath)).replace(/^\./, '');
|
|
334
|
+
throw new Error(`QWEN_AUTH_EXPIRED: Sesión expirada. Ejecutá: ${cliName} --login`);
|
|
335
|
+
}
|
|
297
336
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"agent-rev","version":"0.3.
|
|
1
|
+
{"name":"agent-rev","version":"0.3.4","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"}}
|