open-agents-ai 0.138.81 → 0.138.82
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/index.js +516 -42
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22304,6 +22304,10 @@ var init_agenticRunner = __esm({
|
|
|
22304
22304
|
get taskState() {
|
|
22305
22305
|
return this._taskState;
|
|
22306
22306
|
}
|
|
22307
|
+
/** Get the backend (for post-task LLM extraction calls) */
|
|
22308
|
+
getBackend() {
|
|
22309
|
+
return this.backend;
|
|
22310
|
+
}
|
|
22307
22311
|
/** Get the file state registry (for external inspection) */
|
|
22308
22312
|
get fileRegistry() {
|
|
22309
22313
|
return this._fileRegistry;
|
|
@@ -43885,7 +43889,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
43885
43889
|
}
|
|
43886
43890
|
}
|
|
43887
43891
|
async function handleParallel(arg, ctx) {
|
|
43888
|
-
const { execSync:
|
|
43892
|
+
const { execSync: execSync31 } = await import("node:child_process");
|
|
43889
43893
|
const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
|
|
43890
43894
|
const isRemote = ctx.config.backendType === "nexus";
|
|
43891
43895
|
if (isRemote) {
|
|
@@ -43909,7 +43913,7 @@ async function handleParallel(arg, ctx) {
|
|
|
43909
43913
|
}
|
|
43910
43914
|
let systemdVal = "";
|
|
43911
43915
|
try {
|
|
43912
|
-
const out =
|
|
43916
|
+
const out = execSync31("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
43913
43917
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
43914
43918
|
if (match)
|
|
43915
43919
|
systemdVal = match[1];
|
|
@@ -43938,7 +43942,7 @@ async function handleParallel(arg, ctx) {
|
|
|
43938
43942
|
}
|
|
43939
43943
|
const isSystemd = (() => {
|
|
43940
43944
|
try {
|
|
43941
|
-
const out =
|
|
43945
|
+
const out = execSync31("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
43942
43946
|
return out === "active" || out === "inactive";
|
|
43943
43947
|
} catch {
|
|
43944
43948
|
return false;
|
|
@@ -43952,10 +43956,10 @@ async function handleParallel(arg, ctx) {
|
|
|
43952
43956
|
const overrideContent = `[Service]
|
|
43953
43957
|
Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
43954
43958
|
`;
|
|
43955
|
-
|
|
43956
|
-
|
|
43957
|
-
|
|
43958
|
-
|
|
43959
|
+
execSync31(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
43960
|
+
execSync31(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
43961
|
+
execSync31("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
43962
|
+
execSync31("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
43959
43963
|
let ready = false;
|
|
43960
43964
|
for (let i = 0; i < 30 && !ready; i++) {
|
|
43961
43965
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -43982,7 +43986,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
43982
43986
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
|
|
43983
43987
|
try {
|
|
43984
43988
|
try {
|
|
43985
|
-
|
|
43989
|
+
execSync31("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
43986
43990
|
} catch {
|
|
43987
43991
|
}
|
|
43988
43992
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -44734,18 +44738,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
44734
44738
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
44735
44739
|
let copied = false;
|
|
44736
44740
|
try {
|
|
44737
|
-
const { execSync:
|
|
44741
|
+
const { execSync: execSync31 } = __require("node:child_process");
|
|
44738
44742
|
const platform5 = process.platform;
|
|
44739
44743
|
if (platform5 === "darwin") {
|
|
44740
|
-
|
|
44744
|
+
execSync31("pbcopy", { input: cmd, timeout: 3e3 });
|
|
44741
44745
|
copied = true;
|
|
44742
44746
|
} else if (platform5 === "win32") {
|
|
44743
|
-
|
|
44747
|
+
execSync31("clip", { input: cmd, timeout: 3e3 });
|
|
44744
44748
|
copied = true;
|
|
44745
44749
|
} else {
|
|
44746
44750
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
44747
44751
|
try {
|
|
44748
|
-
|
|
44752
|
+
execSync31(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
44749
44753
|
copied = true;
|
|
44750
44754
|
break;
|
|
44751
44755
|
} catch {
|
|
@@ -52183,15 +52187,301 @@ var init_system_metrics = __esm({
|
|
|
52183
52187
|
}
|
|
52184
52188
|
});
|
|
52185
52189
|
|
|
52190
|
+
// packages/cli/dist/tui/text-selection.js
|
|
52191
|
+
import { execSync as execSync29 } from "node:child_process";
|
|
52192
|
+
function stripAnsi3(s) {
|
|
52193
|
+
return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
52194
|
+
}
|
|
52195
|
+
function visibleLength(s) {
|
|
52196
|
+
return stripAnsi3(s).length;
|
|
52197
|
+
}
|
|
52198
|
+
function copyText(text) {
|
|
52199
|
+
try {
|
|
52200
|
+
const platform5 = process.platform;
|
|
52201
|
+
if (platform5 === "darwin") {
|
|
52202
|
+
execSync29("pbcopy", { input: text, timeout: 3e3 });
|
|
52203
|
+
return true;
|
|
52204
|
+
}
|
|
52205
|
+
if (platform5 === "win32") {
|
|
52206
|
+
execSync29("clip", { input: text, timeout: 3e3 });
|
|
52207
|
+
return true;
|
|
52208
|
+
}
|
|
52209
|
+
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
52210
|
+
try {
|
|
52211
|
+
execSync29(tool, { input: text, timeout: 3e3 });
|
|
52212
|
+
return true;
|
|
52213
|
+
} catch {
|
|
52214
|
+
continue;
|
|
52215
|
+
}
|
|
52216
|
+
}
|
|
52217
|
+
} catch {
|
|
52218
|
+
}
|
|
52219
|
+
try {
|
|
52220
|
+
const b64 = Buffer.from(text).toString("base64");
|
|
52221
|
+
process.stdout.write(`\x1B]52;c;${b64}\x07`);
|
|
52222
|
+
return true;
|
|
52223
|
+
} catch {
|
|
52224
|
+
}
|
|
52225
|
+
return false;
|
|
52226
|
+
}
|
|
52227
|
+
function computeHeaderButtons(termWidth) {
|
|
52228
|
+
const buttons = ["/help", "/voice", "/cohere", "/model"];
|
|
52229
|
+
const GAP = 2;
|
|
52230
|
+
const result = [];
|
|
52231
|
+
let col = termWidth - 1;
|
|
52232
|
+
for (let i = buttons.length - 1; i >= 0; i--) {
|
|
52233
|
+
const label = ` ${buttons[i]} `;
|
|
52234
|
+
const endCol = col;
|
|
52235
|
+
const startCol = col - label.length + 1;
|
|
52236
|
+
if (startCol < 1)
|
|
52237
|
+
break;
|
|
52238
|
+
result.unshift({
|
|
52239
|
+
label,
|
|
52240
|
+
command: buttons[i],
|
|
52241
|
+
startCol,
|
|
52242
|
+
endCol,
|
|
52243
|
+
row: 3
|
|
52244
|
+
});
|
|
52245
|
+
col = startCol - GAP - 1;
|
|
52246
|
+
}
|
|
52247
|
+
return result;
|
|
52248
|
+
}
|
|
52249
|
+
function renderHeaderButtons(termWidth) {
|
|
52250
|
+
const buttons = computeHeaderButtons(termWidth);
|
|
52251
|
+
if (buttons.length === 0)
|
|
52252
|
+
return "";
|
|
52253
|
+
let out = "";
|
|
52254
|
+
for (const btn of buttons) {
|
|
52255
|
+
out += `\x1B[${btn.row};${btn.startCol}H`;
|
|
52256
|
+
out += `\x1B[1;${SEL_FG}m\x1B[48;5;${SEL_BG}m${btn.label}\x1B[0m`;
|
|
52257
|
+
}
|
|
52258
|
+
return out;
|
|
52259
|
+
}
|
|
52260
|
+
function hitTestHeaderButton(row, col, termWidth) {
|
|
52261
|
+
const buttons = computeHeaderButtons(termWidth);
|
|
52262
|
+
for (const btn of buttons) {
|
|
52263
|
+
if (row === btn.row && col >= btn.startCol && col <= btn.endCol) {
|
|
52264
|
+
return btn.command;
|
|
52265
|
+
}
|
|
52266
|
+
}
|
|
52267
|
+
return null;
|
|
52268
|
+
}
|
|
52269
|
+
var SEL_BG, SEL_FG, SEL_START, SEL_END, TextSelection;
|
|
52270
|
+
var init_text_selection = __esm({
|
|
52271
|
+
"packages/cli/dist/tui/text-selection.js"() {
|
|
52272
|
+
"use strict";
|
|
52273
|
+
SEL_BG = 178;
|
|
52274
|
+
SEL_FG = 30;
|
|
52275
|
+
SEL_START = `\x1B[${SEL_FG}m\x1B[48;5;${SEL_BG}m`;
|
|
52276
|
+
SEL_END = `\x1B[0m`;
|
|
52277
|
+
TextSelection = class {
|
|
52278
|
+
_selection = null;
|
|
52279
|
+
_active = false;
|
|
52280
|
+
// true while mouse button is held
|
|
52281
|
+
_blockModeArmed = false;
|
|
52282
|
+
// Ctrl+Shift+B pressed, next click starts block select
|
|
52283
|
+
_provider;
|
|
52284
|
+
constructor(provider) {
|
|
52285
|
+
this._provider = provider;
|
|
52286
|
+
}
|
|
52287
|
+
/** Whether a selection currently exists */
|
|
52288
|
+
get hasSelection() {
|
|
52289
|
+
return this._selection !== null;
|
|
52290
|
+
}
|
|
52291
|
+
/** Whether we're actively dragging */
|
|
52292
|
+
get isDragging() {
|
|
52293
|
+
return this._active;
|
|
52294
|
+
}
|
|
52295
|
+
/** Get the current selection range (or null) */
|
|
52296
|
+
get selection() {
|
|
52297
|
+
return this._selection;
|
|
52298
|
+
}
|
|
52299
|
+
/** Arm block selection mode — next click starts rectangular select */
|
|
52300
|
+
armBlockMode() {
|
|
52301
|
+
this._blockModeArmed = true;
|
|
52302
|
+
}
|
|
52303
|
+
/** Clear the current selection */
|
|
52304
|
+
clear() {
|
|
52305
|
+
this._selection = null;
|
|
52306
|
+
this._active = false;
|
|
52307
|
+
this._blockModeArmed = false;
|
|
52308
|
+
}
|
|
52309
|
+
/**
|
|
52310
|
+
* Handle mouse press (button 0, M suffix in SGR).
|
|
52311
|
+
* Starts a new selection from the click position.
|
|
52312
|
+
*/
|
|
52313
|
+
onMousePress(row, col) {
|
|
52314
|
+
const mode = this._blockModeArmed ? "block" : "line";
|
|
52315
|
+
this._blockModeArmed = false;
|
|
52316
|
+
this._selection = {
|
|
52317
|
+
anchor: { row, col },
|
|
52318
|
+
current: { row, col },
|
|
52319
|
+
mode
|
|
52320
|
+
};
|
|
52321
|
+
this._active = true;
|
|
52322
|
+
}
|
|
52323
|
+
/**
|
|
52324
|
+
* Handle mouse drag (button 32, M suffix in SGR).
|
|
52325
|
+
* Extends the selection to the current cursor position.
|
|
52326
|
+
*/
|
|
52327
|
+
onMouseDrag(row, col) {
|
|
52328
|
+
if (!this._active || !this._selection)
|
|
52329
|
+
return;
|
|
52330
|
+
this._selection.current = { row, col };
|
|
52331
|
+
}
|
|
52332
|
+
/**
|
|
52333
|
+
* Handle mouse release (button 0, m suffix in SGR).
|
|
52334
|
+
* Finalizes the selection.
|
|
52335
|
+
*/
|
|
52336
|
+
onMouseRelease(row, col) {
|
|
52337
|
+
if (!this._active || !this._selection)
|
|
52338
|
+
return;
|
|
52339
|
+
this._selection.current = { row, col };
|
|
52340
|
+
this._active = false;
|
|
52341
|
+
if (this._selection.anchor.row === this._selection.current.row && this._selection.anchor.col === this._selection.current.col) {
|
|
52342
|
+
this._selection = null;
|
|
52343
|
+
}
|
|
52344
|
+
}
|
|
52345
|
+
/**
|
|
52346
|
+
* Compute which content buffer indices and column ranges are selected.
|
|
52347
|
+
* Returns an array of { bufferIdx, startCol, endCol } for each selected line.
|
|
52348
|
+
* Columns are 0-based visible character positions.
|
|
52349
|
+
*/
|
|
52350
|
+
getSelectedRanges() {
|
|
52351
|
+
if (!this._selection)
|
|
52352
|
+
return [];
|
|
52353
|
+
const { anchor, current, mode } = this._selection;
|
|
52354
|
+
const top = this._provider.getScrollRegionTop();
|
|
52355
|
+
const height = this._provider.getContentHeight();
|
|
52356
|
+
const offset = this._provider.getScrollOffset();
|
|
52357
|
+
const totalLines = this._provider.getContentLines().length;
|
|
52358
|
+
const startIdx = Math.max(0, totalLines - height - offset);
|
|
52359
|
+
const anchorBufIdx = startIdx + (anchor.row - top);
|
|
52360
|
+
const currentBufIdx = startIdx + (current.row - top);
|
|
52361
|
+
const minRow = Math.min(anchorBufIdx, currentBufIdx);
|
|
52362
|
+
const maxRow = Math.max(anchorBufIdx, currentBufIdx);
|
|
52363
|
+
const minCol = Math.min(anchor.col, current.col);
|
|
52364
|
+
const maxCol = Math.max(anchor.col, current.col);
|
|
52365
|
+
const ranges = [];
|
|
52366
|
+
if (mode === "block") {
|
|
52367
|
+
for (let idx = minRow; idx <= maxRow; idx++) {
|
|
52368
|
+
if (idx >= 0 && idx < totalLines) {
|
|
52369
|
+
ranges.push({ bufferIdx: idx, startCol: minCol - 1, endCol: maxCol - 1 });
|
|
52370
|
+
}
|
|
52371
|
+
}
|
|
52372
|
+
} else {
|
|
52373
|
+
const isForward = anchorBufIdx < currentBufIdx || anchorBufIdx === currentBufIdx && anchor.col <= current.col;
|
|
52374
|
+
const startR = isForward ? anchorBufIdx : currentBufIdx;
|
|
52375
|
+
const endR = isForward ? currentBufIdx : anchorBufIdx;
|
|
52376
|
+
const startC = isForward ? anchor.col - 1 : current.col - 1;
|
|
52377
|
+
const endC = isForward ? current.col - 1 : anchor.col - 1;
|
|
52378
|
+
for (let idx = startR; idx <= endR; idx++) {
|
|
52379
|
+
if (idx < 0 || idx >= totalLines)
|
|
52380
|
+
continue;
|
|
52381
|
+
const lineLen = visibleLength(this._provider.getContentLines()[idx] ?? "");
|
|
52382
|
+
if (idx === startR && idx === endR) {
|
|
52383
|
+
ranges.push({ bufferIdx: idx, startCol: startC, endCol: endC });
|
|
52384
|
+
} else if (idx === startR) {
|
|
52385
|
+
ranges.push({ bufferIdx: idx, startCol: startC, endCol: Math.max(lineLen, startC) });
|
|
52386
|
+
} else if (idx === endR) {
|
|
52387
|
+
ranges.push({ bufferIdx: idx, startCol: 0, endCol: endC });
|
|
52388
|
+
} else {
|
|
52389
|
+
ranges.push({ bufferIdx: idx, startCol: 0, endCol: lineLen });
|
|
52390
|
+
}
|
|
52391
|
+
}
|
|
52392
|
+
}
|
|
52393
|
+
return ranges;
|
|
52394
|
+
}
|
|
52395
|
+
/**
|
|
52396
|
+
* Apply selection highlighting to a content line for rendering.
|
|
52397
|
+
* Takes the original ANSI line and returns it with selection highlight applied.
|
|
52398
|
+
*
|
|
52399
|
+
* @param line Original content line (with ANSI codes)
|
|
52400
|
+
* @param startCol 0-based visible start column to highlight
|
|
52401
|
+
* @param endCol 0-based visible end column to highlight (inclusive)
|
|
52402
|
+
* @returns Line with selection highlight overlay
|
|
52403
|
+
*/
|
|
52404
|
+
static applyHighlight(line, startCol, endCol) {
|
|
52405
|
+
const plain = stripAnsi3(line);
|
|
52406
|
+
if (startCol > plain.length || endCol < 0 || startCol > endCol)
|
|
52407
|
+
return line;
|
|
52408
|
+
const sc = Math.max(0, startCol);
|
|
52409
|
+
const ec = Math.min(plain.length - 1, endCol);
|
|
52410
|
+
let result = "";
|
|
52411
|
+
let visPos = 0;
|
|
52412
|
+
let i = 0;
|
|
52413
|
+
let inHighlight = false;
|
|
52414
|
+
while (i < line.length) {
|
|
52415
|
+
const escMatch = line.slice(i).match(/^(\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\))/);
|
|
52416
|
+
if (escMatch) {
|
|
52417
|
+
if (inHighlight) {
|
|
52418
|
+
result += SEL_END + escMatch[0] + SEL_START;
|
|
52419
|
+
} else {
|
|
52420
|
+
result += escMatch[0];
|
|
52421
|
+
}
|
|
52422
|
+
i += escMatch[0].length;
|
|
52423
|
+
continue;
|
|
52424
|
+
}
|
|
52425
|
+
if (visPos === sc && !inHighlight) {
|
|
52426
|
+
result += SEL_START;
|
|
52427
|
+
inHighlight = true;
|
|
52428
|
+
}
|
|
52429
|
+
result += line[i];
|
|
52430
|
+
if (visPos === ec && inHighlight) {
|
|
52431
|
+
result += SEL_END;
|
|
52432
|
+
inHighlight = false;
|
|
52433
|
+
}
|
|
52434
|
+
visPos++;
|
|
52435
|
+
i++;
|
|
52436
|
+
}
|
|
52437
|
+
if (inHighlight)
|
|
52438
|
+
result += SEL_END;
|
|
52439
|
+
return result;
|
|
52440
|
+
}
|
|
52441
|
+
/**
|
|
52442
|
+
* Get the selected text content (plain text, no ANSI codes).
|
|
52443
|
+
* For block mode, each line is joined with newline.
|
|
52444
|
+
* For line mode, text flows continuously with newlines between lines.
|
|
52445
|
+
*/
|
|
52446
|
+
getSelectedText() {
|
|
52447
|
+
const ranges = this.getSelectedRanges();
|
|
52448
|
+
if (ranges.length === 0)
|
|
52449
|
+
return "";
|
|
52450
|
+
const lines = this._provider.getContentLines();
|
|
52451
|
+
const parts = [];
|
|
52452
|
+
for (const { bufferIdx, startCol, endCol } of ranges) {
|
|
52453
|
+
const raw = lines[bufferIdx] ?? "";
|
|
52454
|
+
const plain = stripAnsi3(raw);
|
|
52455
|
+
const selected = plain.slice(Math.max(0, startCol), Math.min(plain.length, endCol + 1));
|
|
52456
|
+
parts.push(selected);
|
|
52457
|
+
}
|
|
52458
|
+
return parts.join("\n");
|
|
52459
|
+
}
|
|
52460
|
+
/**
|
|
52461
|
+
* Copy current selection to system clipboard.
|
|
52462
|
+
* Tries platform commands first, falls back to OSC 52.
|
|
52463
|
+
* Returns true if copy succeeded.
|
|
52464
|
+
*/
|
|
52465
|
+
copyToClipboard() {
|
|
52466
|
+
const text = this.getSelectedText();
|
|
52467
|
+
if (!text)
|
|
52468
|
+
return false;
|
|
52469
|
+
return copyText(text);
|
|
52470
|
+
}
|
|
52471
|
+
};
|
|
52472
|
+
}
|
|
52473
|
+
});
|
|
52474
|
+
|
|
52186
52475
|
// packages/cli/dist/tui/status-bar.js
|
|
52187
52476
|
import { readFileSync as readFileSync31 } from "node:fs";
|
|
52188
|
-
var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG, CONTENT_BG, PANEL_BG_SEQ, CONTENT_BG_SEQ, RESET, StatusBar;
|
|
52477
|
+
var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG, CONTENT_BG, TEXT_PRIMARY, PANEL_BG_SEQ, CONTENT_BG_SEQ, RESET, StatusBar;
|
|
52189
52478
|
var init_status_bar = __esm({
|
|
52190
52479
|
"packages/cli/dist/tui/status-bar.js"() {
|
|
52191
52480
|
"use strict";
|
|
52192
52481
|
init_render();
|
|
52193
52482
|
init_braille_spinner();
|
|
52194
52483
|
init_system_metrics();
|
|
52484
|
+
init_text_selection();
|
|
52195
52485
|
EXPERT_TOOL_BASELINES = {
|
|
52196
52486
|
file_read: 12,
|
|
52197
52487
|
structured_read: 15,
|
|
@@ -52351,6 +52641,7 @@ var init_status_bar = __esm({
|
|
|
52351
52641
|
};
|
|
52352
52642
|
PANEL_BG = 234;
|
|
52353
52643
|
CONTENT_BG = 233;
|
|
52644
|
+
TEXT_PRIMARY = 178;
|
|
52354
52645
|
PANEL_BG_SEQ = `\x1B[48;5;${PANEL_BG}m`;
|
|
52355
52646
|
CONTENT_BG_SEQ = `\x1B[48;5;${CONTENT_BG}m`;
|
|
52356
52647
|
RESET = "\x1B[0m";
|
|
@@ -52378,6 +52669,15 @@ var init_status_bar = __esm({
|
|
|
52378
52669
|
_mouseIdleTimer = null;
|
|
52379
52670
|
static MOUSE_IDLE_MS = 1500;
|
|
52380
52671
|
// disable after 1.5s idle
|
|
52672
|
+
/** Text selection state — tracks click-drag selection for copy */
|
|
52673
|
+
_textSelection = new TextSelection({
|
|
52674
|
+
getContentLines: () => this._contentLines,
|
|
52675
|
+
getScrollOffset: () => this._contentScrollOffset,
|
|
52676
|
+
getContentHeight: () => this.contentHeight,
|
|
52677
|
+
getScrollRegionTop: () => this.scrollRegionTop
|
|
52678
|
+
});
|
|
52679
|
+
/** Callback for header button clicks — fires slash commands */
|
|
52680
|
+
_headerButtonHandler = null;
|
|
52381
52681
|
/** Banner refresh callback — called after resize to re-render top rows */
|
|
52382
52682
|
_bannerRefresh = null;
|
|
52383
52683
|
/** Track previous terminal dimensions to clear ghost separators on resize */
|
|
@@ -53021,6 +53321,91 @@ var init_status_bar = __esm({
|
|
|
53021
53321
|
this._mouseIdleTimer = null;
|
|
53022
53322
|
}
|
|
53023
53323
|
}
|
|
53324
|
+
// ── Text Selection + Header Buttons ─────────────────────────────────
|
|
53325
|
+
/** Set the handler for header button clicks (dispatches slash commands) */
|
|
53326
|
+
setHeaderButtonHandler(handler) {
|
|
53327
|
+
this._headerButtonHandler = handler;
|
|
53328
|
+
}
|
|
53329
|
+
/** Get the text selection instance (for external keyboard shortcut wiring) */
|
|
53330
|
+
get textSelection() {
|
|
53331
|
+
return this._textSelection;
|
|
53332
|
+
}
|
|
53333
|
+
/**
|
|
53334
|
+
* Handle a mouse pointer event (press/drag/release).
|
|
53335
|
+
* Called by MouseFilterStream's pointer handler.
|
|
53336
|
+
* Routes to: header button clicks, text selection, or ignored.
|
|
53337
|
+
*/
|
|
53338
|
+
handlePointerEvent(type, col, row) {
|
|
53339
|
+
if (!this.active)
|
|
53340
|
+
return;
|
|
53341
|
+
if (type === "press" && row < this.scrollRegionTop) {
|
|
53342
|
+
const w = process.stdout.columns ?? 80;
|
|
53343
|
+
const cmd = hitTestHeaderButton(row, col, w);
|
|
53344
|
+
if (cmd && this._headerButtonHandler) {
|
|
53345
|
+
this._headerButtonHandler(cmd);
|
|
53346
|
+
return;
|
|
53347
|
+
}
|
|
53348
|
+
}
|
|
53349
|
+
if (row < this.scrollRegionTop)
|
|
53350
|
+
return;
|
|
53351
|
+
const rows = process.stdout.rows ?? 24;
|
|
53352
|
+
const fh = this._currentFooterHeight;
|
|
53353
|
+
const footerStart = rows - fh + 1;
|
|
53354
|
+
if (row >= footerStart)
|
|
53355
|
+
return;
|
|
53356
|
+
if (type === "press") {
|
|
53357
|
+
this._textSelection.clear();
|
|
53358
|
+
this._textSelection.onMousePress(row, col);
|
|
53359
|
+
this.repaintContent();
|
|
53360
|
+
} else if (type === "drag") {
|
|
53361
|
+
this._textSelection.onMouseDrag(row, col);
|
|
53362
|
+
if (this._textSelection.isDragging)
|
|
53363
|
+
this.repaintContent();
|
|
53364
|
+
} else if (type === "release") {
|
|
53365
|
+
this._textSelection.onMouseRelease(row, col);
|
|
53366
|
+
this.repaintContent();
|
|
53367
|
+
}
|
|
53368
|
+
}
|
|
53369
|
+
/** Copy current selection to clipboard. Returns true if copied. */
|
|
53370
|
+
copySelection() {
|
|
53371
|
+
if (!this._textSelection.hasSelection)
|
|
53372
|
+
return false;
|
|
53373
|
+
const ok = this._textSelection.copyToClipboard();
|
|
53374
|
+
if (ok) {
|
|
53375
|
+
const rows = process.stdout.rows ?? 24;
|
|
53376
|
+
const pos = this.rowPositions(rows);
|
|
53377
|
+
const writer = this._origWrite ?? process.stdout.write.bind(process.stdout);
|
|
53378
|
+
writer(`\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;${TEXT_PRIMARY}m \u2713 Copied to clipboard\x1B[0m`);
|
|
53379
|
+
setTimeout(() => {
|
|
53380
|
+
if (this.active)
|
|
53381
|
+
this.renderFooterAndPositionInput();
|
|
53382
|
+
}, 1200);
|
|
53383
|
+
}
|
|
53384
|
+
return ok;
|
|
53385
|
+
}
|
|
53386
|
+
/** Arm block (rectangular) selection mode — next click starts block select */
|
|
53387
|
+
armBlockSelection() {
|
|
53388
|
+
this._textSelection.armBlockMode();
|
|
53389
|
+
const rows = process.stdout.rows ?? 24;
|
|
53390
|
+
const pos = this.rowPositions(rows);
|
|
53391
|
+
const writer = this._origWrite ?? process.stdout.write.bind(process.stdout);
|
|
53392
|
+
writer(`\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;${TEXT_PRIMARY}m \u25A0 Block selection mode \u2014 click and drag\x1B[0m`);
|
|
53393
|
+
setTimeout(() => {
|
|
53394
|
+
if (this.active)
|
|
53395
|
+
this.renderFooterAndPositionInput();
|
|
53396
|
+
}, 1500);
|
|
53397
|
+
}
|
|
53398
|
+
/** Render header buttons overlay on banner row 3 */
|
|
53399
|
+
renderHeaderButtons() {
|
|
53400
|
+
if (!this.active)
|
|
53401
|
+
return;
|
|
53402
|
+
const w = process.stdout.columns ?? 80;
|
|
53403
|
+
const overlay = renderHeaderButtons(w);
|
|
53404
|
+
if (overlay) {
|
|
53405
|
+
const writer = this._origWrite ?? process.stdout.write.bind(process.stdout);
|
|
53406
|
+
writer(overlay);
|
|
53407
|
+
}
|
|
53408
|
+
}
|
|
53024
53409
|
/** Set a callback to re-render the banner after resize/redraw */
|
|
53025
53410
|
setBannerRefresh(refresh) {
|
|
53026
53411
|
this._bannerRefresh = refresh;
|
|
@@ -53215,6 +53600,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
53215
53600
|
scrollContentUp(lines = 1) {
|
|
53216
53601
|
if (!this.active)
|
|
53217
53602
|
return;
|
|
53603
|
+
this._textSelection.clear();
|
|
53218
53604
|
this.cancelMouseIdle();
|
|
53219
53605
|
this.enableMouseTracking();
|
|
53220
53606
|
const maxOffset = Math.max(0, this._contentLines.length - this.contentHeight);
|
|
@@ -53226,6 +53612,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
53226
53612
|
scrollContentDown(lines = 1) {
|
|
53227
53613
|
if (!this.active)
|
|
53228
53614
|
return;
|
|
53615
|
+
this._textSelection.clear();
|
|
53229
53616
|
this.cancelMouseIdle();
|
|
53230
53617
|
this.enableMouseTracking();
|
|
53231
53618
|
this._contentScrollOffset = Math.max(0, this._contentScrollOffset - lines);
|
|
@@ -53262,10 +53649,18 @@ ${CONTENT_BG_SEQ}`);
|
|
|
53262
53649
|
let buf = "\x1B[?2026h";
|
|
53263
53650
|
buf += "\x1B7";
|
|
53264
53651
|
buf += "\x1B[?25l";
|
|
53652
|
+
const selRanges = this._textSelection.hasSelection ? this._textSelection.getSelectedRanges() : [];
|
|
53653
|
+
const selByBuf = /* @__PURE__ */ new Map();
|
|
53654
|
+
for (const r of selRanges)
|
|
53655
|
+
selByBuf.set(r.bufferIdx, r);
|
|
53265
53656
|
for (let row = 0; row < h; row++) {
|
|
53266
53657
|
const lineIdx = startIdx + row;
|
|
53267
|
-
|
|
53658
|
+
let line = lineIdx < totalLines ? this._contentLines[lineIdx] : "";
|
|
53268
53659
|
const screenRow = this.scrollRegionTop + row;
|
|
53660
|
+
const sel = selByBuf.get(lineIdx);
|
|
53661
|
+
if (sel) {
|
|
53662
|
+
line = TextSelection.applyHighlight(line, sel.startCol, sel.endCol);
|
|
53663
|
+
}
|
|
53269
53664
|
buf += `\x1B[${screenRow};1H${CONTENT_BG_SEQ}\x1B[2K${line}`;
|
|
53270
53665
|
}
|
|
53271
53666
|
if (this._contentScrollOffset > 0) {
|
|
@@ -53917,6 +54312,22 @@ ${CONTENT_BG_SEQ}`);
|
|
|
53917
54312
|
onCtrlO();
|
|
53918
54313
|
return;
|
|
53919
54314
|
}
|
|
54315
|
+
if (key?.ctrl && key?.shift && key?.name === "c") {
|
|
54316
|
+
self.copySelection();
|
|
54317
|
+
return;
|
|
54318
|
+
}
|
|
54319
|
+
if (s === "\x1B[67;6u") {
|
|
54320
|
+
self.copySelection();
|
|
54321
|
+
return;
|
|
54322
|
+
}
|
|
54323
|
+
if (key?.ctrl && key?.shift && key?.name === "b") {
|
|
54324
|
+
self.armBlockSelection();
|
|
54325
|
+
return;
|
|
54326
|
+
}
|
|
54327
|
+
if (s === "\x1B[66;6u") {
|
|
54328
|
+
self.armBlockSelection();
|
|
54329
|
+
return;
|
|
54330
|
+
}
|
|
53920
54331
|
if (s && (/\x1B\[</.test(s) || /^\d+;\d+;\d*[Mm]/.test(s) || /^;\d+[Mm]/.test(s) || /\[<\d/.test(s))) {
|
|
53921
54332
|
return;
|
|
53922
54333
|
}
|
|
@@ -54040,11 +54451,13 @@ var init_mouse_filter = __esm({
|
|
|
54040
54451
|
buffer = "";
|
|
54041
54452
|
onScroll = null;
|
|
54042
54453
|
onActivity = null;
|
|
54454
|
+
onPointer = null;
|
|
54043
54455
|
flushTimer = null;
|
|
54044
|
-
constructor(scrollHandler, activityHandler) {
|
|
54456
|
+
constructor(scrollHandler, activityHandler, pointerHandler) {
|
|
54045
54457
|
super();
|
|
54046
54458
|
this.onScroll = scrollHandler;
|
|
54047
54459
|
this.onActivity = activityHandler ?? null;
|
|
54460
|
+
this.onPointer = pointerHandler ?? null;
|
|
54048
54461
|
}
|
|
54049
54462
|
_transform(chunk, _encoding, callback) {
|
|
54050
54463
|
this.buffer += chunk.toString();
|
|
@@ -54060,10 +54473,20 @@ var init_mouse_filter = __esm({
|
|
|
54060
54473
|
if (mouseMatch) {
|
|
54061
54474
|
const btn = parseInt(mouseMatch[1]);
|
|
54062
54475
|
const row = parseInt(mouseMatch[3]);
|
|
54476
|
+
const col = parseInt(mouseMatch[2]);
|
|
54477
|
+
const suffix = mouseMatch[4];
|
|
54063
54478
|
if ((btn === 64 || btn === 96) && this.onScroll)
|
|
54064
54479
|
this.onScroll("up", 3, row);
|
|
54065
54480
|
else if ((btn === 65 || btn === 97) && this.onScroll)
|
|
54066
54481
|
this.onScroll("down", 3, row);
|
|
54482
|
+
else if (this.onPointer) {
|
|
54483
|
+
if (btn === 0 && suffix === "M")
|
|
54484
|
+
this.onPointer("press", col, row);
|
|
54485
|
+
else if (btn === 32 && suffix === "M")
|
|
54486
|
+
this.onPointer("drag", col, row);
|
|
54487
|
+
else if (btn === 0 && suffix === "m")
|
|
54488
|
+
this.onPointer("release", col, row);
|
|
54489
|
+
}
|
|
54067
54490
|
if (this.onActivity)
|
|
54068
54491
|
this.onActivity();
|
|
54069
54492
|
i += mouseMatch[0].length;
|
|
@@ -54122,7 +54545,7 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
54122
54545
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
54123
54546
|
import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
|
|
54124
54547
|
import { existsSync as existsSync43 } from "node:fs";
|
|
54125
|
-
import { execSync as
|
|
54548
|
+
import { execSync as execSync30 } from "node:child_process";
|
|
54126
54549
|
import { homedir as homedir13 } from "node:os";
|
|
54127
54550
|
function formatTimeAgo(date) {
|
|
54128
54551
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -55518,7 +55941,10 @@ async function startInteractive(config, repoPath) {
|
|
|
55518
55941
|
if (process.stdout.isTTY) {
|
|
55519
55942
|
const scrollTop = carouselLines > 0 ? carouselLines : 1;
|
|
55520
55943
|
statusBar.activate(scrollTop);
|
|
55521
|
-
statusBar.setBannerRefresh(() =>
|
|
55944
|
+
statusBar.setBannerRefresh(() => {
|
|
55945
|
+
banner.renderCurrentFrame();
|
|
55946
|
+
statusBar.renderHeaderButtons();
|
|
55947
|
+
});
|
|
55522
55948
|
const { onOverlayLeave: onOverlayLeave2 } = await Promise.resolve().then(() => (init_overlay_lock(), overlay_lock_exports));
|
|
55523
55949
|
onOverlayLeave2(() => {
|
|
55524
55950
|
banner.renderCurrentFrame();
|
|
@@ -55528,6 +55954,7 @@ async function startInteractive(config, repoPath) {
|
|
|
55528
55954
|
if (cohereEnabled) {
|
|
55529
55955
|
statusBar.setCohereActive(true);
|
|
55530
55956
|
}
|
|
55957
|
+
statusBar.renderHeaderButtons();
|
|
55531
55958
|
if (isResumed) {
|
|
55532
55959
|
statusBar.beginContentWrite();
|
|
55533
55960
|
const resumeMsg = hasTaskToResume ? `Updated to v${version} \u2014 picking up where you left off.` : `Updated to v${version}.`;
|
|
@@ -55907,6 +56334,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
55907
56334
|
statusBar.cancelMouseIdle();
|
|
55908
56335
|
statusBar.enableMouseTracking();
|
|
55909
56336
|
statusBar.scheduleMouseIdle();
|
|
56337
|
+
}, (type, col, row) => {
|
|
56338
|
+
statusBar.handlePointerEvent(type, col, row);
|
|
55910
56339
|
});
|
|
55911
56340
|
process.stdin.pipe(mouseFilter);
|
|
55912
56341
|
const rl = readline2.createInterface({
|
|
@@ -55929,6 +56358,21 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
55929
56358
|
statusBar.handleResize();
|
|
55930
56359
|
}
|
|
55931
56360
|
});
|
|
56361
|
+
let commandCtxRef = null;
|
|
56362
|
+
statusBar.setHeaderButtonHandler((command) => {
|
|
56363
|
+
if (!commandCtxRef)
|
|
56364
|
+
return;
|
|
56365
|
+
(async () => {
|
|
56366
|
+
try {
|
|
56367
|
+
if (statusBar.isActive)
|
|
56368
|
+
statusBar.beginContentWrite();
|
|
56369
|
+
await handleSlashCommand(command, commandCtxRef);
|
|
56370
|
+
if (statusBar.isActive)
|
|
56371
|
+
statusBar.endContentWrite();
|
|
56372
|
+
} catch {
|
|
56373
|
+
}
|
|
56374
|
+
})();
|
|
56375
|
+
});
|
|
55932
56376
|
rl.output = null;
|
|
55933
56377
|
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
55934
56378
|
process.stdin.setRawMode(true);
|
|
@@ -57318,7 +57762,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
57318
57762
|
try {
|
|
57319
57763
|
if (process.platform === "win32") {
|
|
57320
57764
|
try {
|
|
57321
|
-
|
|
57765
|
+
execSync30(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
57322
57766
|
} catch {
|
|
57323
57767
|
}
|
|
57324
57768
|
} else {
|
|
@@ -57345,7 +57789,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
57345
57789
|
if (pid > 0) {
|
|
57346
57790
|
if (process.platform === "win32") {
|
|
57347
57791
|
try {
|
|
57348
|
-
|
|
57792
|
+
execSync30(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
57349
57793
|
} catch {
|
|
57350
57794
|
}
|
|
57351
57795
|
} else {
|
|
@@ -57362,7 +57806,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
57362
57806
|
} catch {
|
|
57363
57807
|
}
|
|
57364
57808
|
try {
|
|
57365
|
-
|
|
57809
|
+
execSync30(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
57366
57810
|
} catch {
|
|
57367
57811
|
}
|
|
57368
57812
|
const oaPath = join59(repoRoot, OA_DIR);
|
|
@@ -57376,14 +57820,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
57376
57820
|
} catch (err) {
|
|
57377
57821
|
if (attempt < 2) {
|
|
57378
57822
|
try {
|
|
57379
|
-
|
|
57823
|
+
execSync30(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
57380
57824
|
} catch {
|
|
57381
57825
|
}
|
|
57382
57826
|
} else {
|
|
57383
57827
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
57384
57828
|
if (process.platform === "win32") {
|
|
57385
57829
|
try {
|
|
57386
|
-
|
|
57830
|
+
execSync30(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
57387
57831
|
deleted = true;
|
|
57388
57832
|
} catch {
|
|
57389
57833
|
}
|
|
@@ -57432,6 +57876,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
57432
57876
|
return { entries: ctx.entries.length, lastSaved: ctx.updatedAt };
|
|
57433
57877
|
}
|
|
57434
57878
|
};
|
|
57879
|
+
commandCtxRef = commandCtx;
|
|
57435
57880
|
showPrompt();
|
|
57436
57881
|
if (!isResumed) {
|
|
57437
57882
|
const savedCtx = loadSessionContext(repoRoot);
|
|
@@ -58323,19 +58768,48 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
58323
58768
|
try {
|
|
58324
58769
|
const ts = handle.runner?.taskState;
|
|
58325
58770
|
if (ts && ts.toolCallCount > 2) {
|
|
58326
|
-
|
|
58327
|
-
|
|
58328
|
-
|
|
58329
|
-
|
|
58330
|
-
|
|
58331
|
-
|
|
58332
|
-
|
|
58333
|
-
|
|
58334
|
-
|
|
58335
|
-
|
|
58336
|
-
|
|
58337
|
-
|
|
58338
|
-
|
|
58771
|
+
const extractionBackend = handle.runner.getBackend();
|
|
58772
|
+
const modFiles = Array.from(ts.modifiedFiles.entries()).map(([p, a]) => `${p} (${a})`).join(", ");
|
|
58773
|
+
const trajectoryPrompt = `You are a memory extraction system. Given this completed task trajectory, extract ONE concise reusable lesson.
|
|
58774
|
+
|
|
58775
|
+
TASK: ${task.slice(0, 300)}
|
|
58776
|
+
COMPLETED STEPS: ${(ts.completedSteps || []).slice(-5).join("; ")}
|
|
58777
|
+
FAILED APPROACHES: ${(ts.failedApproaches || []).join("; ") || "none"}
|
|
58778
|
+
FILES MODIFIED: ${modFiles || "none"}
|
|
58779
|
+
TOOL CALLS: ${ts.toolCallCount}
|
|
58780
|
+
|
|
58781
|
+
Extract the lesson in EXACTLY this format (no other text):
|
|
58782
|
+
CATEGORY: strategy|recovery|optimization
|
|
58783
|
+
TRIGGER: <what problem signature activates this \u2014 one line>
|
|
58784
|
+
LESSON: <one-sentence generalizable rule \u2014 the actual fix pattern, NOT error messages>
|
|
58785
|
+
STEPS: <ordered concrete steps, semicolon-separated>
|
|
58786
|
+
|
|
58787
|
+
Rules:
|
|
58788
|
+
- LESSON must describe the FIX PATTERN (e.g. "use ?? null after Map.get()"), never the error text
|
|
58789
|
+
- Keep total response under 200 characters for LESSON field
|
|
58790
|
+
- Use descriptive variable names for non-fixed elements (e.g. "the target file" not "/src/foo.ts")
|
|
58791
|
+
- If FAILED APPROACHES exist, category MUST be "recovery"`;
|
|
58792
|
+
const extractionResp = await extractionBackend.chatCompletion({
|
|
58793
|
+
messages: [
|
|
58794
|
+
{ role: "system", content: "You extract structured procedural memories from task trajectories. Respond ONLY in the requested format." },
|
|
58795
|
+
{ role: "user", content: trajectoryPrompt }
|
|
58796
|
+
],
|
|
58797
|
+
tools: [],
|
|
58798
|
+
temperature: 0,
|
|
58799
|
+
maxTokens: 300,
|
|
58800
|
+
timeoutMs: 3e4
|
|
58801
|
+
});
|
|
58802
|
+
const raw = extractionResp.choices?.[0]?.message?.content || "";
|
|
58803
|
+
const categoryMatch = raw.match(/CATEGORY:\s*(strategy|recovery|optimization)/i);
|
|
58804
|
+
const triggerMatch = raw.match(/TRIGGER:\s*(.+)/i);
|
|
58805
|
+
const lessonMatch = raw.match(/LESSON:\s*(.+)/i);
|
|
58806
|
+
const stepsMatch = raw.match(/STEPS:\s*(.+)/i);
|
|
58807
|
+
const category = categoryMatch?.[1]?.toLowerCase() || "strategy";
|
|
58808
|
+
const trigger = triggerMatch?.[1]?.trim().slice(0, 150) || "";
|
|
58809
|
+
const lesson = lessonMatch?.[1]?.trim().slice(0, 200) || "";
|
|
58810
|
+
const steps = stepsMatch?.[1]?.trim().slice(0, 300) || "";
|
|
58811
|
+
if (lesson && lesson.length > 5) {
|
|
58812
|
+
const content = `[${category}] TRIGGER: ${trigger} | LESSON: ${lesson}` + (steps ? ` | STEPS: ${steps}` : "");
|
|
58339
58813
|
const metaDir = join59(repoRoot, ".oa", "memory", "metabolism");
|
|
58340
58814
|
const storeFile = join59(metaDir, "store.json");
|
|
58341
58815
|
let store = [];
|
|
@@ -58347,15 +58821,15 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
58347
58821
|
store.push({
|
|
58348
58822
|
id: `mem-traj-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
|
|
58349
58823
|
type: "procedural",
|
|
58350
|
-
content:
|
|
58351
|
-
sourceTrace: "trajectory-extraction",
|
|
58824
|
+
content: content.slice(0, 600),
|
|
58825
|
+
sourceTrace: "llm-trajectory-extraction",
|
|
58352
58826
|
scores: {
|
|
58353
|
-
novelty: 0.
|
|
58354
|
-
utility: category === "recovery" ? 0.
|
|
58355
|
-
confidence: 0.
|
|
58827
|
+
novelty: 0.7,
|
|
58828
|
+
utility: category === "recovery" ? 0.85 : 0.7,
|
|
58829
|
+
confidence: 0.8,
|
|
58356
58830
|
identityRelevance: 0.3
|
|
58357
58831
|
},
|
|
58358
|
-
decision: { action: "admit", reason: `
|
|
58832
|
+
decision: { action: "admit", reason: `LLM-extracted ${category} from task (${ts.toolCallCount} tool calls)` },
|
|
58359
58833
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
58360
58834
|
lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
58361
58835
|
accessCount: 0
|
|
@@ -58382,7 +58856,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
58382
58856
|
const metaFile = join59(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
58383
58857
|
if (existsSync43(metaFile)) {
|
|
58384
58858
|
const store = JSON.parse(readFileSync32(metaFile, "utf8"));
|
|
58385
|
-
const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction").slice(-1)[0];
|
|
58859
|
+
const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
58386
58860
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
58387
58861
|
try {
|
|
58388
58862
|
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
package/package.json
CHANGED