@oxecli/oxe 1.0.13 → 1.0.15
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 +32 -5
- package/dist/tools.js +1 -0
- package/dist/ui.js +52 -6
- package/package.json +1 -1
package/dist/engine.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
import { max_output_tokens, max_empty_retries, max_agent_steps, max_context_tokens, context_overhead_margin, compact_keep_recent_turns, max_summary_source_chars, max_read_file_stored_chars, } from "./config.js";
|
|
3
3
|
import { SYSTEM_PROMPT } from "./system.js";
|
|
4
|
-
import { buildTools, truncateToolOutput,
|
|
4
|
+
import { buildTools, truncateToolOutput, toolReadFile, toolWriteFile, toolEditFile, toolBash, toolGlob, toolGrep, toolLoadSkill, } from "./tools.js";
|
|
5
5
|
import { mutedMarkdown, aiMarkdown, tickDuration, displayRows, safeCommitPoint, printAiChunk, formatToolAction, renderPanel, Spinner, hideCursor, } from "./ui.js";
|
|
6
6
|
import { reportUsage } from "./api.js";
|
|
7
7
|
import { stripOrphanCalls, persistCompactionSummary, toolOutputFailed, } from "./sessions.js";
|
|
@@ -83,10 +83,37 @@ export class InferenceEngine {
|
|
|
83
83
|
args = {};
|
|
84
84
|
}
|
|
85
85
|
try {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
// Dispatch by explicit named parameters. Do NOT use Object.values(args)
|
|
87
|
+
// (order-dependent): JSON object key order is not guaranteed, and when a
|
|
88
|
+
// model emits e.g. {content, path} for write_file the content would be
|
|
89
|
+
// mistaken for the path (turning JSX "/" into "\" on Windows). Binding
|
|
90
|
+
// each argument by name makes the tools robust to any key ordering.
|
|
91
|
+
let result;
|
|
92
|
+
switch (name) {
|
|
93
|
+
case "read_file":
|
|
94
|
+
result = toolReadFile(args.path, args.start_line, args.end_line);
|
|
95
|
+
break;
|
|
96
|
+
case "write_file":
|
|
97
|
+
result = toolWriteFile(args.path, args.content);
|
|
98
|
+
break;
|
|
99
|
+
case "edit_file":
|
|
100
|
+
result = toolEditFile(args.path, args.old_string, args.new_string, args.replace_all);
|
|
101
|
+
break;
|
|
102
|
+
case "bash":
|
|
103
|
+
result = await toolBash(args.command, args.timeout, args.cwd);
|
|
104
|
+
break;
|
|
105
|
+
case "glob":
|
|
106
|
+
result = toolGlob(args.pattern, args.path, args.limit);
|
|
107
|
+
break;
|
|
108
|
+
case "grep":
|
|
109
|
+
result = toolGrep(args.pattern, args.path, args.glob, args.limit);
|
|
110
|
+
break;
|
|
111
|
+
case "load_skill":
|
|
112
|
+
result = toolLoadSkill(args.skill_name);
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
return `Error: unknown tool '${name}'`;
|
|
116
|
+
}
|
|
90
117
|
return typeof result === "string" ? result : String(result);
|
|
91
118
|
}
|
|
92
119
|
catch (err) {
|
package/dist/tools.js
CHANGED
|
@@ -4,6 +4,7 @@ import { execFile, spawn } from "node:child_process";
|
|
|
4
4
|
import { structuredPatch } from "diff";
|
|
5
5
|
import { max_diff_source_chars, max_diff_lines, max_diff_context_lines, max_diff_line_chars, max_read_line_chars, max_read_file_bytes, max_read_lines, max_output_chars, max_bash_timeout_seconds, max_grep_file_bytes, strict_max_properties, ignoredDirs, } from "./config.js";
|
|
6
6
|
import { toolLoadSkill } from "./skills.js";
|
|
7
|
+
export { toolLoadSkill };
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
8
9
|
// Natural sort + diff helpers
|
|
9
10
|
// ---------------------------------------------------------------------------
|
package/dist/ui.js
CHANGED
|
@@ -670,12 +670,37 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
670
670
|
return;
|
|
671
671
|
}
|
|
672
672
|
};
|
|
673
|
-
const
|
|
673
|
+
const shiftSpansAfterInsert = (pos, delta) => {
|
|
674
|
+
const newSpans = [];
|
|
675
|
+
for (const [s, e] of pasteSpans) {
|
|
676
|
+
if (pos <= s)
|
|
677
|
+
newSpans.push([s + delta, e + delta]);
|
|
678
|
+
else if (pos >= e)
|
|
679
|
+
newSpans.push([s, e]);
|
|
680
|
+
else {
|
|
681
|
+
newSpans.push([s, pos]);
|
|
682
|
+
newSpans.push([pos + delta, e + delta]);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return newSpans;
|
|
686
|
+
};
|
|
687
|
+
const insert = (text, isPaste = false) => {
|
|
674
688
|
if (histIdx !== hist.length) {
|
|
675
689
|
draft = { buffer, cursor, spans: pasteSpans.slice() };
|
|
676
690
|
histIdx = hist.length;
|
|
677
691
|
}
|
|
692
|
+
const pasteStart = cursor;
|
|
678
693
|
buffer = buffer.slice(0, cursor) + text + buffer.slice(cursor);
|
|
694
|
+
// Keep existing paste spans valid across the insertion point.
|
|
695
|
+
pasteSpans = shiftSpansAfterInsert(cursor, text.length);
|
|
696
|
+
// A real paste records a span so the prompt box can collapse it (mirrors
|
|
697
|
+
// Python's handle_paste). splitBlocks only collapses segments inside a
|
|
698
|
+
// span that meet the threshold, so small pastes stay expanded but remain
|
|
699
|
+
// tagged for cursor/backspace handling.
|
|
700
|
+
if (isPaste) {
|
|
701
|
+
pasteSpans.push([pasteStart, pasteStart + text.length]);
|
|
702
|
+
pasteSpans.sort((a, b) => a[0] - b[0]);
|
|
703
|
+
}
|
|
679
704
|
cursor += text.length;
|
|
680
705
|
};
|
|
681
706
|
const backspace = () => {
|
|
@@ -689,7 +714,25 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
689
714
|
const before = Array.from(buffer.slice(0, cursor));
|
|
690
715
|
before.pop();
|
|
691
716
|
buffer = before.join("") + buffer.slice(cursor);
|
|
717
|
+
const deletedAt = cursor - 1;
|
|
692
718
|
cursor -= 1;
|
|
719
|
+
// Adjust spans: shrink any span covering the deleted char, shift spans
|
|
720
|
+
// that start after it left by one.
|
|
721
|
+
const adjusted = [];
|
|
722
|
+
for (const [s, e] of pasteSpans) {
|
|
723
|
+
if (deletedAt >= s && deletedAt < e) {
|
|
724
|
+
const ne = e - 1;
|
|
725
|
+
if (s < ne)
|
|
726
|
+
adjusted.push([s, ne]);
|
|
727
|
+
}
|
|
728
|
+
else if (deletedAt < s) {
|
|
729
|
+
adjusted.push([s - 1, e - 1]);
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
adjusted.push([s, e]);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
pasteSpans = adjusted.filter(([s, e]) => s < e);
|
|
693
736
|
};
|
|
694
737
|
const moveLeft = () => {
|
|
695
738
|
if (cursor > 0)
|
|
@@ -782,8 +825,9 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
782
825
|
return;
|
|
783
826
|
}
|
|
784
827
|
if (str) {
|
|
785
|
-
// paste
|
|
786
|
-
|
|
828
|
+
// Multi-char sequence = a paste (single-char typed keys arrive one per
|
|
829
|
+
// event). Tag it so the prompt box collapses it when it meets the rules.
|
|
830
|
+
insert(str, str.length > 1);
|
|
787
831
|
repaint();
|
|
788
832
|
}
|
|
789
833
|
};
|
|
@@ -795,6 +839,11 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
795
839
|
// User display + message text
|
|
796
840
|
// ---------------------------------------------------------------------------
|
|
797
841
|
export function userDisplayText(payload, pasteSpans) {
|
|
842
|
+
// Mirror the prompt field exactly: collapse ONLY segments that fall inside a
|
|
843
|
+
// paste span and exceed the collapse threshold (via splitBlocks). Content that
|
|
844
|
+
// the user typed (no paste span) is never collapsed in the prompt, so it must
|
|
845
|
+
// not be collapsed here either — keeping the echoed message consistent with
|
|
846
|
+
// what the prompt box displayed.
|
|
798
847
|
if (pasteSpans && pasteSpans.length) {
|
|
799
848
|
const segs = splitBlocks(payload, pasteSpans);
|
|
800
849
|
let out = "";
|
|
@@ -806,9 +855,6 @@ export function userDisplayText(payload, pasteSpans) {
|
|
|
806
855
|
}
|
|
807
856
|
return out;
|
|
808
857
|
}
|
|
809
|
-
if (shouldCollapsePaste(payload)) {
|
|
810
|
-
return `\x1b[1m\x1b[36m[Pasted text, ${payload.split("\n").length} lines]\x1b[0m`;
|
|
811
|
-
}
|
|
812
858
|
return payload;
|
|
813
859
|
}
|
|
814
860
|
export function collapseLabelText(text, spans) {
|