@oxecli/oxe 1.0.27 → 1.0.28
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 +17 -6
- package/dist/engine.js +18 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -58,9 +58,8 @@ export class CLI {
|
|
|
58
58
|
titleAlign: "left",
|
|
59
59
|
colGap: 2,
|
|
60
60
|
});
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
process.stdout.write(panel + "\n");
|
|
61
|
+
// Keep one blank row between the previous response/footer and the panel.
|
|
62
|
+
process.stdout.write("\n" + panel + "\n");
|
|
64
63
|
if (process.stdin.isTTY) {
|
|
65
64
|
// Wait for a close key, then erase the panel (mirrors Python's Live).
|
|
66
65
|
enableRawStdin();
|
|
@@ -336,6 +335,7 @@ export class CLI {
|
|
|
336
335
|
for (;;) {
|
|
337
336
|
engine.inQuery = false;
|
|
338
337
|
let rawPrompt;
|
|
338
|
+
let queryStarted = false;
|
|
339
339
|
try {
|
|
340
340
|
const [input, spans] = await askBottomPrompt("You", "❯", this.promptHistory);
|
|
341
341
|
if (!input.trim())
|
|
@@ -390,7 +390,9 @@ export class CLI {
|
|
|
390
390
|
continue;
|
|
391
391
|
}
|
|
392
392
|
process.stdout.write(`\n\x1b[1m❯\x1b[0m ${userDisplayText(input, spans)}\n\n`);
|
|
393
|
+
queryStarted = true;
|
|
393
394
|
await engine.executeQuery(input, this.inputItems, this.story, spans);
|
|
395
|
+
queryStarted = false;
|
|
394
396
|
this.saveSession(engine);
|
|
395
397
|
}
|
|
396
398
|
catch (err) {
|
|
@@ -401,7 +403,7 @@ export class CLI {
|
|
|
401
403
|
break;
|
|
402
404
|
}
|
|
403
405
|
if (err?.message === "interrupt") {
|
|
404
|
-
const wasActive = engine.inQuery;
|
|
406
|
+
const wasActive = queryStarted || engine.inQuery;
|
|
405
407
|
engine.inQuery = false;
|
|
406
408
|
// Drop the pending user message/story entry that was never run.
|
|
407
409
|
if (this.inputItems.length && this.inputItems[this.inputItems.length - 1]["role"] === "user") {
|
|
@@ -422,8 +424,8 @@ export class CLI {
|
|
|
422
424
|
// (mirrors Python's console.print()).
|
|
423
425
|
process.stdout.write("\n");
|
|
424
426
|
process.stdout.write(wasActive
|
|
425
|
-
? "\x1b[2mInterrupted. Press Ctrl+C again to
|
|
426
|
-
: "\x1b[2mNo active response. Press Ctrl+C again to
|
|
427
|
+
? "\x1b[2mInterrupted agent. Press Ctrl+C again to close the app, or type a new prompt.\x1b[0m\n"
|
|
428
|
+
: "\x1b[2mNo active response. Press Ctrl+C again to close the app, or type a new prompt.\x1b[0m\n");
|
|
427
429
|
continue;
|
|
428
430
|
}
|
|
429
431
|
throw err;
|
|
@@ -451,10 +453,19 @@ export async function main() {
|
|
|
451
453
|
}
|
|
452
454
|
app.config = config;
|
|
453
455
|
const engine = new InferenceEngine(config);
|
|
456
|
+
const onInterrupt = () => {
|
|
457
|
+
if (engine.inQuery) {
|
|
458
|
+
engine.interrupt();
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
process.exit(130);
|
|
462
|
+
};
|
|
463
|
+
process.on("SIGINT", onInterrupt);
|
|
454
464
|
try {
|
|
455
465
|
await app.replLoop(engine);
|
|
456
466
|
}
|
|
457
467
|
finally {
|
|
468
|
+
process.removeListener("SIGINT", onInterrupt);
|
|
458
469
|
await engine.cleanupStoredResponses();
|
|
459
470
|
const client = engine.client;
|
|
460
471
|
if (typeof client?.close === "function")
|
package/dist/engine.js
CHANGED
|
@@ -47,6 +47,8 @@ export class InferenceEngine {
|
|
|
47
47
|
workActive = false;
|
|
48
48
|
workRows = 2;
|
|
49
49
|
inQuery = false;
|
|
50
|
+
activeAbort = null;
|
|
51
|
+
interrupted = false;
|
|
50
52
|
temperature;
|
|
51
53
|
storedResponseIds = [];
|
|
52
54
|
constructor(config) {
|
|
@@ -62,6 +64,10 @@ export class InferenceEngine {
|
|
|
62
64
|
});
|
|
63
65
|
this.temperature = config["temperature"] ?? null;
|
|
64
66
|
}
|
|
67
|
+
interrupt() {
|
|
68
|
+
this.interrupted = true;
|
|
69
|
+
this.activeAbort?.abort();
|
|
70
|
+
}
|
|
65
71
|
async cleanupStoredResponses() {
|
|
66
72
|
const ids = this.storedResponseIds;
|
|
67
73
|
this.storedResponseIds = [];
|
|
@@ -233,8 +239,12 @@ export class InferenceEngine {
|
|
|
233
239
|
kwargs["temperature"] = this.temperature;
|
|
234
240
|
if (previousResponseId)
|
|
235
241
|
kwargs["previous_response_id"] = previousResponseId;
|
|
236
|
-
const stream = await this.client.responses.create(kwargs
|
|
242
|
+
const stream = await this.client.responses.create(kwargs, {
|
|
243
|
+
signal: this.activeAbort?.signal,
|
|
244
|
+
});
|
|
237
245
|
for await (const event of stream) {
|
|
246
|
+
if (this.interrupted)
|
|
247
|
+
throw new Error("interrupt");
|
|
238
248
|
etype = event.type;
|
|
239
249
|
if (etype === "response.reasoning_text.delta" ||
|
|
240
250
|
etype === "response.reasoning.summary.delta") {
|
|
@@ -413,6 +423,8 @@ export class InferenceEngine {
|
|
|
413
423
|
}
|
|
414
424
|
async executeQuery(userPrompt, inputItems, story, pasteSpans) {
|
|
415
425
|
this.inQuery = true;
|
|
426
|
+
this.interrupted = false;
|
|
427
|
+
this.activeAbort = new AbortController();
|
|
416
428
|
hideCursor();
|
|
417
429
|
inputItems.push({
|
|
418
430
|
role: "user",
|
|
@@ -538,6 +550,8 @@ export class InferenceEngine {
|
|
|
538
550
|
if (c.name === "edit_file" || c.name === "write_file")
|
|
539
551
|
process.stdout.write("\n");
|
|
540
552
|
const rawResult = await this.runTool(c.name, c.arguments);
|
|
553
|
+
if (this.interrupted)
|
|
554
|
+
throw new Error("interrupt");
|
|
541
555
|
const failed = toolOutputFailed(c.name, rawResult);
|
|
542
556
|
const action = formatToolAction(c.name, c.arguments, failed ? "failed" : "ok");
|
|
543
557
|
story.push({ type: "tool", started, text: action, status: failed ? "failed" : "ok" });
|
|
@@ -568,6 +582,8 @@ export class InferenceEngine {
|
|
|
568
582
|
stripOrphanCalls(inputItems);
|
|
569
583
|
}
|
|
570
584
|
catch (err) {
|
|
585
|
+
if (this.interrupted)
|
|
586
|
+
throw new Error("interrupt");
|
|
571
587
|
if (err?.message === "interrupt" || err?.message === "eof") {
|
|
572
588
|
throw err;
|
|
573
589
|
}
|
|
@@ -575,6 +591,7 @@ export class InferenceEngine {
|
|
|
575
591
|
}
|
|
576
592
|
finally {
|
|
577
593
|
this.inQuery = false;
|
|
594
|
+
this.activeAbort = null;
|
|
578
595
|
if (stats["tokens"] > 0 && this.keyData) {
|
|
579
596
|
const userId = this.keyData["user_id"];
|
|
580
597
|
if (userId) {
|