@oxecli/oxe 1.0.31 → 1.0.33

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/engine.js CHANGED
@@ -49,6 +49,7 @@ export class InferenceEngine {
49
49
  inQuery = false;
50
50
  activeAbort = null;
51
51
  interrupted = false;
52
+ queryHasOutput = false;
52
53
  temperature;
53
54
  storedResponseIds = [];
54
55
  constructor(config) {
@@ -264,6 +265,8 @@ export class InferenceEngine {
264
265
  finishThinking(true);
265
266
  }
266
267
  else if (etype === "response.output_text.delta") {
268
+ if (event.delta)
269
+ this.queryHasOutput = true;
267
270
  reportWorking();
268
271
  finishThinking(true);
269
272
  content += event.delta;
@@ -424,6 +427,7 @@ export class InferenceEngine {
424
427
  async executeQuery(userPrompt, inputItems, story, pasteSpans) {
425
428
  this.inQuery = true;
426
429
  this.interrupted = false;
430
+ this.queryHasOutput = false;
427
431
  this.activeAbort = new AbortController();
428
432
  hideCursor();
429
433
  inputItems.push({
@@ -492,11 +496,15 @@ export class InferenceEngine {
492
496
  respId = res.responseId;
493
497
  }
494
498
  catch (err2) {
499
+ if (this.interrupted)
500
+ throw new Error("interrupt");
495
501
  renderErrorPanel(`API Error: ${err2}`);
496
502
  return;
497
503
  }
498
504
  }
499
505
  else {
506
+ if (this.interrupted)
507
+ throw new Error("interrupt");
500
508
  renderErrorPanel(`API Error: ${err}`);
501
509
  return;
502
510
  }
@@ -535,7 +543,8 @@ export class InferenceEngine {
535
543
  return;
536
544
  }
537
545
  if (!calls.length) {
538
- process.stdout.write("\n" + summary() + "\n");
546
+ const gap = text.endsWith("\n\n") ? "" : text.endsWith("\n") ? "\n" : "\n\n";
547
+ process.stdout.write(gap + summary() + "\n");
539
548
  story.push({ type: "footer", text: footerText() });
540
549
  attachFooter(conversation);
541
550
  attachFooter(inputItems);
@@ -582,6 +591,15 @@ export class InferenceEngine {
582
591
  stripOrphanCalls(inputItems);
583
592
  }
584
593
  catch (err) {
594
+ if (this.interrupted && !this.queryHasOutput) {
595
+ const fallback = "What else can I help with?";
596
+ process.stdout.write(aiMarkdown(fallback) + "\n\n" + summary() + "\n");
597
+ story.push({ type: "assistant", text: fallback });
598
+ story.push({ type: "footer", text: footerText() });
599
+ attachFooter(conversation);
600
+ attachFooter(inputItems);
601
+ return;
602
+ }
585
603
  if (this.interrupted)
586
604
  throw new Error("interrupt");
587
605
  if (err?.message === "interrupt" || err?.message === "eof") {
@@ -611,6 +629,5 @@ export class InferenceEngine {
611
629
  function renderErrorPanel(msg) {
612
630
  const text = msg.replace(/\[bold yellow\]|\[yellow\]|\[\/.*?\]/g, "");
613
631
  renderPanel(text, "Error", "", true, "31");
614
- process.stdout.write("\n");
615
632
  }
616
633
  export { renderErrorPanel };
package/dist/ui.js CHANGED
@@ -118,7 +118,41 @@ export function markupToAnsi(text) {
118
118
  // Lightweight markdown -> ANSI
119
119
  // ---------------------------------------------------------------------------
120
120
  export function markdownToAnsi(text) {
121
- const lines = text.split("\n");
121
+ const width = Math.max(terminalWidth() || 80, 1);
122
+ const lines = text.split("\n").flatMap((raw) => {
123
+ if (!raw || raw.length <= width)
124
+ return [raw];
125
+ const indent = raw.match(/^\s*/)?.[0] ?? "";
126
+ const words = raw.trim().split(/\s+/);
127
+ const wrapped = [];
128
+ let current = indent;
129
+ for (const word of words) {
130
+ if (word.length > width) {
131
+ if (current.trim())
132
+ wrapped.push(current);
133
+ current = "";
134
+ for (let i = 0; i < word.length; i += width) {
135
+ const part = word.slice(i, i + width);
136
+ if (part.length === width)
137
+ wrapped.push(part);
138
+ else
139
+ current = part;
140
+ }
141
+ continue;
142
+ }
143
+ const next = current.trim() ? `${current} ${word}` : `${current}${word}`;
144
+ if (current.trim() && next.length > width) {
145
+ wrapped.push(current);
146
+ current = `${indent}${word}`;
147
+ }
148
+ else {
149
+ current = next;
150
+ }
151
+ }
152
+ if (current || !wrapped.length)
153
+ wrapped.push(current);
154
+ return wrapped;
155
+ });
122
156
  const out = [];
123
157
  let inCode = false;
124
158
  let codeBuf = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },