open-agents-ai 0.40.0 → 0.41.0
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/README.md +21 -5
- package/dist/index.js +588 -68
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -162,16 +162,32 @@ Use deep context for:
|
|
|
162
162
|
|
|
163
163
|
The setting persists to `.oa/settings.json`. Deep context is particularly valuable for models with 64K+ context windows (Qwen3.5-122B, Llama 3.1 70B, etc.) where the default thresholds were leaving significant capacity unused.
|
|
164
164
|
|
|
165
|
-
### Status Bar Context Tracking (`Ctx:`)
|
|
165
|
+
### Status Bar Context Tracking (`Ctx:` + `SNR:`)
|
|
166
166
|
|
|
167
|
-
The status bar displays a live `Ctx:` gauge showing estimated context window usage:
|
|
167
|
+
The status bar displays a live `Ctx:` gauge showing estimated context window usage, plus an `SNR:` gauge showing context quality:
|
|
168
168
|
|
|
169
169
|
```
|
|
170
|
-
In: 12,345 | Out: 4,567 | Ctx: 18,000/131,072 86% | Exp: 4.2x
|
|
171
|
-
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
172
|
-
|
|
170
|
+
In: 12,345 | Out: 4,567 | Ctx: 18,000/131,072 86% | SNR: 72% d'2.1 | Exp: 4.2x
|
|
171
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
|
172
|
+
Context window usage Signal-to-Noise Ratio
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
**SNR (Signal-to-Noise Ratio)** — measures how much of the agent's memory context is relevant to the current task vs noise. Inspired by neuroscience signal detection theory:
|
|
176
|
+
|
|
177
|
+
- **d-prime (d')**: psychophysics metric measuring separation between signal and noise distributions. d' >= 2.0 = excellent discrimination, d' ≈ 1.0 = moderate, d' <= 0.5 = noisy
|
|
178
|
+
- **Signal**: memory entries with high keyword overlap to the current task (PFC gating analogy)
|
|
179
|
+
- **Noise**: entries with low relevance or high redundancy (dentate gyrus pattern separation)
|
|
180
|
+
- **Sparsity**: how much of the context is unique vs redundant (sparse distributed memory)
|
|
181
|
+
|
|
182
|
+
The SNR formula combines three components:
|
|
183
|
+
- 50% **signal proportion** (relevant entries / total entries)
|
|
184
|
+
- 30% **d-prime quality** (normalized to 0-1 from the 0-3 d' range)
|
|
185
|
+
- 20% **sparsity** (1 - average pairwise n-gram overlap)
|
|
186
|
+
|
|
187
|
+
Color coding: green (>=70%), yellow (40-70%), red (<40%). SNR is evaluated at task start and task completion. In deep context mode with `/deep`, parallel evaluator agents (PFC Relevance Evaluator + Dentate Gyrus Noise Detector) can run a full consensus-based evaluation.
|
|
188
|
+
|
|
189
|
+
Research basis: d-prime from signal detection theory (Green & Swets 1966), hippocampal pattern separation (Yassa & Stark 2011), PFC gating (Miller & Cohen 2001), biased competition (Desimone & Duncan 1995), multi-agent debate (Du et al., arXiv:2305.14325).
|
|
190
|
+
|
|
175
191
|
This gauge reflects the **post-compaction** token count — when compaction fires, the `Ctx:` value drops to match the actual compressed message history. The compaction warning message shows the before/after:
|
|
176
192
|
|
|
177
193
|
```
|
package/dist/index.js
CHANGED
|
@@ -6133,8 +6133,8 @@ async function loadTranscribeCli() {
|
|
|
6133
6133
|
const nvmBase = join15(homedir6(), ".nvm", "versions", "node");
|
|
6134
6134
|
if (existsSync12(nvmBase)) {
|
|
6135
6135
|
try {
|
|
6136
|
-
const { readdirSync:
|
|
6137
|
-
for (const ver of
|
|
6136
|
+
const { readdirSync: readdirSync14 } = await import("node:fs");
|
|
6137
|
+
for (const ver of readdirSync14(nvmBase)) {
|
|
6138
6138
|
const tcPath = join15(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
6139
6139
|
if (existsSync12(join15(tcPath, "dist", "index.js"))) {
|
|
6140
6140
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -14069,8 +14069,8 @@ ${marker}` : marker);
|
|
|
14069
14069
|
return;
|
|
14070
14070
|
try {
|
|
14071
14071
|
const { mkdirSync: mkdirSync14, writeFileSync: writeFileSync13 } = __require("node:fs");
|
|
14072
|
-
const { join:
|
|
14073
|
-
const sessionDir =
|
|
14072
|
+
const { join: join43 } = __require("node:path");
|
|
14073
|
+
const sessionDir = join43(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
14074
14074
|
mkdirSync14(sessionDir, { recursive: true });
|
|
14075
14075
|
const checkpoint = {
|
|
14076
14076
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -14083,7 +14083,7 @@ ${marker}` : marker);
|
|
|
14083
14083
|
memexEntryCount: this._memexArchive.size,
|
|
14084
14084
|
fileRegistrySize: this._fileRegistry.size
|
|
14085
14085
|
};
|
|
14086
|
-
writeFileSync13(
|
|
14086
|
+
writeFileSync13(join43(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
14087
14087
|
} catch {
|
|
14088
14088
|
}
|
|
14089
14089
|
}
|
|
@@ -15987,8 +15987,8 @@ var init_listen = __esm({
|
|
|
15987
15987
|
const nvmBase = join27(homedir8(), ".nvm", "versions", "node");
|
|
15988
15988
|
if (existsSync19(nvmBase)) {
|
|
15989
15989
|
try {
|
|
15990
|
-
const { readdirSync:
|
|
15991
|
-
for (const ver of
|
|
15990
|
+
const { readdirSync: readdirSync14 } = await import("node:fs");
|
|
15991
|
+
for (const ver of readdirSync14(nvmBase)) {
|
|
15992
15992
|
const tcPath = join27(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
15993
15993
|
if (existsSync19(join27(tcPath, "dist", "index.js"))) {
|
|
15994
15994
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -16218,10 +16218,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
16218
16218
|
wordTimestamps: false
|
|
16219
16219
|
});
|
|
16220
16220
|
if (outputDir) {
|
|
16221
|
-
const { basename:
|
|
16221
|
+
const { basename: basename16 } = await import("node:path");
|
|
16222
16222
|
const transcriptDir = join27(outputDir, ".oa", "transcripts");
|
|
16223
16223
|
mkdirSync5(transcriptDir, { recursive: true });
|
|
16224
|
-
const outFile = join27(transcriptDir, `${
|
|
16224
|
+
const outFile = join27(transcriptDir, `${basename16(filePath)}.txt`);
|
|
16225
16225
|
writeFileSync5(outFile, result.text, "utf-8");
|
|
16226
16226
|
}
|
|
16227
16227
|
return {
|
|
@@ -16607,18 +16607,18 @@ function renderTaskAborted() {
|
|
|
16607
16607
|
${c2.yellow("\u26A0")} ${c2.bold("Task aborted by user")}
|
|
16608
16608
|
`);
|
|
16609
16609
|
}
|
|
16610
|
-
function renderToolCallStart(toolName, args) {
|
|
16610
|
+
function renderToolCallStart(toolName, args, verbose) {
|
|
16611
16611
|
const icon = TOOL_ICONS[toolName] ?? "\u{1F527}";
|
|
16612
16612
|
const label = TOOL_LABELS[toolName] ?? toolName;
|
|
16613
|
-
const argsSummary = formatToolArgs(toolName, args);
|
|
16613
|
+
const argsSummary = formatToolArgs(toolName, args, verbose);
|
|
16614
16614
|
const colorFn = _colorsEnabled ? TOOL_COLORS[toolName] ?? c2.dim : (t) => t;
|
|
16615
16615
|
const emojiPrefix = _emojisEnabled ? `${icon} ` : "";
|
|
16616
16616
|
process.stdout.write(`
|
|
16617
16617
|
${c2.dim("\u23BF")} ${emojiPrefix}${colorFn(c2.bold(label))}${argsSummary ? c2.dim(": ") + argsSummary : ""}
|
|
16618
16618
|
`);
|
|
16619
16619
|
}
|
|
16620
|
-
function renderToolResult(toolName, success, output) {
|
|
16621
|
-
const maxW = getTermWidth() - 10;
|
|
16620
|
+
function renderToolResult(toolName, success, output, verbose) {
|
|
16621
|
+
const maxW = verbose ? Math.max(getTermWidth() - 10, 200) : getTermWidth() - 10;
|
|
16622
16622
|
const prefix = ` ${c2.dim("\u23BF")} `;
|
|
16623
16623
|
switch (toolName) {
|
|
16624
16624
|
case "file_write": {
|
|
@@ -16676,18 +16676,47 @@ function renderToolResult(toolName, success, output) {
|
|
|
16676
16676
|
`);
|
|
16677
16677
|
return;
|
|
16678
16678
|
}
|
|
16679
|
-
const maxLines = 6;
|
|
16679
|
+
const maxLines = verbose ? 200 : 6;
|
|
16680
16680
|
const shown = lines.slice(0, maxLines);
|
|
16681
16681
|
for (const line of shown) {
|
|
16682
|
-
if (isRawJsonDump(line)) {
|
|
16682
|
+
if (isRawJsonDump(line) && !verbose) {
|
|
16683
16683
|
process.stdout.write(`${prefix}${c2.dim("(content omitted)")}
|
|
16684
16684
|
`);
|
|
16685
16685
|
return;
|
|
16686
16686
|
}
|
|
16687
|
-
|
|
16688
|
-
|
|
16689
|
-
|
|
16687
|
+
if (verbose) {
|
|
16688
|
+
const termW = getTermWidth() - 10;
|
|
16689
|
+
if (line.length > termW) {
|
|
16690
|
+
let remaining = line;
|
|
16691
|
+
let first = true;
|
|
16692
|
+
while (remaining.length > 0) {
|
|
16693
|
+
if (remaining.length <= termW) {
|
|
16694
|
+
const formatted2 = formatMarkdownLine(remaining);
|
|
16695
|
+
process.stdout.write(`${first ? prefix : prefix + " "}${formatted2 === remaining ? highlightToolOutput(remaining) : formatted2}
|
|
16696
|
+
`);
|
|
16697
|
+
break;
|
|
16698
|
+
}
|
|
16699
|
+
let breakAt = remaining.lastIndexOf(" ", termW);
|
|
16700
|
+
if (breakAt < termW * 0.3)
|
|
16701
|
+
breakAt = termW;
|
|
16702
|
+
const chunk = remaining.slice(0, breakAt);
|
|
16703
|
+
remaining = remaining.slice(breakAt).trimStart();
|
|
16704
|
+
const formatted = formatMarkdownLine(chunk);
|
|
16705
|
+
process.stdout.write(`${first ? prefix : prefix + " "}${formatted === chunk ? highlightToolOutput(chunk) : formatted}
|
|
16706
|
+
`);
|
|
16707
|
+
first = false;
|
|
16708
|
+
}
|
|
16709
|
+
} else {
|
|
16710
|
+
const formatted = formatMarkdownLine(line);
|
|
16711
|
+
process.stdout.write(`${prefix}${formatted === line ? highlightToolOutput(line) : formatted}
|
|
16712
|
+
`);
|
|
16713
|
+
}
|
|
16714
|
+
} else {
|
|
16715
|
+
const cropped = line.length > maxW ? line.slice(0, maxW - 3) + "..." : line;
|
|
16716
|
+
const formatted = formatMarkdownLine(cropped);
|
|
16717
|
+
process.stdout.write(`${prefix}${formatted === cropped ? highlightToolOutput(cropped) : formatted}
|
|
16690
16718
|
`);
|
|
16719
|
+
}
|
|
16691
16720
|
}
|
|
16692
16721
|
if (lines.length > maxLines) {
|
|
16693
16722
|
process.stdout.write(`${prefix}${c2.dim(`... ${lines.length - maxLines} more lines`)}
|
|
@@ -17026,8 +17055,8 @@ function renderConfig(config) {
|
|
|
17026
17055
|
}
|
|
17027
17056
|
process.stdout.write("\n");
|
|
17028
17057
|
}
|
|
17029
|
-
function formatToolArgs(toolName, args) {
|
|
17030
|
-
const maxArg = Math.max(40, getTermWidth() - 20);
|
|
17058
|
+
function formatToolArgs(toolName, args, verbose) {
|
|
17059
|
+
const maxArg = verbose ? 1e4 : Math.max(40, getTermWidth() - 20);
|
|
17031
17060
|
switch (toolName) {
|
|
17032
17061
|
case "file_read":
|
|
17033
17062
|
case "file_write":
|
|
@@ -19913,17 +19942,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
19913
19942
|
try {
|
|
19914
19943
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
19915
19944
|
const { fileURLToPath: fileURLToPath10 } = await import("node:url");
|
|
19916
|
-
const { dirname: dirname13, join:
|
|
19917
|
-
const { existsSync:
|
|
19945
|
+
const { dirname: dirname13, join: join43 } = await import("node:path");
|
|
19946
|
+
const { existsSync: existsSync30 } = await import("node:fs");
|
|
19918
19947
|
const req = createRequire4(import.meta.url);
|
|
19919
19948
|
const thisDir = dirname13(fileURLToPath10(import.meta.url));
|
|
19920
19949
|
const candidates = [
|
|
19921
|
-
|
|
19922
|
-
|
|
19923
|
-
|
|
19950
|
+
join43(thisDir, "..", "package.json"),
|
|
19951
|
+
join43(thisDir, "..", "..", "package.json"),
|
|
19952
|
+
join43(thisDir, "..", "..", "..", "package.json")
|
|
19924
19953
|
];
|
|
19925
19954
|
for (const pkgPath of candidates) {
|
|
19926
|
-
if (
|
|
19955
|
+
if (existsSync30(pkgPath)) {
|
|
19927
19956
|
const pkg = req(pkgPath);
|
|
19928
19957
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
19929
19958
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -24113,6 +24142,348 @@ DMN state directory: ${this.stateDir}`);
|
|
|
24113
24142
|
}
|
|
24114
24143
|
});
|
|
24115
24144
|
|
|
24145
|
+
// packages/cli/dist/tui/snr-engine.js
|
|
24146
|
+
import { existsSync as existsSync27, readdirSync as readdirSync12, readFileSync as readFileSync20 } from "node:fs";
|
|
24147
|
+
import { join as join37, basename as basename14 } from "node:path";
|
|
24148
|
+
function computeDPrime(signalScores, noiseScores) {
|
|
24149
|
+
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
24150
|
+
return 0;
|
|
24151
|
+
const mean = (arr) => arr.reduce((s, v) => s + v, 0) / arr.length;
|
|
24152
|
+
const variance = (arr, mu) => arr.reduce((s, v) => s + (v - mu) ** 2, 0) / Math.max(1, arr.length - 1);
|
|
24153
|
+
const muSignal = mean(signalScores);
|
|
24154
|
+
const muNoise = mean(noiseScores);
|
|
24155
|
+
const varSignal = variance(signalScores, muSignal);
|
|
24156
|
+
const varNoise = variance(noiseScores, muNoise);
|
|
24157
|
+
const pooledStd = Math.sqrt((varSignal + varNoise) / 2);
|
|
24158
|
+
if (pooledStd === 0)
|
|
24159
|
+
return muSignal > muNoise ? 3 : 0;
|
|
24160
|
+
return (muSignal - muNoise) / pooledStd;
|
|
24161
|
+
}
|
|
24162
|
+
function computeSparsity(entries) {
|
|
24163
|
+
if (entries.length <= 1)
|
|
24164
|
+
return 1;
|
|
24165
|
+
const ngramSets = entries.map((e) => {
|
|
24166
|
+
const words = e.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
|
|
24167
|
+
const ngrams = /* @__PURE__ */ new Set();
|
|
24168
|
+
for (let i = 0; i < words.length - 1; i++) {
|
|
24169
|
+
ngrams.add(`${words[i]} ${words[i + 1]}`);
|
|
24170
|
+
}
|
|
24171
|
+
return ngrams;
|
|
24172
|
+
});
|
|
24173
|
+
let totalPairs = 0;
|
|
24174
|
+
let totalJaccard = 0;
|
|
24175
|
+
for (let i = 0; i < ngramSets.length; i++) {
|
|
24176
|
+
for (let j = i + 1; j < ngramSets.length; j++) {
|
|
24177
|
+
const a = ngramSets[i];
|
|
24178
|
+
const b = ngramSets[j];
|
|
24179
|
+
if (a.size === 0 && b.size === 0)
|
|
24180
|
+
continue;
|
|
24181
|
+
const intersection = new Set([...a].filter((x) => b.has(x)));
|
|
24182
|
+
const union = /* @__PURE__ */ new Set([...a, ...b]);
|
|
24183
|
+
totalJaccard += union.size > 0 ? intersection.size / union.size : 0;
|
|
24184
|
+
totalPairs++;
|
|
24185
|
+
}
|
|
24186
|
+
}
|
|
24187
|
+
if (totalPairs === 0)
|
|
24188
|
+
return 1;
|
|
24189
|
+
const avgOverlap = totalJaccard / totalPairs;
|
|
24190
|
+
return Math.max(0, Math.min(1, 1 - avgOverlap));
|
|
24191
|
+
}
|
|
24192
|
+
function adaptTool3(tool) {
|
|
24193
|
+
return {
|
|
24194
|
+
name: tool.name,
|
|
24195
|
+
description: tool.description,
|
|
24196
|
+
parameters: tool.parameters,
|
|
24197
|
+
async execute(args) {
|
|
24198
|
+
const result = await tool.execute(args);
|
|
24199
|
+
return { success: result.success, output: result.output, error: result.error };
|
|
24200
|
+
}
|
|
24201
|
+
};
|
|
24202
|
+
}
|
|
24203
|
+
function renderSNRUpdate(score) {
|
|
24204
|
+
const pct = Math.round(score.ratio * 100);
|
|
24205
|
+
const color = pct >= 70 ? c2.green : pct >= 40 ? c2.yellow : c2.red;
|
|
24206
|
+
const capWarn = score.capacityWarning ? c2.red(" [CAPACITY]") : "";
|
|
24207
|
+
process.stdout.write(` ${color("\u25C8")} SNR: ${color(`${pct}%`)} (d'=${score.dPrime.toFixed(1)}, signal=${score.signalCount}/${score.entriesEvaluated}, sparsity=${Math.round(score.sparsity * 100)}%) [${score.evaluators.join("+")}]${capWarn}
|
|
24208
|
+
`);
|
|
24209
|
+
}
|
|
24210
|
+
var SNREngine;
|
|
24211
|
+
var init_snr_engine = __esm({
|
|
24212
|
+
"packages/cli/dist/tui/snr-engine.js"() {
|
|
24213
|
+
"use strict";
|
|
24214
|
+
init_dist5();
|
|
24215
|
+
init_dist2();
|
|
24216
|
+
init_project_context();
|
|
24217
|
+
init_render();
|
|
24218
|
+
SNREngine = class {
|
|
24219
|
+
config;
|
|
24220
|
+
repoRoot;
|
|
24221
|
+
lastScore = null;
|
|
24222
|
+
evaluationCount = 0;
|
|
24223
|
+
constructor(config, repoRoot) {
|
|
24224
|
+
this.config = config;
|
|
24225
|
+
this.repoRoot = repoRoot;
|
|
24226
|
+
}
|
|
24227
|
+
get score() {
|
|
24228
|
+
return this.lastScore;
|
|
24229
|
+
}
|
|
24230
|
+
/**
|
|
24231
|
+
* Quick local-only SNR estimation (no LLM calls, fast).
|
|
24232
|
+
* @param contextSlots — total context window tokens (for Hopfield capacity warning)
|
|
24233
|
+
*/
|
|
24234
|
+
computeLocalSNR(currentTask, contextEntries, contextSlots) {
|
|
24235
|
+
if (contextEntries.length === 0) {
|
|
24236
|
+
return this.makeScore(1, 3, 0, 0, 0, 1, ["local-empty"]);
|
|
24237
|
+
}
|
|
24238
|
+
const taskTerms = new Set(currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, "")));
|
|
24239
|
+
const scores = contextEntries.map((entry) => {
|
|
24240
|
+
const entryTerms = entry.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""));
|
|
24241
|
+
const matchCount = entryTerms.filter((t) => taskTerms.has(t)).length;
|
|
24242
|
+
const score2 = entryTerms.length > 0 ? matchCount / Math.sqrt(entryTerms.length) : 0;
|
|
24243
|
+
return { entry, score: score2 };
|
|
24244
|
+
});
|
|
24245
|
+
const allScores = scores.map((s) => s.score);
|
|
24246
|
+
const mean = allScores.reduce((a, b) => a + b, 0) / allScores.length;
|
|
24247
|
+
const std = Math.sqrt(allScores.reduce((a, v) => a + (v - mean) ** 2, 0) / allScores.length);
|
|
24248
|
+
const threshold = mean + 0.5 * std;
|
|
24249
|
+
const signalScores = allScores.filter((s) => s >= threshold);
|
|
24250
|
+
const noiseScores = allScores.filter((s) => s < threshold);
|
|
24251
|
+
const dPrime = computeDPrime(signalScores.length > 0 ? signalScores : [mean], noiseScores.length > 0 ? noiseScores : [0]);
|
|
24252
|
+
const sparsity = computeSparsity(contextEntries);
|
|
24253
|
+
const signalProportion = signalScores.length / allScores.length;
|
|
24254
|
+
const dPrimeNorm = Math.min(1, Math.max(0, dPrime / 3));
|
|
24255
|
+
const ratio = 0.5 * signalProportion + 0.3 * dPrimeNorm + 0.2 * sparsity;
|
|
24256
|
+
const capacityWarning = contextSlots ? contextEntries.length > Math.floor(contextSlots * 0.138) : false;
|
|
24257
|
+
const score = this.makeScore(ratio, dPrime, contextEntries.length, signalScores.length, noiseScores.length, sparsity, ["local-keyword"], capacityWarning);
|
|
24258
|
+
this.lastScore = score;
|
|
24259
|
+
this.evaluationCount++;
|
|
24260
|
+
return score;
|
|
24261
|
+
}
|
|
24262
|
+
/**
|
|
24263
|
+
* Full SNR evaluation using parallel LLM evaluator agents.
|
|
24264
|
+
* Mirrors PFC gating + multi-agent debate (Du et al. 2023).
|
|
24265
|
+
*
|
|
24266
|
+
* Spawns 2 lightweight agents with different evaluation perspectives:
|
|
24267
|
+
* - "Relevance Evaluator" — scores entries by task relevance (PFC role)
|
|
24268
|
+
* - "Noise Detector" — identifies redundant/stale/irrelevant entries (DG role)
|
|
24269
|
+
*
|
|
24270
|
+
* Their consensus determines the final SNR.
|
|
24271
|
+
*/
|
|
24272
|
+
async evaluateWithAgents(currentTask, memoryTopics, onEvent) {
|
|
24273
|
+
const entries = this.loadMemoryEntries(memoryTopics);
|
|
24274
|
+
if (entries.length === 0) {
|
|
24275
|
+
const score2 = this.makeScore(1, 3, 0, 0, 0, 1, ["agents-empty"]);
|
|
24276
|
+
this.lastScore = score2;
|
|
24277
|
+
return score2;
|
|
24278
|
+
}
|
|
24279
|
+
const entrySummaries = entries.map((e, i) => `[${i}] topic=${e.topic} key=${e.key}: ${e.value.slice(0, 200)}${e.value.length > 200 ? "..." : ""}`);
|
|
24280
|
+
const entriesBlock = entrySummaries.join("\n");
|
|
24281
|
+
const [relevanceResult, noiseResult] = await Promise.allSettled([
|
|
24282
|
+
this.runEvaluatorAgent("relevance", `You are a Prefrontal Cortex Gating Evaluator. Your role is to assess which
|
|
24283
|
+
memory entries are RELEVANT to the current task.
|
|
24284
|
+
|
|
24285
|
+
CURRENT TASK: ${currentTask}
|
|
24286
|
+
|
|
24287
|
+
MEMORY ENTRIES TO EVALUATE:
|
|
24288
|
+
${entriesBlock}
|
|
24289
|
+
|
|
24290
|
+
For each entry, output a JSON array of objects:
|
|
24291
|
+
[{"index": 0, "score": 0.8, "reason": "directly related to task"}, ...]
|
|
24292
|
+
|
|
24293
|
+
Score 0-1 where:
|
|
24294
|
+
- 1.0 = directly relevant to the current task
|
|
24295
|
+
- 0.7 = supporting context (useful background)
|
|
24296
|
+
- 0.4 = marginally relevant
|
|
24297
|
+
- 0.1 = not relevant to current task
|
|
24298
|
+
|
|
24299
|
+
Call task_complete with the JSON array when done.`, onEvent),
|
|
24300
|
+
this.runEvaluatorAgent("noise", `You are a Dentate Gyrus Pattern Separation Evaluator. Your role is to identify
|
|
24301
|
+
NOISE in the memory context \u2014 entries that are redundant, stale, or interfering.
|
|
24302
|
+
|
|
24303
|
+
CURRENT TASK: ${currentTask}
|
|
24304
|
+
|
|
24305
|
+
MEMORY ENTRIES TO EVALUATE:
|
|
24306
|
+
${entriesBlock}
|
|
24307
|
+
|
|
24308
|
+
For each entry, output a JSON array of objects:
|
|
24309
|
+
[{"index": 0, "noise_score": 0.2, "reason": "unique, not redundant"}, ...]
|
|
24310
|
+
|
|
24311
|
+
Noise score 0-1 where:
|
|
24312
|
+
- 1.0 = pure noise (completely redundant, stale, or interfering with task)
|
|
24313
|
+
- 0.7 = mostly noise (outdated or largely redundant with another entry)
|
|
24314
|
+
- 0.4 = moderate noise (some overlap with other entries)
|
|
24315
|
+
- 0.1 = clean signal (unique, fresh, non-interfering)
|
|
24316
|
+
|
|
24317
|
+
Look for: duplicate information, outdated facts, entries that contradict
|
|
24318
|
+
newer entries, entries about completely unrelated topics.
|
|
24319
|
+
|
|
24320
|
+
Call task_complete with the JSON array when done.`, onEvent)
|
|
24321
|
+
]);
|
|
24322
|
+
const relevanceScores = this.parseEvaluatorResult(relevanceResult.status === "fulfilled" ? relevanceResult.value : "", entries.length, 0.5);
|
|
24323
|
+
const noiseScores = this.parseEvaluatorResult(noiseResult.status === "fulfilled" ? noiseResult.value : "", entries.length, 0.5);
|
|
24324
|
+
const combinedScores = entries.map((_, i) => {
|
|
24325
|
+
const rel = relevanceScores[i] ?? 0.5;
|
|
24326
|
+
const noise = noiseScores[i] ?? 0.5;
|
|
24327
|
+
const votes = [rel, 1 - noise].sort((a, b) => a - b);
|
|
24328
|
+
return (votes[0] + votes[1]) / 2;
|
|
24329
|
+
});
|
|
24330
|
+
const mean = combinedScores.reduce((a, b) => a + b, 0) / combinedScores.length;
|
|
24331
|
+
const std = Math.sqrt(combinedScores.reduce((a, v) => a + (v - mean) ** 2, 0) / combinedScores.length);
|
|
24332
|
+
const threshold = Math.max(0.3, mean);
|
|
24333
|
+
const signalEntries = combinedScores.filter((s) => s >= threshold);
|
|
24334
|
+
const noiseEntries = combinedScores.filter((s) => s < threshold);
|
|
24335
|
+
const dPrime = computeDPrime(signalEntries.length > 0 ? signalEntries : [mean], noiseEntries.length > 0 ? noiseEntries : [0.1]);
|
|
24336
|
+
const sparsity = computeSparsity(entries.map((e) => e.value));
|
|
24337
|
+
const signalProportion = signalEntries.length / combinedScores.length;
|
|
24338
|
+
const dPrimeNorm = Math.min(1, Math.max(0, dPrime / 3));
|
|
24339
|
+
const ratio = 0.5 * signalProportion + 0.3 * dPrimeNorm + 0.2 * sparsity;
|
|
24340
|
+
const evaluators = [
|
|
24341
|
+
relevanceResult.status === "fulfilled" ? "relevance-agent" : "relevance-failed",
|
|
24342
|
+
noiseResult.status === "fulfilled" ? "noise-agent" : "noise-failed"
|
|
24343
|
+
];
|
|
24344
|
+
const score = this.makeScore(ratio, dPrime, entries.length, signalEntries.length, noiseEntries.length, sparsity, evaluators);
|
|
24345
|
+
this.lastScore = score;
|
|
24346
|
+
this.evaluationCount++;
|
|
24347
|
+
return score;
|
|
24348
|
+
}
|
|
24349
|
+
// ── Evaluator agent ──────────────────────────────────────────────────
|
|
24350
|
+
async runEvaluatorAgent(name, prompt, onEvent) {
|
|
24351
|
+
const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey);
|
|
24352
|
+
const modelTier = getModelTier(this.config.model);
|
|
24353
|
+
const runner = new AgenticRunner(backend, {
|
|
24354
|
+
maxTurns: 5,
|
|
24355
|
+
// Evaluators are very focused — 5 turns max
|
|
24356
|
+
maxTokens: 4096,
|
|
24357
|
+
temperature: 0,
|
|
24358
|
+
// Deterministic scoring
|
|
24359
|
+
requestTimeoutMs: this.config.timeoutMs,
|
|
24360
|
+
taskTimeoutMs: this.config.timeoutMs,
|
|
24361
|
+
compactionThreshold: modelTier === "small" ? 8e3 : 16e3,
|
|
24362
|
+
modelTier
|
|
24363
|
+
});
|
|
24364
|
+
const tools = [
|
|
24365
|
+
new MemoryReadTool(this.repoRoot),
|
|
24366
|
+
new MemorySearchTool(this.repoRoot)
|
|
24367
|
+
];
|
|
24368
|
+
runner.registerTools([
|
|
24369
|
+
...tools.map(adaptTool3),
|
|
24370
|
+
{
|
|
24371
|
+
name: "task_complete",
|
|
24372
|
+
description: "Signal evaluation is complete with your scored results.",
|
|
24373
|
+
parameters: {
|
|
24374
|
+
type: "object",
|
|
24375
|
+
properties: {
|
|
24376
|
+
summary: { type: "string", description: "JSON array of scored entries" }
|
|
24377
|
+
},
|
|
24378
|
+
required: ["summary"]
|
|
24379
|
+
},
|
|
24380
|
+
async execute(args) {
|
|
24381
|
+
return { success: true, output: args["summary"] || "[]" };
|
|
24382
|
+
}
|
|
24383
|
+
}
|
|
24384
|
+
]);
|
|
24385
|
+
if (onEvent)
|
|
24386
|
+
runner.onEvent(onEvent);
|
|
24387
|
+
const result = await runner.run(prompt, `SNR Evaluator (${name}). Working directory: ${this.repoRoot}`);
|
|
24388
|
+
return result.summary || "[]";
|
|
24389
|
+
}
|
|
24390
|
+
// ── Memory loading ───────────────────────────────────────────────────
|
|
24391
|
+
loadMemoryEntries(topics) {
|
|
24392
|
+
const entries = [];
|
|
24393
|
+
const dirs = [
|
|
24394
|
+
join37(this.repoRoot, ".oa", "memory"),
|
|
24395
|
+
join37(this.repoRoot, ".open-agents", "memory")
|
|
24396
|
+
];
|
|
24397
|
+
for (const dir of dirs) {
|
|
24398
|
+
if (!existsSync27(dir))
|
|
24399
|
+
continue;
|
|
24400
|
+
try {
|
|
24401
|
+
const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
|
|
24402
|
+
for (const f of files) {
|
|
24403
|
+
const topic = basename14(f, ".json");
|
|
24404
|
+
if (topics.length > 0 && !topics.includes(topic))
|
|
24405
|
+
continue;
|
|
24406
|
+
try {
|
|
24407
|
+
const data = JSON.parse(readFileSync20(join37(dir, f), "utf-8"));
|
|
24408
|
+
for (const [key, val] of Object.entries(data)) {
|
|
24409
|
+
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
24410
|
+
entries.push({ topic, key, value });
|
|
24411
|
+
}
|
|
24412
|
+
} catch {
|
|
24413
|
+
}
|
|
24414
|
+
}
|
|
24415
|
+
} catch {
|
|
24416
|
+
}
|
|
24417
|
+
}
|
|
24418
|
+
return entries;
|
|
24419
|
+
}
|
|
24420
|
+
// ── Result parsing ───────────────────────────────────────────────────
|
|
24421
|
+
parseEvaluatorResult(summary, entryCount, defaultScore) {
|
|
24422
|
+
const scores = new Array(entryCount).fill(defaultScore);
|
|
24423
|
+
try {
|
|
24424
|
+
const jsonMatch = summary.match(/\[[\s\S]*\]/);
|
|
24425
|
+
if (!jsonMatch)
|
|
24426
|
+
return scores;
|
|
24427
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
24428
|
+
for (const item of parsed) {
|
|
24429
|
+
const idx = typeof item.index === "number" ? item.index : -1;
|
|
24430
|
+
const score = typeof item.score === "number" ? item.score : typeof item.noise_score === "number" ? item.noise_score : defaultScore;
|
|
24431
|
+
if (idx >= 0 && idx < entryCount) {
|
|
24432
|
+
scores[idx] = Math.max(0, Math.min(1, score));
|
|
24433
|
+
}
|
|
24434
|
+
}
|
|
24435
|
+
} catch {
|
|
24436
|
+
}
|
|
24437
|
+
return scores;
|
|
24438
|
+
}
|
|
24439
|
+
// ── Memory pruning recommendations ──────────────────────────────────
|
|
24440
|
+
/**
|
|
24441
|
+
* Identify low-SNR memory entries that should be pruned.
|
|
24442
|
+
* Mirrors synaptic downscaling during slow-wave sleep — weak connections
|
|
24443
|
+
* (low-relevance, high-redundancy entries) are depotentiated.
|
|
24444
|
+
*
|
|
24445
|
+
* Returns topics+keys of entries scoring below the noise threshold.
|
|
24446
|
+
* Does NOT delete anything — the caller decides what to do with the list.
|
|
24447
|
+
*/
|
|
24448
|
+
getPruningCandidates(currentTask, noiseThreshold = 0.3) {
|
|
24449
|
+
const entries = this.loadMemoryEntries([]);
|
|
24450
|
+
if (entries.length === 0)
|
|
24451
|
+
return [];
|
|
24452
|
+
const taskTerms = new Set(currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, "")));
|
|
24453
|
+
const candidates = [];
|
|
24454
|
+
for (const entry of entries) {
|
|
24455
|
+
const entryTerms = entry.value.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""));
|
|
24456
|
+
const matchCount = entryTerms.filter((t) => taskTerms.has(t)).length;
|
|
24457
|
+
const relevance = entryTerms.length > 0 ? matchCount / Math.sqrt(entryTerms.length) : 0;
|
|
24458
|
+
if (relevance < noiseThreshold) {
|
|
24459
|
+
candidates.push({
|
|
24460
|
+
topic: entry.topic,
|
|
24461
|
+
key: entry.key,
|
|
24462
|
+
score: relevance,
|
|
24463
|
+
reason: relevance === 0 ? "no keyword overlap with current task" : `low relevance (${(relevance * 100).toFixed(0)}% < ${(noiseThreshold * 100).toFixed(0)}% threshold)`
|
|
24464
|
+
});
|
|
24465
|
+
}
|
|
24466
|
+
}
|
|
24467
|
+
return candidates.sort((a, b) => a.score - b.score);
|
|
24468
|
+
}
|
|
24469
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
24470
|
+
makeScore(ratio, dPrime, total, signal, noise, sparsity, evaluators, capacityWarning = false) {
|
|
24471
|
+
return {
|
|
24472
|
+
ratio: Math.max(0, Math.min(1, ratio)),
|
|
24473
|
+
dPrime: Math.max(0, dPrime),
|
|
24474
|
+
entriesEvaluated: total,
|
|
24475
|
+
signalCount: signal,
|
|
24476
|
+
noiseCount: noise,
|
|
24477
|
+
sparsity: Math.max(0, Math.min(1, sparsity)),
|
|
24478
|
+
evaluatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24479
|
+
evaluators,
|
|
24480
|
+
capacityWarning
|
|
24481
|
+
};
|
|
24482
|
+
}
|
|
24483
|
+
};
|
|
24484
|
+
}
|
|
24485
|
+
});
|
|
24486
|
+
|
|
24116
24487
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
24117
24488
|
function renderTelegramStart(botUsername, adminId) {
|
|
24118
24489
|
process.stdout.write(`
|
|
@@ -24369,7 +24740,7 @@ function themeForTool(toolName) {
|
|
|
24369
24740
|
return THEME_DEFAULT;
|
|
24370
24741
|
}
|
|
24371
24742
|
}
|
|
24372
|
-
var DENSITY, WAVE, THEME_DEFAULT, THEME_FILE, THEME_SHELL, THEME_WEB, THEME_SEARCH, THEME_MEMORY, THEME_SKILL, THEME_TOOL_CREATE, DEFAULT_METRICS, BrailleSpinner;
|
|
24743
|
+
var DENSITY, WAVE, THEME_DEFAULT, THEME_FILE, THEME_SHELL, THEME_WEB, THEME_SEARCH, THEME_MEMORY, THEME_SKILL, THEME_TOOL_CREATE, THEME_DREAM, DEFAULT_METRICS, BrailleSpinner;
|
|
24373
24744
|
var init_braille_spinner = __esm({
|
|
24374
24745
|
"packages/cli/dist/tui/braille-spinner.js"() {
|
|
24375
24746
|
"use strict";
|
|
@@ -24426,10 +24797,16 @@ var init_braille_spinner = __esm({
|
|
|
24426
24797
|
ramp: [237, 173, 174, 179, 180, 215, 216, 222, 229],
|
|
24427
24798
|
speed: 2
|
|
24428
24799
|
};
|
|
24800
|
+
THEME_DREAM = {
|
|
24801
|
+
ramp: [237, 94, 130, 136, 172, 178, 179, 214, 220],
|
|
24802
|
+
speed: 1
|
|
24803
|
+
};
|
|
24429
24804
|
DEFAULT_METRICS = {
|
|
24430
24805
|
contextPct: 0,
|
|
24431
24806
|
tokenRate: 0,
|
|
24432
|
-
isStreaming: false
|
|
24807
|
+
isStreaming: false,
|
|
24808
|
+
snr: 0.5,
|
|
24809
|
+
isDreaming: false
|
|
24433
24810
|
};
|
|
24434
24811
|
BrailleSpinner = class {
|
|
24435
24812
|
frame = 0;
|
|
@@ -24481,6 +24858,10 @@ var init_braille_spinner = __esm({
|
|
|
24481
24858
|
this._metrics.tokenRate = metrics.tokenRate;
|
|
24482
24859
|
if (metrics.isStreaming !== void 0)
|
|
24483
24860
|
this._metrics.isStreaming = metrics.isStreaming;
|
|
24861
|
+
if (metrics.snr !== void 0)
|
|
24862
|
+
this._metrics.snr = Math.max(0, Math.min(1, metrics.snr));
|
|
24863
|
+
if (metrics.isDreaming !== void 0)
|
|
24864
|
+
this._metrics.isDreaming = metrics.isDreaming;
|
|
24484
24865
|
}
|
|
24485
24866
|
/**
|
|
24486
24867
|
* Render the current animation frame as an ANSI-colored string.
|
|
@@ -24492,28 +24873,41 @@ var init_braille_spinner = __esm({
|
|
|
24492
24873
|
* used — gentle ripples at low usage, full waves at high usage.
|
|
24493
24874
|
* - Slinky: a secondary slow sine wave creates organic compression and
|
|
24494
24875
|
* expansion across columns, making the wave feel elastic and alive.
|
|
24876
|
+
* - SNR entropy: low SNR injects phase jitter per-column (noisy neural signal),
|
|
24877
|
+
* high SNR produces smooth coherent waves (clean signal propagation).
|
|
24878
|
+
* - Dream mode: slower, deeper breathing with warm amber color override.
|
|
24495
24879
|
*/
|
|
24496
24880
|
render(width) {
|
|
24497
24881
|
const cycleLen = WAVE.length;
|
|
24498
|
-
const baseSpeed = this.theme.speed;
|
|
24499
24882
|
const m = this._metrics;
|
|
24500
|
-
const
|
|
24883
|
+
const activeTheme = m.isDreaming ? THEME_DREAM : this.theme;
|
|
24884
|
+
const activeColorRamp = m.isDreaming ? buildColorRamp(THEME_DREAM.ramp) : this.colorRamp;
|
|
24885
|
+
const baseSpeed = activeTheme.speed;
|
|
24886
|
+
const breathRate = m.isDreaming ? 0.04 : 0.08;
|
|
24887
|
+
const breathPhase = Math.sin(this.frame * breathRate);
|
|
24501
24888
|
let speed;
|
|
24502
24889
|
if (m.isStreaming && m.tokenRate > 0) {
|
|
24503
24890
|
const rateBoost = Math.min(4, m.tokenRate / 8);
|
|
24504
24891
|
speed = baseSpeed + rateBoost + breathPhase * 0.3;
|
|
24892
|
+
} else if (m.isDreaming) {
|
|
24893
|
+
speed = baseSpeed * 0.6 + breathPhase * 1.2;
|
|
24505
24894
|
} else {
|
|
24506
24895
|
speed = baseSpeed + breathPhase * 0.8;
|
|
24507
24896
|
}
|
|
24508
24897
|
const pressure = Math.max(0, Math.min(100, m.contextPct)) / 100;
|
|
24509
24898
|
const densityScale = 0.3 + pressure * 0.7;
|
|
24899
|
+
const snr = m.snr;
|
|
24900
|
+
const entropy = Math.max(0, 1 - snr);
|
|
24510
24901
|
const slinkyFreq = 0.02 + (m.isStreaming ? 0.01 : 0);
|
|
24511
24902
|
const slinkyAmp = 1.5 + pressure * 2;
|
|
24903
|
+
const jitterSeed = this.frame * 7919;
|
|
24512
24904
|
let buf = "";
|
|
24513
24905
|
let lastColor = -1;
|
|
24514
24906
|
for (let col = 0; col < width; col++) {
|
|
24515
24907
|
const slinkyOffset = Math.sin(col * 0.1 + this.frame * slinkyFreq) * slinkyAmp;
|
|
24516
|
-
const
|
|
24908
|
+
const jitterHash = Math.sin((col * 127 + jitterSeed) * 1e-3) * 2 + Math.cos((col * 311 + jitterSeed) * 7e-4) * 1.5;
|
|
24909
|
+
const snrJitter = jitterHash * entropy * 3;
|
|
24910
|
+
const rawPhase = col * speed + this.frame + slinkyOffset + snrJitter;
|
|
24517
24911
|
const normalizedPhase = (rawPhase % cycleLen + cycleLen) % cycleLen;
|
|
24518
24912
|
const waveIdx = Math.round(normalizedPhase) % cycleLen;
|
|
24519
24913
|
let amplitude;
|
|
@@ -24531,7 +24925,7 @@ var init_braille_spinner = __esm({
|
|
|
24531
24925
|
}
|
|
24532
24926
|
scaledIdx = Math.max(0, Math.min(cycleLen - 1, scaledIdx));
|
|
24533
24927
|
const ch = WAVE[scaledIdx];
|
|
24534
|
-
const color =
|
|
24928
|
+
const color = activeColorRamp[scaledIdx];
|
|
24535
24929
|
if (color !== lastColor) {
|
|
24536
24930
|
buf += `\x1B[38;5;${color}m`;
|
|
24537
24931
|
lastColor = color;
|
|
@@ -24843,6 +25237,13 @@ var init_status_bar = __esm({
|
|
|
24843
25237
|
setActiveTool(toolName) {
|
|
24844
25238
|
this._brailleSpinner.setTool(toolName);
|
|
24845
25239
|
}
|
|
25240
|
+
/**
|
|
25241
|
+
* Forward metrics directly to the braille spinner.
|
|
25242
|
+
* Used for SNR, dream mode, and other neural activity indicators.
|
|
25243
|
+
*/
|
|
25244
|
+
setBrailleMetrics(metrics) {
|
|
25245
|
+
this._brailleSpinner.setMetrics(metrics);
|
|
25246
|
+
}
|
|
24846
25247
|
/** Context window size to display. Can be updated if model changes. */
|
|
24847
25248
|
setContextWindowSize(size) {
|
|
24848
25249
|
this.metrics.contextWindowSize = size;
|
|
@@ -24869,6 +25270,21 @@ var init_status_bar = __esm({
|
|
|
24869
25270
|
recordSpeedTaskEnd() {
|
|
24870
25271
|
this._speedTracker.taskEnd();
|
|
24871
25272
|
}
|
|
25273
|
+
/** SNR (Signal-to-Noise Ratio) from context quality evaluation */
|
|
25274
|
+
_snr = null;
|
|
25275
|
+
/** Update the SNR gauge with a new evaluation result */
|
|
25276
|
+
setSNR(ratio, dPrime, capacityWarning) {
|
|
25277
|
+
this._snr = { ratio, dPrime, capacityWarning };
|
|
25278
|
+
this._brailleSpinner.setMetrics({ snr: ratio });
|
|
25279
|
+
if (this.active)
|
|
25280
|
+
this.renderFooterPreserveCursor();
|
|
25281
|
+
}
|
|
25282
|
+
/** Clear the SNR gauge (e.g., when starting a fresh task) */
|
|
25283
|
+
clearSNR() {
|
|
25284
|
+
this._snr = null;
|
|
25285
|
+
if (this.active)
|
|
25286
|
+
this.renderFooterPreserveCursor();
|
|
25287
|
+
}
|
|
24872
25288
|
/** Model capabilities — shown as emoji indicators on the status bar */
|
|
24873
25289
|
_caps = {
|
|
24874
25290
|
vision: false,
|
|
@@ -25075,6 +25491,14 @@ var init_status_bar = __esm({
|
|
|
25075
25491
|
const costStr = m.estimatedCost < 0.01 ? `$${m.estimatedCost.toFixed(4)}` : m.estimatedCost < 1 ? `$${m.estimatedCost.toFixed(3)}` : `$${m.estimatedCost.toFixed(2)}`;
|
|
25076
25492
|
costLabel = pipe + pastel2(222, "Cost: ") + c2.bold(costStr);
|
|
25077
25493
|
}
|
|
25494
|
+
let snrLabel = "";
|
|
25495
|
+
if (this._snr) {
|
|
25496
|
+
const snrPct = Math.round(this._snr.ratio * 100);
|
|
25497
|
+
const snrColor = snrPct >= 70 ? c2.green : snrPct >= 40 ? c2.yellow : c2.red;
|
|
25498
|
+
const dPrimeStr = this._snr.dPrime.toFixed(1);
|
|
25499
|
+
const capStr = this._snr.capacityWarning ? c2.red(" !CAP") : "";
|
|
25500
|
+
snrLabel = pipe + pastel2(183, "SNR: ") + snrColor(c2.bold(`${snrPct}%`)) + c2.dim(` d'${dPrimeStr}`) + capStr;
|
|
25501
|
+
}
|
|
25078
25502
|
let speedLabel = "";
|
|
25079
25503
|
if (this._speedTracker.hasData) {
|
|
25080
25504
|
const ratio = this._speedTracker.getSpeedRatio();
|
|
@@ -25098,7 +25522,7 @@ var init_status_bar = __esm({
|
|
|
25098
25522
|
if (this._caps.thinking)
|
|
25099
25523
|
capParts.push("\u{1F9E0}");
|
|
25100
25524
|
const capsLabel = capParts.length > 0 ? pipe + pastel2(183, capParts.join(" ")) : "";
|
|
25101
|
-
return ` ${tokInLabel}${pipe}${tokOutLabel}${pipe}${ctxLabel}${speedLabel}${costLabel}${capsLabel}${recordingLabel}`;
|
|
25525
|
+
return ` ${tokInLabel}${pipe}${tokOutLabel}${pipe}${ctxLabel}${snrLabel}${speedLabel}${costLabel}${capsLabel}${recordingLabel}`;
|
|
25102
25526
|
}
|
|
25103
25527
|
// -------------------------------------------------------------------------
|
|
25104
25528
|
// Private
|
|
@@ -25377,11 +25801,11 @@ var init_status_bar = __esm({
|
|
|
25377
25801
|
import * as readline2 from "node:readline";
|
|
25378
25802
|
import { Writable } from "node:stream";
|
|
25379
25803
|
import { cwd } from "node:process";
|
|
25380
|
-
import { resolve as resolve23, join as
|
|
25804
|
+
import { resolve as resolve23, join as join38, dirname as dirname11, extname as extname9 } from "node:path";
|
|
25381
25805
|
import { createRequire as createRequire2 } from "node:module";
|
|
25382
25806
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
25383
|
-
import { readFileSync as
|
|
25384
|
-
import { existsSync as
|
|
25807
|
+
import { readFileSync as readFileSync21, rmSync as rmSync2, readdirSync as readdirSync13 } from "node:fs";
|
|
25808
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
25385
25809
|
function formatTimeAgo(date) {
|
|
25386
25810
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
25387
25811
|
if (seconds < 60)
|
|
@@ -25400,12 +25824,12 @@ function getVersion() {
|
|
|
25400
25824
|
const require2 = createRequire2(import.meta.url);
|
|
25401
25825
|
const thisDir = dirname11(fileURLToPath8(import.meta.url));
|
|
25402
25826
|
const candidates = [
|
|
25403
|
-
|
|
25404
|
-
|
|
25405
|
-
|
|
25827
|
+
join38(thisDir, "..", "package.json"),
|
|
25828
|
+
join38(thisDir, "..", "..", "package.json"),
|
|
25829
|
+
join38(thisDir, "..", "..", "..", "package.json")
|
|
25406
25830
|
];
|
|
25407
25831
|
for (const pkgPath of candidates) {
|
|
25408
|
-
if (
|
|
25832
|
+
if (existsSync28(pkgPath)) {
|
|
25409
25833
|
const pkg = require2(pkgPath);
|
|
25410
25834
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
25411
25835
|
return pkg.version ?? "0.0.0";
|
|
@@ -25416,7 +25840,7 @@ function getVersion() {
|
|
|
25416
25840
|
}
|
|
25417
25841
|
return "0.0.0";
|
|
25418
25842
|
}
|
|
25419
|
-
function
|
|
25843
|
+
function adaptTool4(tool) {
|
|
25420
25844
|
return {
|
|
25421
25845
|
name: tool.name,
|
|
25422
25846
|
description: tool.description,
|
|
@@ -25512,7 +25936,7 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
25512
25936
|
new AgendaTool(repoRoot)
|
|
25513
25937
|
];
|
|
25514
25938
|
return [
|
|
25515
|
-
...executionTools.map(
|
|
25939
|
+
...executionTools.map(adaptTool4),
|
|
25516
25940
|
createSubAgentTool(config, repoRoot, contextWindowSize),
|
|
25517
25941
|
createTaskCompleteTool()
|
|
25518
25942
|
];
|
|
@@ -25564,7 +25988,7 @@ function createSubAgentTool(config, repoRoot, ctxWindowSize) {
|
|
|
25564
25988
|
new MemoryReadTool(repoRoot),
|
|
25565
25989
|
new MemoryWriteTool(repoRoot)
|
|
25566
25990
|
];
|
|
25567
|
-
subRunner.registerTools(subTools.map(
|
|
25991
|
+
subRunner.registerTools(subTools.map(adaptTool4));
|
|
25568
25992
|
subRunner.registerTool(createTaskCompleteTool());
|
|
25569
25993
|
if (background) {
|
|
25570
25994
|
const promise = subRunner.run(task, `Working directory: ${repoRoot}`).then((result2) => {
|
|
@@ -25594,7 +26018,30 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
25594
26018
|
}
|
|
25595
26019
|
};
|
|
25596
26020
|
}
|
|
25597
|
-
function
|
|
26021
|
+
function gatherMemorySnippets(root) {
|
|
26022
|
+
const snippets = [];
|
|
26023
|
+
const dirs = [
|
|
26024
|
+
join38(root, ".oa", "memory"),
|
|
26025
|
+
join38(root, ".open-agents", "memory")
|
|
26026
|
+
];
|
|
26027
|
+
for (const dir of dirs) {
|
|
26028
|
+
if (!existsSync28(dir))
|
|
26029
|
+
continue;
|
|
26030
|
+
try {
|
|
26031
|
+
for (const f of readdirSync13(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
26032
|
+
const data = JSON.parse(readFileSync21(join38(dir, f), "utf-8"));
|
|
26033
|
+
for (const val of Object.values(data)) {
|
|
26034
|
+
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
26035
|
+
if (v.length > 10)
|
|
26036
|
+
snippets.push(v);
|
|
26037
|
+
}
|
|
26038
|
+
}
|
|
26039
|
+
} catch {
|
|
26040
|
+
}
|
|
26041
|
+
}
|
|
26042
|
+
return snippets;
|
|
26043
|
+
}
|
|
26044
|
+
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction) {
|
|
25598
26045
|
const voiceStyleMap = {
|
|
25599
26046
|
concise: 1,
|
|
25600
26047
|
balanced: 3,
|
|
@@ -25729,7 +26176,7 @@ ${entry.fullContent}`
|
|
|
25729
26176
|
renderVoiceText(desc);
|
|
25730
26177
|
voice.speak(desc);
|
|
25731
26178
|
}
|
|
25732
|
-
renderToolCallStart(event.toolName ?? "unknown", event.toolArgs ?? {});
|
|
26179
|
+
renderToolCallStart(event.toolName ?? "unknown", event.toolArgs ?? {}, config.verbose);
|
|
25733
26180
|
});
|
|
25734
26181
|
break;
|
|
25735
26182
|
case "tool_result": {
|
|
@@ -25745,7 +26192,7 @@ ${entry.fullContent}`
|
|
|
25745
26192
|
const toolDurationMs = toolCallStartMs > 0 ? Date.now() - toolCallStartMs : 0;
|
|
25746
26193
|
toolCallStartMs = 0;
|
|
25747
26194
|
contentWrite(() => {
|
|
25748
|
-
renderToolResult(event.toolName ?? "unknown", event.success ?? false, event.content ?? "");
|
|
26195
|
+
renderToolResult(event.toolName ?? "unknown", event.success ?? false, event.content ?? "", config.verbose);
|
|
25749
26196
|
if (config.verbose && toolDurationMs > 0) {
|
|
25750
26197
|
const durStr = toolDurationMs < 1e3 ? `${toolDurationMs}ms` : `${(toolDurationMs / 1e3).toFixed(1)}s`;
|
|
25751
26198
|
const sizeStr = resultLen > 0 ? ` | ${resultLen.toLocaleString()} chars (~${Math.ceil(resultLen / 4).toLocaleString()} tokens)` : "";
|
|
@@ -25807,6 +26254,8 @@ ${entry.fullContent}`
|
|
|
25807
26254
|
break;
|
|
25808
26255
|
case "compaction":
|
|
25809
26256
|
contentWrite(() => renderWarning(`Context compacted: ${event.content}`));
|
|
26257
|
+
if (onCompaction)
|
|
26258
|
+
onCompaction();
|
|
25810
26259
|
break;
|
|
25811
26260
|
case "status":
|
|
25812
26261
|
contentWrite(() => renderInfo(event.content ?? ""));
|
|
@@ -26111,6 +26560,37 @@ async function startInteractive(config, repoPath) {
|
|
|
26111
26560
|
let dreamEngine = null;
|
|
26112
26561
|
let blessEngine = null;
|
|
26113
26562
|
let dmnEngine = null;
|
|
26563
|
+
const snrEngine = new SNREngine(config, repoRoot);
|
|
26564
|
+
let pendingSNREval = null;
|
|
26565
|
+
function scheduleAgentSNREval(taskPrompt) {
|
|
26566
|
+
if (pendingSNREval)
|
|
26567
|
+
return;
|
|
26568
|
+
pendingSNREval = (async () => {
|
|
26569
|
+
try {
|
|
26570
|
+
const score = await snrEngine.evaluateWithAgents(taskPrompt, []);
|
|
26571
|
+
statusBar.setSNR(score.ratio, score.dPrime, score.capacityWarning);
|
|
26572
|
+
renderSNRUpdate(score);
|
|
26573
|
+
} catch {
|
|
26574
|
+
} finally {
|
|
26575
|
+
pendingSNREval = null;
|
|
26576
|
+
}
|
|
26577
|
+
})();
|
|
26578
|
+
}
|
|
26579
|
+
function compactionSNRCallback() {
|
|
26580
|
+
if (!deepContextEnabled)
|
|
26581
|
+
return void 0;
|
|
26582
|
+
return () => {
|
|
26583
|
+
try {
|
|
26584
|
+
const memSnippets = gatherMemorySnippets(repoRoot);
|
|
26585
|
+
if (memSnippets.length > 0 && lastSubmittedPrompt) {
|
|
26586
|
+
const snr = snrEngine.computeLocalSNR(lastSubmittedPrompt, memSnippets, resolvedContextWindowSize);
|
|
26587
|
+
statusBar.setSNR(snr.ratio, snr.dPrime, snr.capacityWarning);
|
|
26588
|
+
scheduleAgentSNREval(lastSubmittedPrompt);
|
|
26589
|
+
}
|
|
26590
|
+
} catch {
|
|
26591
|
+
}
|
|
26592
|
+
};
|
|
26593
|
+
}
|
|
26114
26594
|
let telegramBridge = null;
|
|
26115
26595
|
let activeTelegramChatId = null;
|
|
26116
26596
|
let dmnRetriggerTimer = null;
|
|
@@ -26140,6 +26620,8 @@ Respond concisely and safely.`;
|
|
|
26140
26620
|
return;
|
|
26141
26621
|
}
|
|
26142
26622
|
writeContent(() => renderInfo("DMN re-activating..."));
|
|
26623
|
+
statusBar.setProcessing(true);
|
|
26624
|
+
statusBar.setBrailleMetrics({ isDreaming: true });
|
|
26143
26625
|
try {
|
|
26144
26626
|
const proposal = await dmnEngine.runCycle((event) => {
|
|
26145
26627
|
if (event.type === "tool_call") {
|
|
@@ -26147,6 +26629,8 @@ Respond concisely and safely.`;
|
|
|
26147
26629
|
`));
|
|
26148
26630
|
}
|
|
26149
26631
|
});
|
|
26632
|
+
statusBar.setProcessing(false);
|
|
26633
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
26150
26634
|
if (proposal) {
|
|
26151
26635
|
const provenanceNote = proposal.provenance.length > 0 ? `
|
|
26152
26636
|
|
|
@@ -26162,6 +26646,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
26162
26646
|
scheduleDMNRetrigger(6e4);
|
|
26163
26647
|
}
|
|
26164
26648
|
} catch (err) {
|
|
26649
|
+
statusBar.setProcessing(false);
|
|
26650
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
26165
26651
|
writeContent(() => renderWarning(`DMN cycle error: ${err instanceof Error ? err.message : String(err)}`));
|
|
26166
26652
|
scheduleDMNRetrigger(6e4);
|
|
26167
26653
|
}
|
|
@@ -26425,6 +26911,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
26425
26911
|
}
|
|
26426
26912
|
dreamEngine = new DreamEngine(currentConfig, repoRoot);
|
|
26427
26913
|
writeContent(() => renderDreamStart(mode));
|
|
26914
|
+
statusBar.setProcessing(true);
|
|
26915
|
+
statusBar.setBrailleMetrics({ isDreaming: true });
|
|
26428
26916
|
dreamEngine.start(mode, (event) => {
|
|
26429
26917
|
if (event.type === "tool_call") {
|
|
26430
26918
|
writeContent(() => renderToolCallStart(event.toolName ?? "unknown", event.toolArgs ?? {}));
|
|
@@ -26438,10 +26926,14 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
26438
26926
|
});
|
|
26439
26927
|
}
|
|
26440
26928
|
}).then((state) => {
|
|
26929
|
+
statusBar.setProcessing(false);
|
|
26930
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
26441
26931
|
writeContent(() => renderDreamEnd(state));
|
|
26442
26932
|
dreamEngine = null;
|
|
26443
26933
|
showPrompt();
|
|
26444
26934
|
}).catch((err) => {
|
|
26935
|
+
statusBar.setProcessing(false);
|
|
26936
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
26445
26937
|
writeContent(() => renderError(`Dream error: ${err instanceof Error ? err.message : String(err)}`));
|
|
26446
26938
|
dreamEngine = null;
|
|
26447
26939
|
showPrompt();
|
|
@@ -26451,6 +26943,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
26451
26943
|
if (dreamEngine?.isActive) {
|
|
26452
26944
|
dreamEngine.stop();
|
|
26453
26945
|
dreamEngine = null;
|
|
26946
|
+
statusBar.setProcessing(false);
|
|
26947
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
26454
26948
|
}
|
|
26455
26949
|
},
|
|
26456
26950
|
isDreaming() {
|
|
@@ -26664,8 +27158,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
26664
27158
|
return true;
|
|
26665
27159
|
},
|
|
26666
27160
|
destroyProject() {
|
|
26667
|
-
const oaPath =
|
|
26668
|
-
if (
|
|
27161
|
+
const oaPath = join38(repoRoot, OA_DIR);
|
|
27162
|
+
if (existsSync28(oaPath)) {
|
|
26669
27163
|
try {
|
|
26670
27164
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
26671
27165
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -26924,7 +27418,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
26924
27418
|
toolPatternStore: toolPatternStore ?? void 0
|
|
26925
27419
|
}, bruteForceEnabled, statusBar, handleSudoRequest, costTracker, (summary) => {
|
|
26926
27420
|
lastCompletedSummary = summary;
|
|
26927
|
-
}, currentTaskType, resolvedContextWindowSize, resolvedCaps, currentStyle, deepContextEnabled);
|
|
27421
|
+
}, currentTaskType, resolvedContextWindowSize, resolvedCaps, currentStyle, deepContextEnabled, compactionSNRCallback());
|
|
26928
27422
|
activeTask = task;
|
|
26929
27423
|
showPrompt();
|
|
26930
27424
|
await task.promise;
|
|
@@ -26939,13 +27433,13 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
26939
27433
|
}
|
|
26940
27434
|
}
|
|
26941
27435
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
26942
|
-
const isImage = isImagePath(cleanPath) &&
|
|
26943
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
27436
|
+
const isImage = isImagePath(cleanPath) && existsSync28(resolve23(repoRoot, cleanPath));
|
|
27437
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync28(resolve23(repoRoot, cleanPath));
|
|
26944
27438
|
if (activeTask) {
|
|
26945
27439
|
if (isImage) {
|
|
26946
27440
|
try {
|
|
26947
27441
|
const imgPath = resolve23(repoRoot, cleanPath);
|
|
26948
|
-
const imgBuffer =
|
|
27442
|
+
const imgBuffer = readFileSync21(imgPath);
|
|
26949
27443
|
const base64 = imgBuffer.toString("base64");
|
|
26950
27444
|
const ext = extname9(cleanPath).toLowerCase();
|
|
26951
27445
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -27014,6 +27508,14 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
27014
27508
|
const displayText = isImage ? `[Image: ${cleanPath}]` : inputLineCount > 1 ? `[pasted ${inputLineCount} lines]` : fullInput;
|
|
27015
27509
|
writeContent(() => renderUserMessage(displayText));
|
|
27016
27510
|
lastSubmittedPrompt = fullInput;
|
|
27511
|
+
try {
|
|
27512
|
+
const memSnippets = gatherMemorySnippets(repoRoot);
|
|
27513
|
+
if (memSnippets.length > 0) {
|
|
27514
|
+
const snr = snrEngine.computeLocalSNR(fullInput, memSnippets, resolvedContextWindowSize);
|
|
27515
|
+
statusBar.setSNR(snr.ratio, snr.dPrime, snr.capacityWarning);
|
|
27516
|
+
}
|
|
27517
|
+
} catch {
|
|
27518
|
+
}
|
|
27017
27519
|
let taskInput = fullInput;
|
|
27018
27520
|
if (restoredSessionContext) {
|
|
27019
27521
|
taskInput = `${restoredSessionContext}
|
|
@@ -27036,7 +27538,7 @@ NEW TASK: ${fullInput}`;
|
|
|
27036
27538
|
toolPatternStore: toolPatternStore ?? void 0
|
|
27037
27539
|
}, bruteForceEnabled, statusBar, handleSudoRequest, costTracker, (summary) => {
|
|
27038
27540
|
lastCompletedSummary = summary;
|
|
27039
|
-
}, currentTaskType, resolvedContextWindowSize, resolvedCaps, currentStyle, deepContextEnabled);
|
|
27541
|
+
}, currentTaskType, resolvedContextWindowSize, resolvedCaps, currentStyle, deepContextEnabled, compactionSNRCallback());
|
|
27040
27542
|
activeTask = task;
|
|
27041
27543
|
showPrompt();
|
|
27042
27544
|
await task.promise;
|
|
@@ -27065,6 +27567,17 @@ NEW TASK: ${fullInput}`;
|
|
|
27065
27567
|
} finally {
|
|
27066
27568
|
statusBar.setProcessing(false);
|
|
27067
27569
|
statusBar.recordSpeedTaskEnd();
|
|
27570
|
+
try {
|
|
27571
|
+
const memSnippets = gatherMemorySnippets(repoRoot);
|
|
27572
|
+
if (memSnippets.length > 0 && lastSubmittedPrompt) {
|
|
27573
|
+
const snr = snrEngine.computeLocalSNR(lastSubmittedPrompt, memSnippets, resolvedContextWindowSize);
|
|
27574
|
+
statusBar.setSNR(snr.ratio, snr.dPrime, snr.capacityWarning);
|
|
27575
|
+
}
|
|
27576
|
+
} catch {
|
|
27577
|
+
}
|
|
27578
|
+
if (deepContextEnabled && lastSubmittedPrompt) {
|
|
27579
|
+
scheduleAgentSNREval(lastSubmittedPrompt);
|
|
27580
|
+
}
|
|
27068
27581
|
if (activeTask) {
|
|
27069
27582
|
sessionFilesTouched = Array.from(activeTask.filesTouched);
|
|
27070
27583
|
sessionToolCallCount = activeTask.toolCallCount;
|
|
@@ -27119,6 +27632,8 @@ Respond concisely and safely.`;
|
|
|
27119
27632
|
}
|
|
27120
27633
|
if (dmnEngine) {
|
|
27121
27634
|
writeContent(() => renderInfo("No queued tasks \u2014 DMN self-reflection activating..."));
|
|
27635
|
+
statusBar.setProcessing(true);
|
|
27636
|
+
statusBar.setBrailleMetrics({ isDreaming: true });
|
|
27122
27637
|
try {
|
|
27123
27638
|
const proposal = await dmnEngine.runCycle((event) => {
|
|
27124
27639
|
if (event.type === "tool_call") {
|
|
@@ -27126,6 +27641,8 @@ Respond concisely and safely.`;
|
|
|
27126
27641
|
`));
|
|
27127
27642
|
}
|
|
27128
27643
|
});
|
|
27644
|
+
statusBar.setProcessing(false);
|
|
27645
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
27129
27646
|
if (proposal) {
|
|
27130
27647
|
const provenanceNote = proposal.provenance.length > 0 ? `
|
|
27131
27648
|
|
|
@@ -27145,6 +27662,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
27145
27662
|
scheduleDMNRetrigger(cooldownSec * 1e3);
|
|
27146
27663
|
}
|
|
27147
27664
|
} catch (err) {
|
|
27665
|
+
statusBar.setProcessing(false);
|
|
27666
|
+
statusBar.setBrailleMetrics({ isDreaming: false });
|
|
27148
27667
|
writeContent(() => renderWarning(`DMN cycle error: ${err instanceof Error ? err.message : String(err)}`));
|
|
27149
27668
|
if (blessEngine?.isActive) {
|
|
27150
27669
|
scheduleDMNRetrigger(6e4);
|
|
@@ -27259,6 +27778,7 @@ var init_interactive = __esm({
|
|
|
27259
27778
|
init_dream_engine();
|
|
27260
27779
|
init_bless_engine();
|
|
27261
27780
|
init_dmn_engine();
|
|
27781
|
+
init_snr_engine();
|
|
27262
27782
|
init_telegram_bridge();
|
|
27263
27783
|
init_status_bar();
|
|
27264
27784
|
init_dist6();
|
|
@@ -27297,7 +27817,7 @@ import { glob } from "glob";
|
|
|
27297
27817
|
import ignore from "ignore";
|
|
27298
27818
|
import { readFile as readFile14, stat as stat4 } from "node:fs/promises";
|
|
27299
27819
|
import { createHash } from "node:crypto";
|
|
27300
|
-
import { join as
|
|
27820
|
+
import { join as join39, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
|
|
27301
27821
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
27302
27822
|
var init_codebase_indexer = __esm({
|
|
27303
27823
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -27341,7 +27861,7 @@ var init_codebase_indexer = __esm({
|
|
|
27341
27861
|
const ig = ignore.default();
|
|
27342
27862
|
if (this.config.respectGitignore) {
|
|
27343
27863
|
try {
|
|
27344
|
-
const gitignoreContent = await readFile14(
|
|
27864
|
+
const gitignoreContent = await readFile14(join39(this.config.rootDir, ".gitignore"), "utf-8");
|
|
27345
27865
|
ig.add(gitignoreContent);
|
|
27346
27866
|
} catch {
|
|
27347
27867
|
}
|
|
@@ -27356,7 +27876,7 @@ var init_codebase_indexer = __esm({
|
|
|
27356
27876
|
for (const relativePath of files) {
|
|
27357
27877
|
if (ig.ignores(relativePath))
|
|
27358
27878
|
continue;
|
|
27359
|
-
const fullPath =
|
|
27879
|
+
const fullPath = join39(this.config.rootDir, relativePath);
|
|
27360
27880
|
try {
|
|
27361
27881
|
const fileStat = await stat4(fullPath);
|
|
27362
27882
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -27379,7 +27899,7 @@ var init_codebase_indexer = __esm({
|
|
|
27379
27899
|
}
|
|
27380
27900
|
buildTree(files) {
|
|
27381
27901
|
const root = {
|
|
27382
|
-
name:
|
|
27902
|
+
name: basename15(this.config.rootDir),
|
|
27383
27903
|
path: this.config.rootDir,
|
|
27384
27904
|
type: "directory",
|
|
27385
27905
|
children: []
|
|
@@ -27402,7 +27922,7 @@ var init_codebase_indexer = __esm({
|
|
|
27402
27922
|
if (!child) {
|
|
27403
27923
|
child = {
|
|
27404
27924
|
name: part,
|
|
27405
|
-
path:
|
|
27925
|
+
path: join39(current.path, part),
|
|
27406
27926
|
type: "directory",
|
|
27407
27927
|
children: []
|
|
27408
27928
|
};
|
|
@@ -27485,13 +28005,13 @@ __export(index_repo_exports, {
|
|
|
27485
28005
|
indexRepoCommand: () => indexRepoCommand
|
|
27486
28006
|
});
|
|
27487
28007
|
import { resolve as resolve24 } from "node:path";
|
|
27488
|
-
import { existsSync as
|
|
28008
|
+
import { existsSync as existsSync29, statSync as statSync10 } from "node:fs";
|
|
27489
28009
|
import { cwd as cwd2 } from "node:process";
|
|
27490
28010
|
async function indexRepoCommand(opts, _config) {
|
|
27491
28011
|
const repoRoot = resolve24(opts.repoPath ?? cwd2());
|
|
27492
28012
|
printHeader("Index Repository");
|
|
27493
28013
|
printInfo(`Indexing: ${repoRoot}`);
|
|
27494
|
-
if (!
|
|
28014
|
+
if (!existsSync29(repoRoot)) {
|
|
27495
28015
|
printError(`Path does not exist: ${repoRoot}`);
|
|
27496
28016
|
process.exit(1);
|
|
27497
28017
|
}
|
|
@@ -27743,7 +28263,7 @@ var config_exports = {};
|
|
|
27743
28263
|
__export(config_exports, {
|
|
27744
28264
|
configCommand: () => configCommand
|
|
27745
28265
|
});
|
|
27746
|
-
import { join as
|
|
28266
|
+
import { join as join40, resolve as resolve25 } from "node:path";
|
|
27747
28267
|
import { homedir as homedir13 } from "node:os";
|
|
27748
28268
|
import { cwd as cwd3 } from "node:process";
|
|
27749
28269
|
function redactIfSensitive(key, value) {
|
|
@@ -27802,7 +28322,7 @@ function handleShow(opts, config) {
|
|
|
27802
28322
|
}
|
|
27803
28323
|
}
|
|
27804
28324
|
printSection("Config File");
|
|
27805
|
-
printInfo(`~/.open-agents/config.json (${
|
|
28325
|
+
printInfo(`~/.open-agents/config.json (${join40(homedir13(), ".open-agents", "config.json")})`);
|
|
27806
28326
|
printSection("Priority Chain");
|
|
27807
28327
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
27808
28328
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -27841,7 +28361,7 @@ function handleSet(opts, _config) {
|
|
|
27841
28361
|
const coerced = coerceForSettings(key, value);
|
|
27842
28362
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
27843
28363
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
27844
|
-
printInfo(`Saved to ${
|
|
28364
|
+
printInfo(`Saved to ${join40(repoRoot, ".oa", "settings.json")}`);
|
|
27845
28365
|
printInfo("This override applies only when running in this workspace.");
|
|
27846
28366
|
} catch (err) {
|
|
27847
28367
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -28061,7 +28581,7 @@ __export(eval_exports, {
|
|
|
28061
28581
|
});
|
|
28062
28582
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
28063
28583
|
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12 } from "node:fs";
|
|
28064
|
-
import { join as
|
|
28584
|
+
import { join as join41 } from "node:path";
|
|
28065
28585
|
async function evalCommand(opts, config) {
|
|
28066
28586
|
const suiteName = opts.suite ?? "basic";
|
|
28067
28587
|
const suite = SUITES[suiteName];
|
|
@@ -28182,9 +28702,9 @@ async function evalCommand(opts, config) {
|
|
|
28182
28702
|
process.exit(failed > 0 ? 1 : 0);
|
|
28183
28703
|
}
|
|
28184
28704
|
function createTempEvalRepo() {
|
|
28185
|
-
const dir =
|
|
28705
|
+
const dir = join41(tmpdir7(), `open-agents-eval-${Date.now()}`);
|
|
28186
28706
|
mkdirSync13(dir, { recursive: true });
|
|
28187
|
-
writeFileSync12(
|
|
28707
|
+
writeFileSync12(join41(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
28188
28708
|
return dir;
|
|
28189
28709
|
}
|
|
28190
28710
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -28244,7 +28764,7 @@ init_updater();
|
|
|
28244
28764
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
28245
28765
|
import { createRequire as createRequire3 } from "node:module";
|
|
28246
28766
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
28247
|
-
import { dirname as dirname12, join as
|
|
28767
|
+
import { dirname as dirname12, join as join42 } from "node:path";
|
|
28248
28768
|
|
|
28249
28769
|
// packages/cli/dist/cli.js
|
|
28250
28770
|
import { createInterface } from "node:readline";
|
|
@@ -28351,7 +28871,7 @@ init_output();
|
|
|
28351
28871
|
function getVersion2() {
|
|
28352
28872
|
try {
|
|
28353
28873
|
const require2 = createRequire3(import.meta.url);
|
|
28354
|
-
const pkgPath =
|
|
28874
|
+
const pkgPath = join42(dirname12(fileURLToPath9(import.meta.url)), "..", "package.json");
|
|
28355
28875
|
const pkg = require2(pkgPath);
|
|
28356
28876
|
return pkg.version;
|
|
28357
28877
|
} catch {
|
package/package.json
CHANGED