agent-mp 0.5.22 → 0.5.24
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/commands/repl.d.ts +0 -2
- package/dist/commands/repl.js +187 -227
- package/dist/commands/setup.js +55 -0
- package/dist/core/engine.js +24 -31
- package/dist/index.js +26 -19
- package/dist/ui/input.d.ts +23 -25
- package/dist/ui/input.js +310 -248
- package/dist/utils/qwen-auth.d.ts +14 -4
- package/dist/utils/qwen-auth.js +81 -8
- package/package.json +1 -1
package/dist/core/engine.js
CHANGED
|
@@ -69,7 +69,7 @@ function rebuildCmd(cliName, model, flags) {
|
|
|
69
69
|
}
|
|
70
70
|
async function ask(prompt, rl, fi) {
|
|
71
71
|
if (fi) {
|
|
72
|
-
fi.println(chalk.cyan(
|
|
72
|
+
fi.println(chalk.cyan(prompt));
|
|
73
73
|
const answer = await fi.readLine();
|
|
74
74
|
// Echo user response right-aligned (chat style, per line)
|
|
75
75
|
const userLines = answer.trim().split('\n').filter(l => l.trim());
|
|
@@ -329,17 +329,25 @@ export class AgentEngine {
|
|
|
329
329
|
if (!this.fi)
|
|
330
330
|
return noop;
|
|
331
331
|
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
332
|
+
const dotFrames = ['· ', '·· ', '···'];
|
|
332
333
|
let i = 0;
|
|
334
|
+
let ti = 0;
|
|
333
335
|
const t0 = Date.now();
|
|
334
336
|
const fi = this.fi;
|
|
337
|
+
let streaming = false;
|
|
335
338
|
fi.startActivity(`${frames[0]} ${label} 0s`);
|
|
339
|
+
fi.setActivityLines([` ${dotFrames[0]} esperando respuesta...`]);
|
|
336
340
|
const iv = setInterval(() => {
|
|
337
341
|
const s = Math.floor((Date.now() - t0) / 1000);
|
|
342
|
+
ti++;
|
|
338
343
|
fi.updateActivityHeader(`${frames[i++ % frames.length]} ${label} ${s}s`);
|
|
339
|
-
|
|
344
|
+
if (!streaming) {
|
|
345
|
+
fi.setActivityLines([` ${dotFrames[ti % dotFrames.length]} esperando respuesta...`]);
|
|
346
|
+
}
|
|
347
|
+
}, 300);
|
|
340
348
|
return {
|
|
341
349
|
stop() { clearInterval(iv); fi.stopActivity(); },
|
|
342
|
-
push(
|
|
350
|
+
push(_chunk) { streaming = true; },
|
|
343
351
|
};
|
|
344
352
|
}
|
|
345
353
|
/** Extract readable text lines from a qwen/CLI streaming chunk. */
|
|
@@ -409,7 +417,7 @@ INSTRUCCIONES:
|
|
|
409
417
|
const model = this.coordinatorCmd.match(/(?:-m|--model)\s+(\S+)/)?.[1] || 'coder-model';
|
|
410
418
|
const sp = this._startSpinner(`coordinador ${model}`);
|
|
411
419
|
try {
|
|
412
|
-
const result = await callQwenAPI(prompt, model, (c) =>
|
|
420
|
+
const result = await callQwenAPI(prompt, model, (c) => sp.push(c));
|
|
413
421
|
sp.stop();
|
|
414
422
|
return result;
|
|
415
423
|
}
|
|
@@ -620,26 +628,22 @@ INSTRUCCIONES:
|
|
|
620
628
|
const ROLE_BINARIES = new Set(['agent-orch', 'agent-impl', 'agent-rev', 'agent-explorer']);
|
|
621
629
|
const tryRoleBinaryCreds = async (cliName, model) => {
|
|
622
630
|
const credsPath = path.join(os.homedir(), `.${cliName}`, 'oauth_creds.json');
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
631
|
+
const hasOAuthCreds = await fileExists(credsPath);
|
|
632
|
+
if (!hasOAuthCreds) {
|
|
633
|
+
// No role OAuth creds — try global API key config before giving up
|
|
634
|
+
const { loadApiKeyConfig } = await import('../utils/qwen-auth.js');
|
|
635
|
+
const apiKeyCfg = await loadApiKeyConfig();
|
|
636
|
+
if (!apiKeyCfg) {
|
|
637
|
+
log.warn(`${cliName} has no credentials — run: agent-mp setup api-key or ${cliName} --login`);
|
|
638
|
+
return null;
|
|
639
|
+
}
|
|
640
|
+
// Fall through: callQwenAPIFromCreds will use the API key config
|
|
626
641
|
}
|
|
627
642
|
const sp = this._startSpinner(`${cliName} ${model}`);
|
|
628
|
-
|
|
629
|
-
const onChunk = (delta) => {
|
|
630
|
-
lineBuf += delta;
|
|
631
|
-
const lines = lineBuf.split('\n');
|
|
632
|
-
lineBuf = lines.pop() || '';
|
|
633
|
-
for (const l of lines) {
|
|
634
|
-
if (l.trim())
|
|
635
|
-
sp.push(l.trim());
|
|
636
|
-
}
|
|
637
|
-
};
|
|
643
|
+
const onChunk = (delta) => sp.push(delta);
|
|
638
644
|
try {
|
|
639
645
|
log.info(`${cliName}: calling Qwen API with own credentials (${model})`);
|
|
640
646
|
const result = await callQwenAPIFromCreds(rolePrompt, model, credsPath, onChunk);
|
|
641
|
-
if (lineBuf.trim())
|
|
642
|
-
sp.push(lineBuf.trim());
|
|
643
647
|
sp.stop();
|
|
644
648
|
return result;
|
|
645
649
|
}
|
|
@@ -696,20 +700,9 @@ INSTRUCCIONES:
|
|
|
696
700
|
const fb = this.config.fallback_global;
|
|
697
701
|
log.warn(`Using global fallback: ${fb.cli} (${fb.model})`);
|
|
698
702
|
const sp = this._startSpinner(`${fb.cli} ${fb.model} (fallback)`);
|
|
699
|
-
|
|
700
|
-
const onChunk = (delta) => {
|
|
701
|
-
lineBuf += delta;
|
|
702
|
-
const lines = lineBuf.split('\n');
|
|
703
|
-
lineBuf = lines.pop() || '';
|
|
704
|
-
for (const l of lines) {
|
|
705
|
-
if (l.trim())
|
|
706
|
-
sp.push(l.trim());
|
|
707
|
-
}
|
|
708
|
-
};
|
|
703
|
+
const onChunk = (delta) => sp.push(delta);
|
|
709
704
|
try {
|
|
710
705
|
const globalResult = await callQwenAPI(rolePrompt, fb.model, onChunk);
|
|
711
|
-
if (lineBuf.trim())
|
|
712
|
-
sp.push(lineBuf.trim());
|
|
713
706
|
sp.stop();
|
|
714
707
|
trackTokens(globalResult, fb.cli, fb.model);
|
|
715
708
|
return globalResult;
|
package/dist/index.js
CHANGED
|
@@ -61,8 +61,8 @@ REPL commands (type inside the session):
|
|
|
61
61
|
/run orch <task> Run only orchestrator
|
|
62
62
|
/run impl <id> Run only implementor
|
|
63
63
|
/run rev <id> Run only reviewer
|
|
64
|
-
/login
|
|
65
|
-
/logout
|
|
64
|
+
/login Configure API key
|
|
65
|
+
/logout Clear API key and credentials
|
|
66
66
|
/models [cli] List available models
|
|
67
67
|
/tasks List all tasks
|
|
68
68
|
/clear Clear screen
|
|
@@ -100,25 +100,32 @@ if (nativeRole) {
|
|
|
100
100
|
console.log(chalk.dim(` Version: ${PKG_NAME} --version\n`));
|
|
101
101
|
process.exit(0);
|
|
102
102
|
}
|
|
103
|
-
// --login:
|
|
103
|
+
// --login: configure API key for this role
|
|
104
104
|
if (args.includes('--login') || args.includes('login')) {
|
|
105
|
-
const {
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
105
|
+
const { saveApiKeyConfig, loadApiKeyConfig, DEFAULT_API_BASE_URL } = await import('./utils/qwen-auth.js');
|
|
106
|
+
const rl = (await import('readline')).createInterface({ input: process.stdin, output: process.stdout });
|
|
107
|
+
const ask = (q) => new Promise((res) => rl.question(q, res));
|
|
108
|
+
const existing = await loadApiKeyConfig();
|
|
109
|
+
console.log(chalk.bold.cyan(`\n ${PKG_NAME} — API Key Setup\n`));
|
|
110
|
+
if (existing) {
|
|
111
|
+
console.log(chalk.dim(` Current: ${existing.provider} / ${existing.model}`));
|
|
112
|
+
}
|
|
113
|
+
const apiKey = await ask(` API Key${existing ? ' [Enter to keep]' : ''}: `);
|
|
114
|
+
const model = await ask(` Model [${existing?.model ?? 'qwen-plus'}]: `);
|
|
115
|
+
rl.close();
|
|
116
|
+
const cfg = {
|
|
117
|
+
provider: existing?.provider ?? 'openai-compatible',
|
|
118
|
+
api_key: apiKey.trim() || existing?.api_key || '',
|
|
119
|
+
base_url: DEFAULT_API_BASE_URL,
|
|
120
|
+
model: model.trim() || existing?.model || 'qwen-plus',
|
|
121
|
+
};
|
|
122
|
+
if (!cfg.api_key) {
|
|
123
|
+
console.log(chalk.red(' API key is required.'));
|
|
124
|
+
process.exit(1);
|
|
120
125
|
}
|
|
121
|
-
|
|
126
|
+
await saveApiKeyConfig(cfg);
|
|
127
|
+
console.log(chalk.green(`\n ✓ API key saved — ${cfg.provider} / ${cfg.model}\n`));
|
|
128
|
+
process.exit(0);
|
|
122
129
|
}
|
|
123
130
|
// --status: show auth status
|
|
124
131
|
if (args.includes('--status') || args.includes('status')) {
|
package/dist/ui/input.d.ts
CHANGED
|
@@ -1,41 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline prompt, styled like Gemini/Qwen CLI.
|
|
3
|
+
* Draws at the current cursor line; when output arrives we erase the area
|
|
4
|
+
* (line-by-line, \x1b[2K) and redraw below. No absolute positioning.
|
|
5
|
+
*/
|
|
1
6
|
export declare class FixedInput {
|
|
2
|
-
private buf;
|
|
3
7
|
private history;
|
|
4
|
-
private histIdx;
|
|
5
8
|
private origLog;
|
|
6
|
-
private _pasting;
|
|
7
|
-
private _pasteAccum;
|
|
8
|
-
private _drawPending;
|
|
9
9
|
private _activityHeader;
|
|
10
10
|
private _activityLines;
|
|
11
|
-
private
|
|
11
|
+
private _inputBuffer;
|
|
12
|
+
private _cursorPos;
|
|
13
|
+
private _pasting;
|
|
14
|
+
private _pasteAccum;
|
|
15
|
+
private _resolveInput?;
|
|
16
|
+
private _inputActive;
|
|
17
|
+
private _areaRows;
|
|
18
|
+
private _cursorRow;
|
|
19
|
+
private _onResize?;
|
|
12
20
|
get cols(): number;
|
|
13
|
-
private get _reservedRows();
|
|
14
|
-
private get scrollBottom();
|
|
15
|
-
private _contentRows;
|
|
16
21
|
setup(): void;
|
|
17
22
|
teardown(): void;
|
|
18
|
-
redrawBox(): void;
|
|
19
23
|
suspend(): () => void;
|
|
20
|
-
/** Enter activity mode: show the 5-line log box instead of the input box. */
|
|
21
24
|
startActivity(header: string): void;
|
|
22
|
-
/** Update the header line (spinner frame + elapsed time) without clearing lines. */
|
|
23
25
|
updateActivityHeader(header: string): void;
|
|
24
|
-
/**
|
|
25
|
-
* Append a line to the activity log (keeps last ACTIVITY_LINES lines).
|
|
26
|
-
* Strips ANSI codes and skips blank or pure-JSON lines.
|
|
27
|
-
*/
|
|
28
26
|
pushActivity(rawLine: string): void;
|
|
29
|
-
/**
|
|
27
|
+
/** Replace all content lines at once (for streaming preview). */
|
|
28
|
+
setActivityLines(lines: string[]): void;
|
|
30
29
|
stopActivity(): void;
|
|
31
|
-
readLine(): Promise<string>;
|
|
32
30
|
println(text: string): void;
|
|
33
31
|
printSeparator(): void;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
private
|
|
40
|
-
private
|
|
32
|
+
redrawBox(): void;
|
|
33
|
+
readLine(): Promise<string>;
|
|
34
|
+
private _commitPaste;
|
|
35
|
+
/** Build a string that erases the currently-drawn area and leaves the cursor at col 0 of the top row. */
|
|
36
|
+
private _buildClear;
|
|
37
|
+
private _clearArea;
|
|
38
|
+
private _redraw;
|
|
41
39
|
}
|