agent-mp 0.4.7 → 0.4.9
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 +42 -9
- package/dist/utils/qwen-auth.js +7 -2
- package/package.json +1 -1
package/dist/core/engine.js
CHANGED
|
@@ -521,17 +521,28 @@ INSTRUCCIONES:
|
|
|
521
521
|
return null;
|
|
522
522
|
}
|
|
523
523
|
const sp = this._startSpinner(`${cliName} ${model}`);
|
|
524
|
+
let lineBuf = '';
|
|
525
|
+
const onChunk = (delta) => {
|
|
526
|
+
lineBuf += delta;
|
|
527
|
+
const lines = lineBuf.split('\n');
|
|
528
|
+
lineBuf = lines.pop() || '';
|
|
529
|
+
for (const l of lines) {
|
|
530
|
+
if (l.trim())
|
|
531
|
+
sp.push(l.trim());
|
|
532
|
+
}
|
|
533
|
+
};
|
|
524
534
|
try {
|
|
525
535
|
log.info(`${cliName}: calling Qwen API with own credentials (${model})`);
|
|
526
|
-
const result = await callQwenAPIFromCreds(rolePrompt, model, credsPath,
|
|
536
|
+
const result = await callQwenAPIFromCreds(rolePrompt, model, credsPath, onChunk);
|
|
537
|
+
if (lineBuf.trim())
|
|
538
|
+
sp.push(lineBuf.trim());
|
|
527
539
|
sp.stop();
|
|
528
540
|
return result;
|
|
529
541
|
}
|
|
530
542
|
catch (err) {
|
|
531
543
|
sp.stop();
|
|
532
544
|
if (err.message?.startsWith('QWEN_AUTH_EXPIRED')) {
|
|
533
|
-
|
|
534
|
-
console.log(chalk.yellow(` Ejecutá: ${cliName} --login\n`));
|
|
545
|
+
log.warn(`${cliName} session expired — using fallback`);
|
|
535
546
|
return null;
|
|
536
547
|
}
|
|
537
548
|
log.warn(`${cliName} direct API call failed: ${err.message}`);
|
|
@@ -572,15 +583,33 @@ INSTRUCCIONES:
|
|
|
572
583
|
}
|
|
573
584
|
}
|
|
574
585
|
}
|
|
575
|
-
// Try global fallback
|
|
586
|
+
// Try global fallback — use callQwenAPI directly for streaming (no subprocess)
|
|
576
587
|
if (this.config.fallback_global) {
|
|
577
588
|
const fb = this.config.fallback_global;
|
|
578
|
-
log.warn(`
|
|
579
|
-
const
|
|
580
|
-
|
|
589
|
+
log.warn(`Using global fallback: ${fb.cli} (${fb.model})`);
|
|
590
|
+
const sp = this._startSpinner(`${fb.cli} ${fb.model} (fallback)`);
|
|
591
|
+
let lineBuf = '';
|
|
592
|
+
const onChunk = (delta) => {
|
|
593
|
+
lineBuf += delta;
|
|
594
|
+
const lines = lineBuf.split('\n');
|
|
595
|
+
lineBuf = lines.pop() || '';
|
|
596
|
+
for (const l of lines) {
|
|
597
|
+
if (l.trim())
|
|
598
|
+
sp.push(l.trim());
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
try {
|
|
602
|
+
const globalResult = await callQwenAPI(rolePrompt, fb.model, onChunk);
|
|
603
|
+
if (lineBuf.trim())
|
|
604
|
+
sp.push(lineBuf.trim());
|
|
605
|
+
sp.stop();
|
|
581
606
|
trackTokens(globalResult, fb.cli, fb.model);
|
|
582
607
|
return globalResult;
|
|
583
608
|
}
|
|
609
|
+
catch (err) {
|
|
610
|
+
sp.stop();
|
|
611
|
+
log.warn(`Global fallback failed: ${err.message}`);
|
|
612
|
+
}
|
|
584
613
|
}
|
|
585
614
|
// All options exhausted
|
|
586
615
|
throw new Error(`${roleName} failed: primary + individual fallback + global fallback all failed`);
|
|
@@ -791,12 +820,16 @@ contenido completo del archivo aqui
|
|
|
791
820
|
}
|
|
792
821
|
const now = new Date().toISOString();
|
|
793
822
|
if (fileBlocks.length > 0) {
|
|
823
|
+
const sp = this._startSpinner(`Escribiendo ${fileBlocks.length} archivo(s)`);
|
|
794
824
|
for (const { relPath, content } of fileBlocks) {
|
|
825
|
+
// Strip markdown code fences the LLM may have wrapped around content
|
|
826
|
+
const clean = content.replace(/^```[\w]*\n/, '').replace(/\n```$/, '');
|
|
827
|
+
sp.push(relPath);
|
|
795
828
|
const absPath = path.join(this.projectDir, relPath);
|
|
796
829
|
await fs.mkdir(path.dirname(absPath), { recursive: true });
|
|
797
|
-
await writeFile(absPath,
|
|
798
|
-
log.ok(` Creado: ${relPath}`);
|
|
830
|
+
await writeFile(absPath, clean);
|
|
799
831
|
}
|
|
832
|
+
sp.stop();
|
|
800
833
|
log.ok(`${fileBlocks.length} archivo(s) implementado(s)`);
|
|
801
834
|
}
|
|
802
835
|
else {
|
package/dist/utils/qwen-auth.js
CHANGED
|
@@ -225,6 +225,9 @@ export async function qwenAuthStatus() {
|
|
|
225
225
|
const token = await loadToken();
|
|
226
226
|
if (!token)
|
|
227
227
|
return { authenticated: false };
|
|
228
|
+
// Verify token is not expired (loadToken already refreshes if close to expiry)
|
|
229
|
+
if (token.expiresAt > 0 && token.expiresAt < Date.now())
|
|
230
|
+
return { authenticated: false };
|
|
228
231
|
return { authenticated: true };
|
|
229
232
|
}
|
|
230
233
|
export async function fetchQwenModels() {
|
|
@@ -232,7 +235,8 @@ export async function fetchQwenModels() {
|
|
|
232
235
|
if (!token)
|
|
233
236
|
return [];
|
|
234
237
|
try {
|
|
235
|
-
const
|
|
238
|
+
const host = token.resourceUrl ? `https://${token.resourceUrl}` : 'https://chat.qwen.ai';
|
|
239
|
+
const res = await fetch(`${host}/api/models`, {
|
|
236
240
|
headers: { Authorization: `Bearer ${token.accessToken}` },
|
|
237
241
|
});
|
|
238
242
|
if (!res.ok)
|
|
@@ -249,7 +253,8 @@ export async function getQwenAccessToken() {
|
|
|
249
253
|
return token?.accessToken || null;
|
|
250
254
|
}
|
|
251
255
|
async function callQwenAPIWithToken(token, prompt, model, onData) {
|
|
252
|
-
const
|
|
256
|
+
const host = token.resourceUrl ? `https://${token.resourceUrl}` : 'https://chat.qwen.ai';
|
|
257
|
+
const baseUrl = `${host}/api/v1`;
|
|
253
258
|
const useStream = !!onData;
|
|
254
259
|
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
255
260
|
method: 'POST',
|