@oxecli/oxe 1.0.34 → 1.0.36
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/cli.js +20 -5
- package/dist/engine.js +12 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -42,6 +42,20 @@ export class CLI {
|
|
|
42
42
|
const style = status === "failed" ? "\x1b[31m" : "\x1b[32m";
|
|
43
43
|
process.stdout.write(`${style}${truncateEllipsis(String(text), max_action_chars, "text")}\x1b[0m\n`);
|
|
44
44
|
}
|
|
45
|
+
printAssistantBlock(text) {
|
|
46
|
+
const rendered = aiMarkdown(text);
|
|
47
|
+
process.stdout.write(rendered);
|
|
48
|
+
if (!text.endsWith("\n"))
|
|
49
|
+
process.stdout.write("\n");
|
|
50
|
+
}
|
|
51
|
+
printFooterAfter(text, footer) {
|
|
52
|
+
const trailing = text.match(/\n*$/)?.[0].length ?? 0;
|
|
53
|
+
if (trailing < 2)
|
|
54
|
+
process.stdout.write("\n".repeat(2 - trailing));
|
|
55
|
+
process.stdout.write(aiMarkdown(footer));
|
|
56
|
+
if (!footer.endsWith("\n"))
|
|
57
|
+
process.stdout.write("\n");
|
|
58
|
+
}
|
|
45
59
|
async showHelp() {
|
|
46
60
|
// Mirror Python's `_show_help`: a bordered table panel with the command
|
|
47
61
|
// column bold (with `<arg>` placeholders cyan) and descriptions dim, inside
|
|
@@ -76,7 +90,9 @@ export class CLI {
|
|
|
76
90
|
// clear downward so the whole panel disappears and the cursor lands back
|
|
77
91
|
// on the fresh line before the prompt.
|
|
78
92
|
const n = panel.split("\n").length;
|
|
79
|
-
|
|
93
|
+
// Include the leading separator row in the cleanup so the next prompt
|
|
94
|
+
// creates exactly one fresh separator instead of duplicating it.
|
|
95
|
+
process.stdout.write(`\x1b[${n + 1}A\r\x1b[J`);
|
|
80
96
|
}
|
|
81
97
|
}
|
|
82
98
|
async awaitRawCloseKey() {
|
|
@@ -141,13 +157,12 @@ export class CLI {
|
|
|
141
157
|
process.stdout.write(`\x1b[1m❯\x1b[0m ${userDisplayText(payload, r["paste_spans"])}\n`);
|
|
142
158
|
}
|
|
143
159
|
else if (kind === "assistant") {
|
|
144
|
-
|
|
160
|
+
this.printAssistantBlock(payload);
|
|
145
161
|
let footer = String(r["footer"] ?? "").trim();
|
|
146
162
|
if (footer) {
|
|
147
163
|
if (!footer.startsWith("("))
|
|
148
164
|
footer = `(${footer})`;
|
|
149
|
-
|
|
150
|
-
process.stdout.write("\n" + aiMarkdown(footer) + "\n");
|
|
165
|
+
this.printFooterAfter(payload, footer);
|
|
151
166
|
}
|
|
152
167
|
}
|
|
153
168
|
else {
|
|
@@ -173,7 +188,7 @@ export class CLI {
|
|
|
173
188
|
process.stdout.write(`\x1b[1m❯\x1b[0m ${userDisplayText(text, e["paste_spans"])}\n`);
|
|
174
189
|
}
|
|
175
190
|
else if (typ === "assistant") {
|
|
176
|
-
|
|
191
|
+
this.printAssistantBlock(text);
|
|
177
192
|
}
|
|
178
193
|
else if (typ === "tool") {
|
|
179
194
|
this.printToolEntry(e["started"], text, e["status"] ?? "");
|
package/dist/engine.js
CHANGED
|
@@ -438,6 +438,10 @@ export class InferenceEngine {
|
|
|
438
438
|
}
|
|
439
439
|
async executeQuery(userPrompt, inputItems, story, pasteSpans) {
|
|
440
440
|
this.inQuery = true;
|
|
441
|
+
// A completed status line belongs to the previous turn. Never let its
|
|
442
|
+
// replacement state reach the next user prompt.
|
|
443
|
+
this.workActive = false;
|
|
444
|
+
this.workRows = 0;
|
|
441
445
|
this.interrupted = false;
|
|
442
446
|
this.queryHasOutput = false;
|
|
443
447
|
this.activeAbort = new AbortController();
|
|
@@ -552,6 +556,8 @@ export class InferenceEngine {
|
|
|
552
556
|
dropRetryPrompts(conversation, inputItems, retryPrompts);
|
|
553
557
|
process.stdout.write(aiMarkdown(emptyMessage) + "\n");
|
|
554
558
|
process.stdout.write("\n" + summary() + "\n");
|
|
559
|
+
this.workActive = false;
|
|
560
|
+
this.workRows = 0;
|
|
555
561
|
return;
|
|
556
562
|
}
|
|
557
563
|
if (!calls.length) {
|
|
@@ -560,6 +566,8 @@ export class InferenceEngine {
|
|
|
560
566
|
story.push({ type: "footer", text: footerText() });
|
|
561
567
|
attachFooter(conversation);
|
|
562
568
|
attachFooter(inputItems);
|
|
569
|
+
this.workActive = false;
|
|
570
|
+
this.workRows = 0;
|
|
563
571
|
return;
|
|
564
572
|
}
|
|
565
573
|
if (text.trim())
|
|
@@ -603,6 +611,10 @@ export class InferenceEngine {
|
|
|
603
611
|
stripOrphanCalls(inputItems);
|
|
604
612
|
}
|
|
605
613
|
catch (err) {
|
|
614
|
+
if (this.interrupted) {
|
|
615
|
+
this.workActive = false;
|
|
616
|
+
this.workRows = 0;
|
|
617
|
+
}
|
|
606
618
|
if (this.interrupted)
|
|
607
619
|
throw new Error("interrupt");
|
|
608
620
|
if (err?.message === "interrupt" || err?.message === "eof") {
|