ucode-agent 1.22.0 → 1.24.0
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/package.json +1 -1
- package/src/core/loop.js +21 -9
- package/src/ui/plain.js +351 -349
- package/src/ui/screen.js +20 -41
- package/src/ui/theme.js +429 -392
package/src/ui/screen.js
CHANGED
|
@@ -39,7 +39,7 @@ import chalk from 'chalk';
|
|
|
39
39
|
import {
|
|
40
40
|
theme, blue, sky, deep, dim, edge, ADDED, REMOVED, BANNER, BANNER_WIDTH, SPINNER,
|
|
41
41
|
boxTop, boxBottom, boxRow, visLen, padVis, clip, wrapAnsi,
|
|
42
|
-
shortenPath, asLabel, ensureColour, planLine, bare, narration, narrationMark, groupKind, groupLabel, groupTarget, runLine, planRows,
|
|
42
|
+
shortenPath, asLabel, ensureColour, planLine, bare, narration, narrationMark, groupKind, groupLabel, groupTarget, runLine, planRows, tidyReply } from './theme.js';
|
|
43
43
|
import { FRAME_MS, fitActivity, shimmer, spinnerGlyph, formatDuration, doneLine, stepPaint } from './activity.js';
|
|
44
44
|
import { renderer, render, polish } from './markdown.js';
|
|
45
45
|
import { VERSION } from '../core/version.js';
|
|
@@ -258,7 +258,7 @@ export class Screen {
|
|
|
258
258
|
if (!text?.trim()) return;
|
|
259
259
|
this.endRun();
|
|
260
260
|
this.add('');
|
|
261
|
-
this.add(render(this.md,
|
|
261
|
+
this.add(render(this.md, tidyReply(text)));
|
|
262
262
|
this.add('');
|
|
263
263
|
this.render();
|
|
264
264
|
}
|
|
@@ -541,44 +541,17 @@ export class Screen {
|
|
|
541
541
|
// and the transcript gets one line afterwards saying how long it took.
|
|
542
542
|
|
|
543
543
|
/**
|
|
544
|
-
* The
|
|
544
|
+
* The model's reasoning does not go on screen.
|
|
545
545
|
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
* Written once, never rewritten. Rewriting it as more arrived was the
|
|
552
|
-
* flicker — an unfinished sentence showed as a single word, then jumped.
|
|
546
|
+
* It was surfaced here to fill the wait before the first tool call, and what
|
|
547
|
+
* it actually filled it with was the model talking to itself: "I need to
|
|
548
|
+
* build this", "The user wants a tasks app". Nobody needs their own request
|
|
549
|
+
* read back to them, and half-formed working-out is not something to publish.
|
|
550
|
+
* What the model *says* is its reply, and that is the only thing shown.
|
|
553
551
|
*/
|
|
554
|
-
thinkingDelta(
|
|
555
|
-
if (this.thoughtSince === undefined) this.thoughtSince = Date.now();
|
|
556
|
-
if (!text || this.openedWith) return;
|
|
557
|
-
|
|
558
|
-
this.thought = ((this.thought ?? '') + text).slice(0, 600);
|
|
559
|
-
const tidy = this.thought.replace(/\s+/g, ' ').trim();
|
|
560
|
-
const finished = /^(.+?[.!?])(?:\s|$)/.exec(tidy);
|
|
561
|
-
if (!finished) return;
|
|
552
|
+
thinkingDelta() {}
|
|
562
553
|
|
|
563
|
-
|
|
564
|
-
if (line.length < 12) return; // "Okay." tells nobody anything
|
|
565
|
-
// Reasoning models open by restating the request to themselves — "The user
|
|
566
|
-
// wants a tasks app called Tide" — which the user wrote, is looking at, and
|
|
567
|
-
// does not need read back. Only a sentence about what is being done is
|
|
568
|
-
// worth the line.
|
|
569
|
-
if (RESTATEMENT.test(line)) { this.thought = ''; return; }
|
|
570
|
-
|
|
571
|
-
this.openedWith = line;
|
|
572
|
-
// Full strength: this is the model talking, and it is the thing on the page
|
|
573
|
-
// worth reading. The dimmed lines around it are the machinery.
|
|
574
|
-
this.push(' ' + chalk.white(clip(line, Math.max(30, this.width() - 6))));
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
thinkingEnd() {
|
|
578
|
-
this.thought = '';
|
|
579
|
-
this.openedWith = undefined;
|
|
580
|
-
this.thoughtSince = undefined;
|
|
581
|
-
}
|
|
554
|
+
thinkingEnd() {}
|
|
582
555
|
|
|
583
556
|
error(err, { debug = false } = {}) {
|
|
584
557
|
const known = err && typeof err === 'object' && err.attempted;
|
|
@@ -804,7 +777,9 @@ export class Screen {
|
|
|
804
777
|
const a = this.activity;
|
|
805
778
|
const since = a?.start ?? this.status.since ?? now;
|
|
806
779
|
const meta = [];
|
|
807
|
-
|
|
780
|
+
// No step count. It measures how much machinery ran, which is not
|
|
781
|
+
// something the person waiting has any use for; the elapsed time is.
|
|
782
|
+
void stepPaint;
|
|
808
783
|
if (now - since >= 1000) meta.push({ text: formatDuration(now - since), keep: true });
|
|
809
784
|
middle = fitActivity({
|
|
810
785
|
glyph: spinnerGlyph(this.tick, now),
|
|
@@ -910,9 +885,13 @@ export class Screen {
|
|
|
910
885
|
const a = this.activity;
|
|
911
886
|
this.activity = null;
|
|
912
887
|
if (!this.status.busy) this.stopTimer();
|
|
913
|
-
//
|
|
914
|
-
//
|
|
915
|
-
|
|
888
|
+
// Nothing is written when a turn finishes. The reply is the end of the
|
|
889
|
+
// turn, and a timing line under it is bookkeeping the reader did not ask
|
|
890
|
+
// for. A turn that stopped *without* finishing still says so, because
|
|
891
|
+
// silence there is indistinguishable from a crash.
|
|
892
|
+
if (a && !ok && Date.now() - a.start >= 2000) {
|
|
893
|
+
this.push(` ${doneLine(Date.now() - a.start, a.steps, { ok })}`);
|
|
894
|
+
}
|
|
916
895
|
this.paintStatus();
|
|
917
896
|
}
|
|
918
897
|
|