0agent 1.0.38 → 1.0.39
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/bin/chat.js +67 -24
- package/package.json +1 -1
package/bin/chat.js
CHANGED
|
@@ -23,33 +23,64 @@ class Spinner {
|
|
|
23
23
|
this._msg = msg;
|
|
24
24
|
this._frames = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏'];
|
|
25
25
|
this._i = 0; this._timer = null; this._active = false;
|
|
26
|
+
this._sessionMode = false; // true during agent sessions — no \r animation
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
// Animated spinner — safe only at startup when user cannot type yet.
|
|
30
|
+
// Uses \r which conflicts with readline when user is typing.
|
|
27
31
|
start(msg) {
|
|
28
32
|
if (this._active) return;
|
|
29
33
|
if (msg) this._msg = msg;
|
|
30
34
|
this._active = true;
|
|
35
|
+
this._sessionMode = false;
|
|
31
36
|
this._timer = setInterval(() => {
|
|
32
37
|
process.stdout.write(`\r \x1b[36m${this._frames[this._i++ % this._frames.length]}\x1b[0m \x1b[2m${this._msg}\x1b[0m `);
|
|
33
38
|
}, 80);
|
|
34
39
|
}
|
|
40
|
+
|
|
41
|
+
// Session mode — prints a one-time static status line, NO \r animation.
|
|
42
|
+
// readline owns the cursor; call rl.prompt(true) after this to show › .
|
|
43
|
+
startSession(msg) {
|
|
44
|
+
if (this._active) return;
|
|
45
|
+
if (msg) this._msg = msg;
|
|
46
|
+
this._active = true;
|
|
47
|
+
this._sessionMode = true;
|
|
48
|
+
process.stdout.write(` \x1b[2m⠋ ${this._msg}...\x1b[0m\n`);
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
update(msg) { this._msg = msg; }
|
|
52
|
+
|
|
36
53
|
stop(clearIt = true) {
|
|
37
54
|
if (!this._active) return;
|
|
38
|
-
clearInterval(this._timer); this._timer = null;
|
|
39
|
-
|
|
55
|
+
if (this._timer) { clearInterval(this._timer); this._timer = null; }
|
|
56
|
+
const wasSession = this._sessionMode;
|
|
57
|
+
this._active = false;
|
|
58
|
+
this._sessionMode = false;
|
|
59
|
+
// Only clear the \r-based animation line; session mode output flows naturally
|
|
60
|
+
if (clearIt && !wasSession) {
|
|
61
|
+
process.stdout.write('\r\x1b[2K');
|
|
62
|
+
}
|
|
40
63
|
}
|
|
64
|
+
|
|
41
65
|
get active() { return this._active; }
|
|
42
66
|
|
|
43
|
-
|
|
44
|
-
* Pause spinner, run fn() (which may print lines), then resume.
|
|
45
|
-
* Prevents spinner from overwriting printed content.
|
|
46
|
-
*/
|
|
67
|
+
// Pause to print something cleanly, then resume.
|
|
47
68
|
pauseFor(fn) {
|
|
48
|
-
const wasActive
|
|
49
|
-
const
|
|
50
|
-
|
|
69
|
+
const wasActive = this._active;
|
|
70
|
+
const wasSession = this._sessionMode;
|
|
71
|
+
const savedMsg = this._msg;
|
|
72
|
+
this.stop(!wasSession); // clear animated spinner; session mode: just deactivate
|
|
51
73
|
fn();
|
|
52
|
-
if (wasActive)
|
|
74
|
+
if (wasActive) {
|
|
75
|
+
if (wasSession) {
|
|
76
|
+
// Re-mark active without printing again — readline is showing the prompt
|
|
77
|
+
this._active = true;
|
|
78
|
+
this._sessionMode = true;
|
|
79
|
+
this._msg = savedMsg;
|
|
80
|
+
} else {
|
|
81
|
+
this.start(savedMsg);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
53
84
|
}
|
|
54
85
|
}
|
|
55
86
|
|
|
@@ -192,13 +223,20 @@ function handleWsEvent(event) {
|
|
|
192
223
|
case 'session.step': {
|
|
193
224
|
spinner.stop();
|
|
194
225
|
if (streaming) { process.stdout.write('\n'); streaming = false; }
|
|
226
|
+
// Clear current readline line, print step, then restore › prompt
|
|
227
|
+
process.stdout.write('\r\x1b[2K');
|
|
195
228
|
console.log(` ${fmt(C.dim, '›')} ${event.step}`);
|
|
196
|
-
spinner.
|
|
229
|
+
spinner.startSession(event.step.slice(0, 50));
|
|
230
|
+
rl.prompt(true); // restore › so user can keep typing
|
|
197
231
|
break;
|
|
198
232
|
}
|
|
199
233
|
case 'session.token': {
|
|
200
234
|
spinner.stop();
|
|
201
|
-
if (!streaming) {
|
|
235
|
+
if (!streaming) {
|
|
236
|
+
// Clear › prompt line before streaming response
|
|
237
|
+
process.stdout.write('\r\x1b[2K\n ');
|
|
238
|
+
streaming = true;
|
|
239
|
+
}
|
|
202
240
|
process.stdout.write(event.token);
|
|
203
241
|
lineBuffer += event.token;
|
|
204
242
|
break;
|
|
@@ -383,9 +421,10 @@ async function runTask(input) {
|
|
|
383
421
|
});
|
|
384
422
|
const s = await res.json();
|
|
385
423
|
sessionId = s.session_id ?? s.id;
|
|
386
|
-
//
|
|
387
|
-
process.stdout.write(
|
|
388
|
-
spinner.
|
|
424
|
+
// Start session-mode status (no \r animation) then restore › so user can type
|
|
425
|
+
process.stdout.write('\n');
|
|
426
|
+
spinner.startSession('Thinking');
|
|
427
|
+
rl.prompt(true); // keep › visible — user can queue next message while agent works
|
|
389
428
|
|
|
390
429
|
// Polling fallback — runs concurrently with WS events.
|
|
391
430
|
// Catches completion when WS is disconnected (e.g. daemon just restarted).
|
|
@@ -416,8 +455,10 @@ async function runTask(input) {
|
|
|
416
455
|
const steps = session.steps ?? [];
|
|
417
456
|
for (let j = lastPolledStep; j < steps.length; j++) {
|
|
418
457
|
spinner.stop();
|
|
458
|
+
process.stdout.write('\r\x1b[2K');
|
|
419
459
|
console.log(` \x1b[2m›\x1b[0m ${steps[j].description}`);
|
|
420
|
-
spinner.
|
|
460
|
+
spinner.startSession(steps[j].description.slice(0, 50));
|
|
461
|
+
rl.prompt(true);
|
|
421
462
|
}
|
|
422
463
|
lastPolledStep = steps.length;
|
|
423
464
|
|
|
@@ -968,14 +1009,16 @@ rl.on('line', async (input) => {
|
|
|
968
1009
|
if (pendingResolve) {
|
|
969
1010
|
messageQueue.push(line);
|
|
970
1011
|
const qLen = messageQueue.length;
|
|
971
|
-
spinner.pauseFor(
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1012
|
+
// No spinner.pauseFor() needed — session mode has no \r animation
|
|
1013
|
+
// Just print the queued confirmation and restore the › prompt
|
|
1014
|
+
process.stdout.write('\r\x1b[2K');
|
|
1015
|
+
process.stdout.write(
|
|
1016
|
+
` ${fmt(C.magenta, '↳')} ${fmt(C.bold, `[queued #${qLen}]`)} ${fmt(C.dim, line.slice(0, 70))}\n`
|
|
1017
|
+
);
|
|
1018
|
+
if (qLen > 1) {
|
|
1019
|
+
process.stdout.write(` ${fmt(C.dim, `${qLen} tasks waiting`)}\n`);
|
|
1020
|
+
}
|
|
1021
|
+
rl.prompt(true); // keep › visible
|
|
979
1022
|
return;
|
|
980
1023
|
}
|
|
981
1024
|
|