omnius 1.0.94 → 1.0.96
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 +1137 -206
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -131793,16 +131793,16 @@ var require_cache2 = __commonJS({
|
|
|
131793
131793
|
return dispatch(opts2, handler);
|
|
131794
131794
|
}
|
|
131795
131795
|
if (origins !== void 0) {
|
|
131796
|
-
const
|
|
131796
|
+
const requestOrigin2 = opts2.origin.toString().toLowerCase();
|
|
131797
131797
|
let isAllowed = false;
|
|
131798
131798
|
for (let i2 = 0; i2 < origins.length; i2++) {
|
|
131799
131799
|
const allowed = origins[i2];
|
|
131800
131800
|
if (typeof allowed === "string") {
|
|
131801
|
-
if (allowed.toLowerCase() ===
|
|
131801
|
+
if (allowed.toLowerCase() === requestOrigin2) {
|
|
131802
131802
|
isAllowed = true;
|
|
131803
131803
|
break;
|
|
131804
131804
|
}
|
|
131805
|
-
} else if (allowed.test(
|
|
131805
|
+
} else if (allowed.test(requestOrigin2)) {
|
|
131806
131806
|
isAllowed = true;
|
|
131807
131807
|
break;
|
|
131808
131808
|
}
|
|
@@ -246345,8 +246345,8 @@ var require_pattern = __commonJS({
|
|
|
246345
246345
|
}
|
|
246346
246346
|
exports.endsWithSlashGlobStar = endsWithSlashGlobStar;
|
|
246347
246347
|
function isAffectDepthOfReadingPattern(pattern) {
|
|
246348
|
-
const
|
|
246349
|
-
return endsWithSlashGlobStar(pattern) || isStaticPattern(
|
|
246348
|
+
const basename31 = path12.basename(pattern);
|
|
246349
|
+
return endsWithSlashGlobStar(pattern) || isStaticPattern(basename31);
|
|
246350
246350
|
}
|
|
246351
246351
|
exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
|
|
246352
246352
|
function expandPatternsWithBraceExpansion(patterns) {
|
|
@@ -246982,7 +246982,7 @@ var require_async3 = __commonJS({
|
|
|
246982
246982
|
readdirWithFileTypes(directory, settings, callback);
|
|
246983
246983
|
return;
|
|
246984
246984
|
}
|
|
246985
|
-
|
|
246985
|
+
readdir7(directory, settings, callback);
|
|
246986
246986
|
}
|
|
246987
246987
|
exports.read = read3;
|
|
246988
246988
|
function readdirWithFileTypes(directory, settings, callback) {
|
|
@@ -247031,7 +247031,7 @@ var require_async3 = __commonJS({
|
|
|
247031
247031
|
});
|
|
247032
247032
|
};
|
|
247033
247033
|
}
|
|
247034
|
-
function
|
|
247034
|
+
function readdir7(directory, settings, callback) {
|
|
247035
247035
|
settings.fs.readdir(directory, (readdirError, names) => {
|
|
247036
247036
|
if (readdirError !== null) {
|
|
247037
247037
|
callFailureCallback(callback, readdirError);
|
|
@@ -247066,7 +247066,7 @@ var require_async3 = __commonJS({
|
|
|
247066
247066
|
});
|
|
247067
247067
|
});
|
|
247068
247068
|
}
|
|
247069
|
-
exports.readdir =
|
|
247069
|
+
exports.readdir = readdir7;
|
|
247070
247070
|
function callFailureCallback(callback, error) {
|
|
247071
247071
|
callback(error);
|
|
247072
247072
|
}
|
|
@@ -247090,7 +247090,7 @@ var require_sync2 = __commonJS({
|
|
|
247090
247090
|
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
|
|
247091
247091
|
return readdirWithFileTypes(directory, settings);
|
|
247092
247092
|
}
|
|
247093
|
-
return
|
|
247093
|
+
return readdir7(directory, settings);
|
|
247094
247094
|
}
|
|
247095
247095
|
exports.read = read3;
|
|
247096
247096
|
function readdirWithFileTypes(directory, settings) {
|
|
@@ -247115,7 +247115,7 @@ var require_sync2 = __commonJS({
|
|
|
247115
247115
|
});
|
|
247116
247116
|
}
|
|
247117
247117
|
exports.readdirWithFileTypes = readdirWithFileTypes;
|
|
247118
|
-
function
|
|
247118
|
+
function readdir7(directory, settings) {
|
|
247119
247119
|
const names = settings.fs.readdirSync(directory);
|
|
247120
247120
|
return names.map((name10) => {
|
|
247121
247121
|
const entryPath = common.joinPathSegments(directory, name10, settings.pathSegmentSeparator);
|
|
@@ -247131,7 +247131,7 @@ var require_sync2 = __commonJS({
|
|
|
247131
247131
|
return entry;
|
|
247132
247132
|
});
|
|
247133
247133
|
}
|
|
247134
|
-
exports.readdir =
|
|
247134
|
+
exports.readdir = readdir7;
|
|
247135
247135
|
}
|
|
247136
247136
|
});
|
|
247137
247137
|
|
|
@@ -406906,9 +406906,9 @@ ${lanes.join("\n")}
|
|
|
406906
406906
|
/*ignoreCase*/
|
|
406907
406907
|
false
|
|
406908
406908
|
)) {
|
|
406909
|
-
const
|
|
406910
|
-
if (
|
|
406911
|
-
const name10 = removeSuffix(removePrefix(
|
|
406909
|
+
const basename31 = getBaseFileName(a2.fileName);
|
|
406910
|
+
if (basename31 === "lib.d.ts" || basename31 === "lib.es6.d.ts") return 0;
|
|
406911
|
+
const name10 = removeSuffix(removePrefix(basename31, "lib."), ".d.ts");
|
|
406912
406912
|
const index = libs.indexOf(name10);
|
|
406913
406913
|
if (index !== -1) return index + 1;
|
|
406914
406914
|
}
|
|
@@ -470834,8 +470834,8 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
470834
470834
|
}
|
|
470835
470835
|
};
|
|
470836
470836
|
for (const file of files) {
|
|
470837
|
-
const
|
|
470838
|
-
if (
|
|
470837
|
+
const basename31 = getBaseFileName(file);
|
|
470838
|
+
if (basename31 === "package.json" || basename31 === "bower.json") {
|
|
470839
470839
|
createProjectWatcher(
|
|
470840
470840
|
file,
|
|
470841
470841
|
"FileWatcher"
|
|
@@ -474519,8 +474519,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
474519
474519
|
var _a;
|
|
474520
474520
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
474521
474521
|
if (!fileOrDirectoryPath) return;
|
|
474522
|
-
const
|
|
474523
|
-
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (
|
|
474522
|
+
const basename31 = getBaseFileName(fileOrDirectoryPath);
|
|
474523
|
+
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename31 === "package.json" || basename31 === "node_modules")) {
|
|
474524
474524
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
474525
474525
|
var _a2;
|
|
474526
474526
|
(_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
|
|
@@ -483423,7 +483423,7 @@ var require_path_browserify = __commonJS({
|
|
|
483423
483423
|
if (hasRoot && end === 1) return "//";
|
|
483424
483424
|
return path12.slice(0, end);
|
|
483425
483425
|
},
|
|
483426
|
-
basename: function
|
|
483426
|
+
basename: function basename31(path12, ext) {
|
|
483427
483427
|
if (ext !== void 0 && typeof ext !== "string") throw new TypeError('"ext" argument must be a string');
|
|
483428
483428
|
assertPath(path12);
|
|
483429
483429
|
var start2 = 0;
|
|
@@ -524121,9 +524121,9 @@ var init_verifierRunner = __esm({
|
|
|
524121
524121
|
async executeTests(patch, repoRoot) {
|
|
524122
524122
|
if (patch.testsToRun.length === 0)
|
|
524123
524123
|
return "(no tests specified)";
|
|
524124
|
-
const { execFile:
|
|
524124
|
+
const { execFile: execFile8 } = await import("node:child_process");
|
|
524125
524125
|
const { promisify: promisify7 } = await import("node:util");
|
|
524126
|
-
const execFileAsync5 = promisify7(
|
|
524126
|
+
const execFileAsync5 = promisify7(execFile8);
|
|
524127
524127
|
const outputs = [];
|
|
524128
524128
|
const workDir = this.options.workingDir || repoRoot;
|
|
524129
524129
|
for (const cmd of patch.testsToRun.slice(0, 3)) {
|
|
@@ -524289,9 +524289,9 @@ var init_retryController = __esm({
|
|
|
524289
524289
|
* Call after each verification to get the next action.
|
|
524290
524290
|
* Also increments the internal attempt counter.
|
|
524291
524291
|
*/
|
|
524292
|
-
evaluate(
|
|
524292
|
+
evaluate(decision2) {
|
|
524293
524293
|
this.attemptCount += 1;
|
|
524294
|
-
if (
|
|
524294
|
+
if (decision2.status === "pass" && decision2.nextAction === "finish") {
|
|
524295
524295
|
return {
|
|
524296
524296
|
outcome: "accept",
|
|
524297
524297
|
attemptNumber: this.attemptCount,
|
|
@@ -524299,7 +524299,7 @@ var init_retryController = __esm({
|
|
|
524299
524299
|
repeatLoopDetected: false
|
|
524300
524300
|
};
|
|
524301
524301
|
}
|
|
524302
|
-
if (
|
|
524302
|
+
if (decision2.nextAction === "rollback") {
|
|
524303
524303
|
return {
|
|
524304
524304
|
outcome: "rollback",
|
|
524305
524305
|
attemptNumber: this.attemptCount,
|
|
@@ -524307,7 +524307,7 @@ var init_retryController = __esm({
|
|
|
524307
524307
|
repeatLoopDetected: false
|
|
524308
524308
|
};
|
|
524309
524309
|
}
|
|
524310
|
-
if (
|
|
524310
|
+
if (decision2.nextAction === "inspect_more") {
|
|
524311
524311
|
if (this.attemptCount > this.maxRetries) {
|
|
524312
524312
|
return {
|
|
524313
524313
|
outcome: "give_up",
|
|
@@ -524323,7 +524323,7 @@ var init_retryController = __esm({
|
|
|
524323
524323
|
repeatLoopDetected: false
|
|
524324
524324
|
};
|
|
524325
524325
|
}
|
|
524326
|
-
const fingerprint =
|
|
524326
|
+
const fingerprint = decision2.failureFingerprint;
|
|
524327
524327
|
let repeatLoopDetected = false;
|
|
524328
524328
|
if (fingerprint) {
|
|
524329
524329
|
repeatLoopDetected = this.fingerprintHistory.includes(fingerprint);
|
|
@@ -524348,7 +524348,7 @@ var init_retryController = __esm({
|
|
|
524348
524348
|
return {
|
|
524349
524349
|
outcome: "retry",
|
|
524350
524350
|
attemptNumber: this.attemptCount,
|
|
524351
|
-
reason: `Verification ${
|
|
524351
|
+
reason: `Verification ${decision2.status}. Retrying (attempt ${this.attemptCount} of ${this.maxRetries}).`,
|
|
524352
524352
|
repeatLoopDetected: false
|
|
524353
524353
|
};
|
|
524354
524354
|
}
|
|
@@ -524760,6 +524760,620 @@ var init_textSanitize = __esm({
|
|
|
524760
524760
|
}
|
|
524761
524761
|
});
|
|
524762
524762
|
|
|
524763
|
+
// packages/orchestrator/dist/ollama-pool-cleanup.js
|
|
524764
|
+
var ollama_pool_cleanup_exports = {};
|
|
524765
|
+
__export(ollama_pool_cleanup_exports, {
|
|
524766
|
+
classifyOllamaProcesses: () => classifyOllamaProcesses,
|
|
524767
|
+
cleanupStaleOllamaProcesses: () => cleanupStaleOllamaProcesses,
|
|
524768
|
+
scanOllamaProcesses: () => scanOllamaProcesses
|
|
524769
|
+
});
|
|
524770
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
524771
|
+
import { readdir as readdir6, readFile as fsReadFile, readlink } from "node:fs/promises";
|
|
524772
|
+
import { basename as basename16 } from "node:path";
|
|
524773
|
+
async function scanOllamaProcesses(options2 = {}) {
|
|
524774
|
+
const system = makeSystem(options2.system);
|
|
524775
|
+
const config = resolveDefaultPoolConfig();
|
|
524776
|
+
const baseInstanceUrl = (options2.baseInstanceUrl ?? config.baseInstanceUrl).replace(/\/+$/, "");
|
|
524777
|
+
const basePort = portFromUrl(baseInstanceUrl) ?? DEFAULT_BASE_PORT;
|
|
524778
|
+
const poolPortStart = options2.poolPortStart ?? config.spawnPortStart ?? DEFAULT_POOL_PORT_START;
|
|
524779
|
+
const protectedPorts = uniqueNumbers([
|
|
524780
|
+
DEFAULT_BASE_PORT,
|
|
524781
|
+
basePort,
|
|
524782
|
+
...options2.protectedPorts ?? []
|
|
524783
|
+
]);
|
|
524784
|
+
const scannedAtMs = system.now();
|
|
524785
|
+
const [psRows, portMap, systemdOllamaMainPid, gpuMemoryByPid] = await Promise.all([
|
|
524786
|
+
readPsRows(system),
|
|
524787
|
+
readListeningPortMap(system),
|
|
524788
|
+
readSystemdOllamaMainPid(system),
|
|
524789
|
+
readGpuMemoryByPid(system)
|
|
524790
|
+
]);
|
|
524791
|
+
const snapshots = [];
|
|
524792
|
+
for (const row of psRows) {
|
|
524793
|
+
if (!isOllamaServeCommand(row.command))
|
|
524794
|
+
continue;
|
|
524795
|
+
const env2 = await readProcEnv(system, row.pid);
|
|
524796
|
+
const ports = uniqueNumbers([
|
|
524797
|
+
...portMap.get(row.pid) ?? [],
|
|
524798
|
+
...portsFromEnv(env2.values)
|
|
524799
|
+
]);
|
|
524800
|
+
const ollamaApiPorts = await probeOllamaPorts(system, ports);
|
|
524801
|
+
snapshots.push({
|
|
524802
|
+
pid: row.pid,
|
|
524803
|
+
ppid: row.ppid,
|
|
524804
|
+
command: row.command,
|
|
524805
|
+
cpuPct: row.cpuPct,
|
|
524806
|
+
memPct: row.memPct,
|
|
524807
|
+
elapsedMs: row.elapsedMs,
|
|
524808
|
+
ports,
|
|
524809
|
+
ollamaApiPorts,
|
|
524810
|
+
envReadable: env2.readable,
|
|
524811
|
+
env: env2.values,
|
|
524812
|
+
gpuMemoryMb: gpuMemoryByPid.get(row.pid) ?? null,
|
|
524813
|
+
isOllamaServe: true
|
|
524814
|
+
});
|
|
524815
|
+
}
|
|
524816
|
+
const decisions = classifyOllamaProcesses(snapshots, {
|
|
524817
|
+
baseInstanceUrl,
|
|
524818
|
+
protectedPorts,
|
|
524819
|
+
poolPortStart,
|
|
524820
|
+
poolPortEnd: options2.poolPortEnd,
|
|
524821
|
+
minAgeMs: options2.minAgeMs,
|
|
524822
|
+
cpuThresholdPct: options2.cpuThresholdPct,
|
|
524823
|
+
poolStatus: options2.poolStatus,
|
|
524824
|
+
systemdOllamaMainPid
|
|
524825
|
+
});
|
|
524826
|
+
return {
|
|
524827
|
+
scannedAtMs,
|
|
524828
|
+
baseInstanceUrl,
|
|
524829
|
+
protectedPorts,
|
|
524830
|
+
poolPortStart,
|
|
524831
|
+
systemdOllamaMainPid,
|
|
524832
|
+
processes: snapshots,
|
|
524833
|
+
decisions,
|
|
524834
|
+
provenance: {
|
|
524835
|
+
entity: `urn:omnius:ollama-pool-cleanup:${scannedAtMs}`,
|
|
524836
|
+
activity: "ollama-process-scan",
|
|
524837
|
+
agent: PROVENANCE_AGENT,
|
|
524838
|
+
timestampMs: scannedAtMs
|
|
524839
|
+
}
|
|
524840
|
+
};
|
|
524841
|
+
}
|
|
524842
|
+
async function cleanupStaleOllamaProcesses(options2 = {}) {
|
|
524843
|
+
const system = makeSystem(options2.system);
|
|
524844
|
+
const dryRun = options2.dryRun !== false;
|
|
524845
|
+
const scan = await scanOllamaProcesses({ ...options2, system });
|
|
524846
|
+
const inference = await maybeApplyInference(scan, options2, system);
|
|
524847
|
+
const decisions = inference.decisions;
|
|
524848
|
+
const report2 = {
|
|
524849
|
+
...scan,
|
|
524850
|
+
decisions,
|
|
524851
|
+
dryRun,
|
|
524852
|
+
usedInference: inference.usedInference,
|
|
524853
|
+
inferenceFallbackReason: inference.fallbackReason,
|
|
524854
|
+
terminated: [],
|
|
524855
|
+
skipped: [],
|
|
524856
|
+
errors: [],
|
|
524857
|
+
provenance: {
|
|
524858
|
+
entity: scan.provenance.entity,
|
|
524859
|
+
activity: dryRun ? "ollama-process-cleanup-dry-run" : "ollama-process-cleanup",
|
|
524860
|
+
agent: PROVENANCE_AGENT,
|
|
524861
|
+
timestampMs: scan.scannedAtMs
|
|
524862
|
+
}
|
|
524863
|
+
};
|
|
524864
|
+
for (const decision2 of decisions) {
|
|
524865
|
+
const proc = scan.processes.find((p2) => p2.pid === decision2.pid);
|
|
524866
|
+
if (!proc)
|
|
524867
|
+
continue;
|
|
524868
|
+
if (decision2.action !== "terminate") {
|
|
524869
|
+
report2.skipped.push({ pid: decision2.pid, reason: decision2.reasons.join("; ") || "kept" });
|
|
524870
|
+
continue;
|
|
524871
|
+
}
|
|
524872
|
+
const recheck = classifyOllamaProcesses([proc], {
|
|
524873
|
+
baseInstanceUrl: scan.baseInstanceUrl,
|
|
524874
|
+
protectedPorts: scan.protectedPorts,
|
|
524875
|
+
poolPortStart: scan.poolPortStart,
|
|
524876
|
+
poolPortEnd: options2.poolPortEnd,
|
|
524877
|
+
minAgeMs: options2.minAgeMs,
|
|
524878
|
+
cpuThresholdPct: options2.cpuThresholdPct,
|
|
524879
|
+
poolStatus: options2.poolStatus,
|
|
524880
|
+
systemdOllamaMainPid: scan.systemdOllamaMainPid
|
|
524881
|
+
})[0];
|
|
524882
|
+
if (!recheck || recheck.action !== "terminate") {
|
|
524883
|
+
report2.skipped.push({ pid: decision2.pid, reason: "final safety recheck refused termination" });
|
|
524884
|
+
continue;
|
|
524885
|
+
}
|
|
524886
|
+
if (dryRun) {
|
|
524887
|
+
report2.terminated.push({ pid: proc.pid, ports: proc.ports, signal: "dry-run", verified: false });
|
|
524888
|
+
continue;
|
|
524889
|
+
}
|
|
524890
|
+
try {
|
|
524891
|
+
system.kill(proc.pid, "SIGTERM");
|
|
524892
|
+
await system.sleep(options2.graceMs ?? DEFAULT_GRACE_MS);
|
|
524893
|
+
let signal = "SIGTERM";
|
|
524894
|
+
if (system.isPidAlive(proc.pid)) {
|
|
524895
|
+
system.kill(proc.pid, "SIGKILL");
|
|
524896
|
+
signal = "SIGKILL";
|
|
524897
|
+
await system.sleep(250);
|
|
524898
|
+
}
|
|
524899
|
+
const verified = !system.isPidAlive(proc.pid) && await portsClosed(system, proc.ollamaApiPorts);
|
|
524900
|
+
report2.terminated.push({ pid: proc.pid, ports: proc.ports, signal, verified });
|
|
524901
|
+
} catch (err) {
|
|
524902
|
+
report2.errors.push({
|
|
524903
|
+
pid: proc.pid,
|
|
524904
|
+
error: err instanceof Error ? err.message : String(err)
|
|
524905
|
+
});
|
|
524906
|
+
}
|
|
524907
|
+
}
|
|
524908
|
+
return report2;
|
|
524909
|
+
}
|
|
524910
|
+
function classifyOllamaProcesses(processes, options2 = {}) {
|
|
524911
|
+
const config = resolveDefaultPoolConfig();
|
|
524912
|
+
const basePort = portFromUrl(options2.baseInstanceUrl ?? config.baseInstanceUrl) ?? DEFAULT_BASE_PORT;
|
|
524913
|
+
const protectedPorts = new Set(uniqueNumbers([
|
|
524914
|
+
DEFAULT_BASE_PORT,
|
|
524915
|
+
basePort,
|
|
524916
|
+
...options2.protectedPorts ?? []
|
|
524917
|
+
]));
|
|
524918
|
+
const poolPortStart = options2.poolPortStart ?? config.spawnPortStart ?? DEFAULT_POOL_PORT_START;
|
|
524919
|
+
const poolPortEnd = options2.poolPortEnd ?? poolPortStart + 128;
|
|
524920
|
+
const minAgeMs = options2.minAgeMs ?? DEFAULT_MIN_AGE_MS;
|
|
524921
|
+
const cpuThresholdPct = options2.cpuThresholdPct ?? DEFAULT_CPU_THRESHOLD_PCT;
|
|
524922
|
+
const activeRefs = activePoolRefs(options2.poolStatus ?? null);
|
|
524923
|
+
return processes.map((proc) => {
|
|
524924
|
+
const reasons = [];
|
|
524925
|
+
const hasProtectedPort = proc.ports.some((p2) => protectedPorts.has(p2));
|
|
524926
|
+
const isSystemdMain = options2.systemdOllamaMainPid !== null && options2.systemdOllamaMainPid !== void 0 && proc.pid === options2.systemdOllamaMainPid;
|
|
524927
|
+
const tracked = activeRefs.pids.has(proc.pid) || proc.ports.some((p2) => activeRefs.ports.has(p2));
|
|
524928
|
+
const inPoolPortRange = proc.ports.some((p2) => p2 >= poolPortStart && p2 <= poolPortEnd);
|
|
524929
|
+
const envPort = portsFromEnv(proc.env).some((p2) => proc.ports.includes(p2));
|
|
524930
|
+
const hasPortEvidence = proc.ports.length > 0 && proc.ollamaApiPorts.length > 0;
|
|
524931
|
+
const lowCpu = proc.cpuPct === null || proc.cpuPct <= cpuThresholdPct;
|
|
524932
|
+
const oldEnough = proc.elapsedMs === null || proc.elapsedMs >= minAgeMs;
|
|
524933
|
+
if (!proc.isOllamaServe) {
|
|
524934
|
+
return decision(proc, "keep", "unknown-ollama", false, false, "deterministic", ["not an ollama serve process"]);
|
|
524935
|
+
}
|
|
524936
|
+
if (isSystemdMain)
|
|
524937
|
+
reasons.push("systemd ollama.service main PID");
|
|
524938
|
+
if (hasProtectedPort)
|
|
524939
|
+
reasons.push(`owns protected port ${proc.ports.filter((p2) => protectedPorts.has(p2)).join(",")}`);
|
|
524940
|
+
if (isSystemdMain || hasProtectedPort) {
|
|
524941
|
+
return decision(proc, "keep", "base-service", true, false, "deterministic", reasons);
|
|
524942
|
+
}
|
|
524943
|
+
if (tracked) {
|
|
524944
|
+
return decision(proc, "keep", "active-pool-owned", true, false, "deterministic", ["tracked by live in-memory pool"]);
|
|
524945
|
+
}
|
|
524946
|
+
if (!hasPortEvidence)
|
|
524947
|
+
reasons.push("no verified Ollama API listening port for this PID");
|
|
524948
|
+
if (!inPoolPortRange && !envPort)
|
|
524949
|
+
reasons.push(`not in pool port range ${poolPortStart}-${poolPortEnd} and no OLLAMA_HOST evidence`);
|
|
524950
|
+
if (!lowCpu)
|
|
524951
|
+
reasons.push(`CPU ${proc.cpuPct?.toFixed(1)}% exceeds ${cpuThresholdPct}%`);
|
|
524952
|
+
if (!oldEnough)
|
|
524953
|
+
reasons.push(`age ${proc.elapsedMs}ms below ${minAgeMs}ms`);
|
|
524954
|
+
const eligible = hasPortEvidence && (inPoolPortRange || envPort) && lowCpu && oldEnough;
|
|
524955
|
+
if (!eligible) {
|
|
524956
|
+
return decision(proc, "keep", "unknown-ollama", false, false, "deterministic", reasons);
|
|
524957
|
+
}
|
|
524958
|
+
reasons.push("old low-utilization untracked pool-range Ollama runner");
|
|
524959
|
+
return decision(proc, "terminate", "stale-pool-runner", false, true, "deterministic", reasons);
|
|
524960
|
+
});
|
|
524961
|
+
}
|
|
524962
|
+
function decision(proc, action, classification, protectedProc, eligible, source, reasons) {
|
|
524963
|
+
return {
|
|
524964
|
+
pid: proc.pid,
|
|
524965
|
+
action,
|
|
524966
|
+
classification,
|
|
524967
|
+
confidence: eligible ? 0.92 : protectedProc ? 1 : 0.5,
|
|
524968
|
+
protected: protectedProc,
|
|
524969
|
+
eligible,
|
|
524970
|
+
source,
|
|
524971
|
+
reasons
|
|
524972
|
+
};
|
|
524973
|
+
}
|
|
524974
|
+
async function maybeApplyInference(scan, options2, system) {
|
|
524975
|
+
const mode = options2.useInference ?? "auto";
|
|
524976
|
+
if (mode === false || process.env["OMNIUS_OLLAMA_CLEANUP_INFERENCE"] === "0") {
|
|
524977
|
+
return { decisions: scan.decisions, usedInference: false, fallbackReason: null };
|
|
524978
|
+
}
|
|
524979
|
+
if (mode === "auto" || mode === true) {
|
|
524980
|
+
try {
|
|
524981
|
+
const inferenceUrl = (options2.inferenceUrl ?? process.env["OMNIUS_OLLAMA_CLEANUP_INFERENCE_URL"] ?? "http://127.0.0.1:11435").replace(/\/+$/, "");
|
|
524982
|
+
await system.fetchJson(`${inferenceUrl}/health`, 1500);
|
|
524983
|
+
const body = {
|
|
524984
|
+
model: options2.inferenceModel ?? process.env["OMNIUS_OLLAMA_CLEANUP_MODEL"] ?? process.env["OMNIUS_MODEL"] ?? "qwen3.5:4b",
|
|
524985
|
+
stream: false,
|
|
524986
|
+
messages: [
|
|
524987
|
+
{
|
|
524988
|
+
role: "system",
|
|
524989
|
+
content: [
|
|
524990
|
+
"You classify stale Ollama pool processes.",
|
|
524991
|
+
'Return only compact JSON: {"decisions":[{"pid":123,"action":"keep|terminate","reason":"..."}]}',
|
|
524992
|
+
"Never terminate port 11434, the configured base port, systemd ollama.service, or a tracked active pool instance.",
|
|
524993
|
+
"Only choose terminate for processes already marked deterministic action terminate."
|
|
524994
|
+
].join(" ")
|
|
524995
|
+
},
|
|
524996
|
+
{
|
|
524997
|
+
role: "user",
|
|
524998
|
+
content: JSON.stringify({
|
|
524999
|
+
protectedPorts: scan.protectedPorts,
|
|
525000
|
+
baseInstanceUrl: scan.baseInstanceUrl,
|
|
525001
|
+
processes: scan.processes.map((p2) => ({
|
|
525002
|
+
pid: p2.pid,
|
|
525003
|
+
ports: p2.ports,
|
|
525004
|
+
ollamaApiPorts: p2.ollamaApiPorts,
|
|
525005
|
+
cpuPct: p2.cpuPct,
|
|
525006
|
+
elapsedMs: p2.elapsedMs,
|
|
525007
|
+
gpuMemoryMb: p2.gpuMemoryMb,
|
|
525008
|
+
command: p2.command,
|
|
525009
|
+
deterministic: scan.decisions.find((d2) => d2.pid === p2.pid)
|
|
525010
|
+
}))
|
|
525011
|
+
})
|
|
525012
|
+
}
|
|
525013
|
+
],
|
|
525014
|
+
temperature: 0
|
|
525015
|
+
};
|
|
525016
|
+
const resp = await system.fetchJson(`${inferenceUrl}/v1/chat/completions`, 15e3, body);
|
|
525017
|
+
const text = extractInferenceText(resp);
|
|
525018
|
+
const parsed = parseJsonObject(text);
|
|
525019
|
+
if (!Array.isArray(parsed.decisions))
|
|
525020
|
+
throw new Error("missing decisions array");
|
|
525021
|
+
const byPid = new Map(parsed.decisions.map((d2) => [Number(d2.pid), d2]));
|
|
525022
|
+
const decisions = scan.decisions.map((det) => {
|
|
525023
|
+
const inf = byPid.get(det.pid);
|
|
525024
|
+
if (!inf)
|
|
525025
|
+
return { ...det, source: "inference-fallback", reasons: [...det.reasons, "inference omitted PID"] };
|
|
525026
|
+
const requestedAction = inf.action === "terminate" ? "terminate" : "keep";
|
|
525027
|
+
if (requestedAction === "terminate" && det.action !== "terminate") {
|
|
525028
|
+
return {
|
|
525029
|
+
...det,
|
|
525030
|
+
action: "keep",
|
|
525031
|
+
source: "inference-fallback",
|
|
525032
|
+
reasons: [...det.reasons, "inference requested termination but hard rules rejected it"]
|
|
525033
|
+
};
|
|
525034
|
+
}
|
|
525035
|
+
return {
|
|
525036
|
+
...det,
|
|
525037
|
+
action: requestedAction,
|
|
525038
|
+
source: "inference",
|
|
525039
|
+
reasons: [...det.reasons, `inference: ${String(inf.reason ?? requestedAction).slice(0, 200)}`]
|
|
525040
|
+
};
|
|
525041
|
+
});
|
|
525042
|
+
return { decisions, usedInference: true, fallbackReason: null };
|
|
525043
|
+
} catch (err) {
|
|
525044
|
+
return {
|
|
525045
|
+
decisions: scan.decisions.map((d2) => ({ ...d2, source: "inference-fallback" })),
|
|
525046
|
+
usedInference: false,
|
|
525047
|
+
fallbackReason: err instanceof Error ? err.message : String(err)
|
|
525048
|
+
};
|
|
525049
|
+
}
|
|
525050
|
+
}
|
|
525051
|
+
return { decisions: scan.decisions, usedInference: false, fallbackReason: null };
|
|
525052
|
+
}
|
|
525053
|
+
function makeSystem(overrides) {
|
|
525054
|
+
const base3 = {
|
|
525055
|
+
runCommand: (command, args, timeoutMs) => new Promise((resolve52, reject) => {
|
|
525056
|
+
execFile5(command, args, { encoding: "utf8", timeout: timeoutMs }, (err, stdout) => {
|
|
525057
|
+
if (err)
|
|
525058
|
+
reject(err);
|
|
525059
|
+
else
|
|
525060
|
+
resolve52(stdout);
|
|
525061
|
+
});
|
|
525062
|
+
}),
|
|
525063
|
+
readFile: async (path12) => fsReadFile(path12, "utf8"),
|
|
525064
|
+
readDir: async (path12) => readdir6(path12),
|
|
525065
|
+
readLink: async (path12) => readlink(path12),
|
|
525066
|
+
fetchJson: async (url, timeoutMs, body) => {
|
|
525067
|
+
const resp = await fetch(url, {
|
|
525068
|
+
method: body === void 0 ? "GET" : "POST",
|
|
525069
|
+
headers: body === void 0 ? void 0 : { "content-type": "application/json" },
|
|
525070
|
+
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
525071
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
525072
|
+
});
|
|
525073
|
+
if (!resp.ok)
|
|
525074
|
+
throw new Error(`HTTP ${resp.status} from ${url}`);
|
|
525075
|
+
return resp.json();
|
|
525076
|
+
},
|
|
525077
|
+
kill: (pid, signal) => process.kill(pid, signal),
|
|
525078
|
+
isPidAlive: (pid) => {
|
|
525079
|
+
try {
|
|
525080
|
+
process.kill(pid, 0);
|
|
525081
|
+
return true;
|
|
525082
|
+
} catch {
|
|
525083
|
+
return false;
|
|
525084
|
+
}
|
|
525085
|
+
},
|
|
525086
|
+
sleep: (ms) => new Promise((resolve52) => setTimeout(resolve52, ms)),
|
|
525087
|
+
now: () => Date.now()
|
|
525088
|
+
};
|
|
525089
|
+
return { ...base3, ...overrides ?? {} };
|
|
525090
|
+
}
|
|
525091
|
+
async function readPsRows(system) {
|
|
525092
|
+
try {
|
|
525093
|
+
const out = await system.runCommand("ps", ["-eo", "pid=,ppid=,pcpu=,pmem=,etimes=,args="], 5e3);
|
|
525094
|
+
return out.split(/\r?\n/).map(parsePsRow).filter((r2) => r2 !== null);
|
|
525095
|
+
} catch {
|
|
525096
|
+
return [];
|
|
525097
|
+
}
|
|
525098
|
+
}
|
|
525099
|
+
function parsePsRow(line) {
|
|
525100
|
+
const trimmed = line.trim();
|
|
525101
|
+
if (!trimmed)
|
|
525102
|
+
return null;
|
|
525103
|
+
const parts = trimmed.split(/\s+/, 6);
|
|
525104
|
+
if (parts.length < 6)
|
|
525105
|
+
return null;
|
|
525106
|
+
const pid = Number(parts[0]);
|
|
525107
|
+
if (!Number.isFinite(pid))
|
|
525108
|
+
return null;
|
|
525109
|
+
const ppid = Number(parts[1]);
|
|
525110
|
+
const cpuPct = nullableNumber(parts[2]);
|
|
525111
|
+
const memPct = nullableNumber(parts[3]);
|
|
525112
|
+
const elapsedSec = nullableNumber(parts[4]);
|
|
525113
|
+
const commandStart = nthWhitespaceIndex(trimmed, 5);
|
|
525114
|
+
const command = commandStart >= 0 ? trimmed.slice(commandStart).trim() : parts[5] ?? "";
|
|
525115
|
+
return {
|
|
525116
|
+
pid,
|
|
525117
|
+
ppid: Number.isFinite(ppid) ? ppid : null,
|
|
525118
|
+
cpuPct,
|
|
525119
|
+
memPct,
|
|
525120
|
+
elapsedMs: elapsedSec === null ? null : elapsedSec * 1e3,
|
|
525121
|
+
command
|
|
525122
|
+
};
|
|
525123
|
+
}
|
|
525124
|
+
async function readListeningPortMap(system) {
|
|
525125
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
525126
|
+
await readSsPorts(system, map2);
|
|
525127
|
+
await readLsofPorts(system, map2);
|
|
525128
|
+
await readProcNetPorts(system, map2);
|
|
525129
|
+
return map2;
|
|
525130
|
+
}
|
|
525131
|
+
async function readSsPorts(system, map2) {
|
|
525132
|
+
try {
|
|
525133
|
+
const out = await system.runCommand("ss", ["-ltnpH"], 5e3);
|
|
525134
|
+
for (const line of out.split(/\r?\n/)) {
|
|
525135
|
+
const pidMatch = line.match(/pid=(\d+)/);
|
|
525136
|
+
if (!pidMatch?.[1])
|
|
525137
|
+
continue;
|
|
525138
|
+
const parts = line.trim().split(/\s+/);
|
|
525139
|
+
const local = parts[3] ?? parts[2] ?? "";
|
|
525140
|
+
const port = parseEndpointPort(local);
|
|
525141
|
+
if (port === null)
|
|
525142
|
+
continue;
|
|
525143
|
+
addPort(map2, Number(pidMatch[1]), port);
|
|
525144
|
+
}
|
|
525145
|
+
} catch {
|
|
525146
|
+
}
|
|
525147
|
+
}
|
|
525148
|
+
async function readLsofPorts(system, map2) {
|
|
525149
|
+
try {
|
|
525150
|
+
const out = await system.runCommand("lsof", ["-nP", "-iTCP", "-sTCP:LISTEN"], 5e3);
|
|
525151
|
+
for (const line of out.split(/\r?\n/).slice(1)) {
|
|
525152
|
+
const parts = line.trim().split(/\s+/);
|
|
525153
|
+
const pid = Number(parts[1]);
|
|
525154
|
+
const name10 = parts[8] ?? "";
|
|
525155
|
+
const port = parseEndpointPort(name10);
|
|
525156
|
+
if (Number.isFinite(pid) && port !== null)
|
|
525157
|
+
addPort(map2, pid, port);
|
|
525158
|
+
}
|
|
525159
|
+
} catch {
|
|
525160
|
+
}
|
|
525161
|
+
}
|
|
525162
|
+
async function readProcNetPorts(system, map2) {
|
|
525163
|
+
if (process.platform !== "linux")
|
|
525164
|
+
return;
|
|
525165
|
+
try {
|
|
525166
|
+
const inodeToPort = /* @__PURE__ */ new Map();
|
|
525167
|
+
for (const file of ["/proc/net/tcp", "/proc/net/tcp6"]) {
|
|
525168
|
+
try {
|
|
525169
|
+
const text = await system.readFile(file);
|
|
525170
|
+
for (const line of text.split(/\r?\n/).slice(1)) {
|
|
525171
|
+
const parts = line.trim().split(/\s+/);
|
|
525172
|
+
if (parts.length < 10 || parts[3] !== "0A")
|
|
525173
|
+
continue;
|
|
525174
|
+
const local = parts[1] ?? "";
|
|
525175
|
+
const inode = parts[9] ?? "";
|
|
525176
|
+
const port = parseProcNetPort(local);
|
|
525177
|
+
if (port !== null && inode)
|
|
525178
|
+
inodeToPort.set(inode, port);
|
|
525179
|
+
}
|
|
525180
|
+
} catch {
|
|
525181
|
+
}
|
|
525182
|
+
}
|
|
525183
|
+
if (inodeToPort.size === 0)
|
|
525184
|
+
return;
|
|
525185
|
+
const procEntries = await system.readDir("/proc");
|
|
525186
|
+
await Promise.all(procEntries.filter((name10) => /^\d+$/.test(name10)).map(async (pidText) => {
|
|
525187
|
+
const pid = Number(pidText);
|
|
525188
|
+
try {
|
|
525189
|
+
const fdDir = `/proc/${pid}/fd`;
|
|
525190
|
+
const fds = await system.readDir(fdDir);
|
|
525191
|
+
for (const fd of fds) {
|
|
525192
|
+
try {
|
|
525193
|
+
const target = await system.readLink(`${fdDir}/${fd}`);
|
|
525194
|
+
const m2 = target.match(/^socket:\[(\d+)\]$/);
|
|
525195
|
+
const port = m2?.[1] ? inodeToPort.get(m2[1]) : void 0;
|
|
525196
|
+
if (port !== void 0)
|
|
525197
|
+
addPort(map2, pid, port);
|
|
525198
|
+
} catch {
|
|
525199
|
+
}
|
|
525200
|
+
}
|
|
525201
|
+
} catch {
|
|
525202
|
+
}
|
|
525203
|
+
}));
|
|
525204
|
+
} catch {
|
|
525205
|
+
}
|
|
525206
|
+
}
|
|
525207
|
+
async function readSystemdOllamaMainPid(system) {
|
|
525208
|
+
try {
|
|
525209
|
+
const out = await system.runCommand("systemctl", ["show", "ollama.service", "-p", "MainPID", "--value"], 3e3);
|
|
525210
|
+
const pid = Number(out.trim());
|
|
525211
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
525212
|
+
} catch {
|
|
525213
|
+
return null;
|
|
525214
|
+
}
|
|
525215
|
+
}
|
|
525216
|
+
async function readGpuMemoryByPid(system) {
|
|
525217
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
525218
|
+
try {
|
|
525219
|
+
const out = await system.runCommand("nvidia-smi", ["--query-compute-apps=pid,used_memory", "--format=csv,noheader,nounits"], 3e3);
|
|
525220
|
+
for (const line of out.split(/\r?\n/)) {
|
|
525221
|
+
const [pidText, memText] = line.split(",").map((s2) => s2?.trim());
|
|
525222
|
+
const pid = Number(pidText);
|
|
525223
|
+
const mem = Number(memText);
|
|
525224
|
+
if (Number.isFinite(pid) && Number.isFinite(mem))
|
|
525225
|
+
map2.set(pid, mem);
|
|
525226
|
+
}
|
|
525227
|
+
} catch {
|
|
525228
|
+
}
|
|
525229
|
+
return map2;
|
|
525230
|
+
}
|
|
525231
|
+
async function readProcEnv(system, pid) {
|
|
525232
|
+
try {
|
|
525233
|
+
const raw = await system.readFile(`/proc/${pid}/environ`);
|
|
525234
|
+
const values = {};
|
|
525235
|
+
for (const entry of raw.split("\0")) {
|
|
525236
|
+
const idx = entry.indexOf("=");
|
|
525237
|
+
if (idx <= 0)
|
|
525238
|
+
continue;
|
|
525239
|
+
const key = entry.slice(0, idx);
|
|
525240
|
+
if (!["OLLAMA_HOST", "OLLAMA_MODELS", "OLLAMA_NUM_PARALLEL", "CUDA_VISIBLE_DEVICES", "GPU_DEVICE_ORDINAL"].includes(key))
|
|
525241
|
+
continue;
|
|
525242
|
+
values[key] = entry.slice(idx + 1);
|
|
525243
|
+
}
|
|
525244
|
+
return { readable: true, values };
|
|
525245
|
+
} catch {
|
|
525246
|
+
return { readable: false, values: {} };
|
|
525247
|
+
}
|
|
525248
|
+
}
|
|
525249
|
+
async function probeOllamaPorts(system, ports) {
|
|
525250
|
+
const ok2 = [];
|
|
525251
|
+
await Promise.all(ports.map(async (port) => {
|
|
525252
|
+
try {
|
|
525253
|
+
const json = await system.fetchJson(`http://127.0.0.1:${port}/api/version`, 1e3);
|
|
525254
|
+
if (json && typeof json === "object" && "version" in json)
|
|
525255
|
+
ok2.push(port);
|
|
525256
|
+
} catch {
|
|
525257
|
+
}
|
|
525258
|
+
}));
|
|
525259
|
+
return ok2.sort((a2, b) => a2 - b);
|
|
525260
|
+
}
|
|
525261
|
+
async function portsClosed(system, ports) {
|
|
525262
|
+
for (const port of ports) {
|
|
525263
|
+
try {
|
|
525264
|
+
await system.fetchJson(`http://127.0.0.1:${port}/api/version`, 750);
|
|
525265
|
+
return false;
|
|
525266
|
+
} catch {
|
|
525267
|
+
}
|
|
525268
|
+
}
|
|
525269
|
+
return true;
|
|
525270
|
+
}
|
|
525271
|
+
function activePoolRefs(poolStatus) {
|
|
525272
|
+
const pids = /* @__PURE__ */ new Set();
|
|
525273
|
+
const ports = /* @__PURE__ */ new Set();
|
|
525274
|
+
for (const inst of poolStatus?.instances ?? []) {
|
|
525275
|
+
if (inst.poolOwned && inst.pid !== null)
|
|
525276
|
+
pids.add(inst.pid);
|
|
525277
|
+
const port = portFromUrl(inst.baseUrl);
|
|
525278
|
+
if (inst.poolOwned && port !== null)
|
|
525279
|
+
ports.add(port);
|
|
525280
|
+
}
|
|
525281
|
+
return { pids, ports };
|
|
525282
|
+
}
|
|
525283
|
+
function isOllamaServeCommand(command) {
|
|
525284
|
+
const [exe, subcommand] = command.trim().split(/\s+/);
|
|
525285
|
+
return basename16(exe ?? "") === "ollama" && subcommand === "serve";
|
|
525286
|
+
}
|
|
525287
|
+
function portsFromEnv(env2) {
|
|
525288
|
+
const host = env2["OLLAMA_HOST"];
|
|
525289
|
+
if (!host)
|
|
525290
|
+
return [];
|
|
525291
|
+
const port = portFromUrl(host.includes("://") ? host : `http://${host}`);
|
|
525292
|
+
return port === null ? [] : [port];
|
|
525293
|
+
}
|
|
525294
|
+
function addPort(map2, pid, port) {
|
|
525295
|
+
if (!Number.isFinite(pid) || !Number.isFinite(port))
|
|
525296
|
+
return;
|
|
525297
|
+
const list = map2.get(pid) ?? [];
|
|
525298
|
+
if (!list.includes(port))
|
|
525299
|
+
list.push(port);
|
|
525300
|
+
list.sort((a2, b) => a2 - b);
|
|
525301
|
+
map2.set(pid, list);
|
|
525302
|
+
}
|
|
525303
|
+
function portFromUrl(value2) {
|
|
525304
|
+
try {
|
|
525305
|
+
const normalized = /^[^:/]+:\d+$/.test(value2) ? `http://${value2}` : value2;
|
|
525306
|
+
const url = new URL(normalized);
|
|
525307
|
+
const port = url.port ? Number(url.port) : url.protocol === "https:" ? 443 : 80;
|
|
525308
|
+
return Number.isFinite(port) ? port : null;
|
|
525309
|
+
} catch {
|
|
525310
|
+
const match = value2.match(/:(\d+)(?:\/|$)/);
|
|
525311
|
+
return match?.[1] ? Number(match[1]) : null;
|
|
525312
|
+
}
|
|
525313
|
+
}
|
|
525314
|
+
function parseEndpointPort(endpoint) {
|
|
525315
|
+
const cleaned = endpoint.replace(/^\[/, "").replace(/\]$/, "");
|
|
525316
|
+
const colon = cleaned.match(/:(\d+)(?:\s|$|\)|->)?/);
|
|
525317
|
+
if (colon?.[1])
|
|
525318
|
+
return Number(colon[1]);
|
|
525319
|
+
const dot = cleaned.match(/\.(\d+)$/);
|
|
525320
|
+
return dot?.[1] ? Number(dot[1]) : null;
|
|
525321
|
+
}
|
|
525322
|
+
function parseProcNetPort(localAddress) {
|
|
525323
|
+
const parts = localAddress.split(":");
|
|
525324
|
+
const hex = parts[1];
|
|
525325
|
+
if (!hex)
|
|
525326
|
+
return null;
|
|
525327
|
+
const port = Number.parseInt(hex, 16);
|
|
525328
|
+
return Number.isFinite(port) ? port : null;
|
|
525329
|
+
}
|
|
525330
|
+
function nullableNumber(value2) {
|
|
525331
|
+
const n2 = Number(value2);
|
|
525332
|
+
return Number.isFinite(n2) ? n2 : null;
|
|
525333
|
+
}
|
|
525334
|
+
function nthWhitespaceIndex(value2, count) {
|
|
525335
|
+
let seen = 0;
|
|
525336
|
+
for (let i2 = 0; i2 < value2.length; i2++) {
|
|
525337
|
+
if (/\s/.test(value2[i2])) {
|
|
525338
|
+
while (i2 < value2.length && /\s/.test(value2[i2]))
|
|
525339
|
+
i2++;
|
|
525340
|
+
seen++;
|
|
525341
|
+
if (seen === count)
|
|
525342
|
+
return i2;
|
|
525343
|
+
}
|
|
525344
|
+
}
|
|
525345
|
+
return -1;
|
|
525346
|
+
}
|
|
525347
|
+
function uniqueNumbers(values) {
|
|
525348
|
+
return [...new Set(values.filter((v) => Number.isFinite(v)))].sort((a2, b) => a2 - b);
|
|
525349
|
+
}
|
|
525350
|
+
function extractInferenceText(resp) {
|
|
525351
|
+
const obj = resp;
|
|
525352
|
+
return String(obj?.choices?.[0]?.message?.content ?? obj?.message?.content ?? obj?.response ?? obj?.content ?? "");
|
|
525353
|
+
}
|
|
525354
|
+
function parseJsonObject(text) {
|
|
525355
|
+
const trimmed = text.trim();
|
|
525356
|
+
if (trimmed.startsWith("{"))
|
|
525357
|
+
return JSON.parse(trimmed);
|
|
525358
|
+
const match = trimmed.match(/\{[\s\S]*\}/);
|
|
525359
|
+
if (!match)
|
|
525360
|
+
throw new Error("model response did not contain JSON");
|
|
525361
|
+
return JSON.parse(match[0]);
|
|
525362
|
+
}
|
|
525363
|
+
var DEFAULT_BASE_PORT, DEFAULT_POOL_PORT_START, DEFAULT_MIN_AGE_MS, DEFAULT_CPU_THRESHOLD_PCT, DEFAULT_GRACE_MS, PROVENANCE_AGENT;
|
|
525364
|
+
var init_ollama_pool_cleanup = __esm({
|
|
525365
|
+
"packages/orchestrator/dist/ollama-pool-cleanup.js"() {
|
|
525366
|
+
"use strict";
|
|
525367
|
+
init_ollama_pool();
|
|
525368
|
+
DEFAULT_BASE_PORT = 11434;
|
|
525369
|
+
DEFAULT_POOL_PORT_START = 11435;
|
|
525370
|
+
DEFAULT_MIN_AGE_MS = 10 * 60 * 1e3;
|
|
525371
|
+
DEFAULT_CPU_THRESHOLD_PCT = 1;
|
|
525372
|
+
DEFAULT_GRACE_MS = 2e3;
|
|
525373
|
+
PROVENANCE_AGENT = "orchestrator.ollama-pool-cleanup";
|
|
525374
|
+
}
|
|
525375
|
+
});
|
|
525376
|
+
|
|
524763
525377
|
// packages/orchestrator/dist/ollama-pool.js
|
|
524764
525378
|
import { spawn as spawn21, exec } from "node:child_process";
|
|
524765
525379
|
import { existsSync as existsSync60, readFileSync as readFileSync47, readdirSync as readdirSync20, statfsSync as statfsSync3, statSync as statSync22 } from "node:fs";
|
|
@@ -525213,6 +525827,7 @@ var init_ollama_pool = __esm({
|
|
|
525213
525827
|
spawnedAtMs: Date.now()
|
|
525214
525828
|
}, null));
|
|
525215
525829
|
this.startReaper();
|
|
525830
|
+
this.scheduleStartupCleanupScan();
|
|
525216
525831
|
}
|
|
525217
525832
|
/**
|
|
525218
525833
|
* Resolve the effective agent id for an acquire request. Explicit option
|
|
@@ -525625,6 +526240,40 @@ var init_ollama_pool = __esm({
|
|
|
525625
526240
|
await inst.terminate();
|
|
525626
526241
|
return true;
|
|
525627
526242
|
}
|
|
526243
|
+
scheduleStartupCleanupScan() {
|
|
526244
|
+
if (process.env["NODE_ENV"] === "test" || process.env["VITEST"])
|
|
526245
|
+
return;
|
|
526246
|
+
if (process.env["OMNIUS_OLLAMA_CLEANUP_STARTUP_SCAN"] === "0")
|
|
526247
|
+
return;
|
|
526248
|
+
const handle2 = setTimeout(async () => {
|
|
526249
|
+
try {
|
|
526250
|
+
const cleanupOnStart = process.env["OMNIUS_OLLAMA_CLEANUP_ON_START"] === "1";
|
|
526251
|
+
const { cleanupStaleOllamaProcesses: cleanupStaleOllamaProcesses2 } = await Promise.resolve().then(() => (init_ollama_pool_cleanup(), ollama_pool_cleanup_exports));
|
|
526252
|
+
const report2 = await cleanupStaleOllamaProcesses2({
|
|
526253
|
+
dryRun: !cleanupOnStart,
|
|
526254
|
+
useInference: cleanupOnStart ? "auto" : false,
|
|
526255
|
+
baseInstanceUrl: this.config.baseInstanceUrl,
|
|
526256
|
+
poolPortStart: this.config.spawnPortStart,
|
|
526257
|
+
poolStatus: await this.status()
|
|
526258
|
+
});
|
|
526259
|
+
const stale = report2.decisions.filter((d2) => d2.action === "terminate");
|
|
526260
|
+
if (stale.length > 0) {
|
|
526261
|
+
this.emit(cleanupOnStart ? "stale-process-cleanup" : "stale-processes-found", {
|
|
526262
|
+
staleCount: stale.length,
|
|
526263
|
+
dryRun: report2.dryRun,
|
|
526264
|
+
terminated: report2.terminated,
|
|
526265
|
+
skipped: report2.skipped,
|
|
526266
|
+
errors: report2.errors,
|
|
526267
|
+
provenance: report2.provenance
|
|
526268
|
+
});
|
|
526269
|
+
}
|
|
526270
|
+
} catch (error) {
|
|
526271
|
+
this.emit("stale-process-scan-failed", { error });
|
|
526272
|
+
}
|
|
526273
|
+
}, 250);
|
|
526274
|
+
if (typeof handle2.unref === "function")
|
|
526275
|
+
handle2.unref();
|
|
526276
|
+
}
|
|
525628
526277
|
portFromUrl(url) {
|
|
525629
526278
|
const m2 = url.match(/:(\d+)(?:\/|$)/);
|
|
525630
526279
|
if (m2?.[1])
|
|
@@ -526323,7 +526972,7 @@ var init_intervention_replay = __esm({
|
|
|
526323
526972
|
|
|
526324
526973
|
// packages/orchestrator/dist/world-state-disk-scan.js
|
|
526325
526974
|
import { existsSync as existsSync64, readFileSync as readFileSync50, readdirSync as readdirSync22, statSync as statSync24 } from "node:fs";
|
|
526326
|
-
import { join as join77, relative as relative7, basename as
|
|
526975
|
+
import { join as join77, relative as relative7, basename as basename17 } from "node:path";
|
|
526327
526976
|
function loadIgnoreFile(path12) {
|
|
526328
526977
|
if (!existsSync64(path12))
|
|
526329
526978
|
return [];
|
|
@@ -526403,7 +527052,7 @@ function scanWorkspace(opts) {
|
|
|
526403
527052
|
}
|
|
526404
527053
|
const abs = join77(dir, entry);
|
|
526405
527054
|
const rel = relative7(root, abs);
|
|
526406
|
-
const base3 =
|
|
527055
|
+
const base3 = basename17(abs);
|
|
526407
527056
|
if (shouldIgnore(rel, base3, patterns))
|
|
526408
527057
|
continue;
|
|
526409
527058
|
let st;
|
|
@@ -537418,8 +538067,8 @@ function createAppState(opts) {
|
|
|
537418
538067
|
expandedView: false
|
|
537419
538068
|
};
|
|
537420
538069
|
}
|
|
537421
|
-
function recordToolDecision(state,
|
|
537422
|
-
state.toolDecisions.push({ ...
|
|
538070
|
+
function recordToolDecision(state, decision2) {
|
|
538071
|
+
state.toolDecisions.push({ ...decision2, timestamp: Date.now() });
|
|
537423
538072
|
if (state.toolDecisions.length > state.toolDecisionMaxHistory) {
|
|
537424
538073
|
state.toolDecisions.splice(0, state.toolDecisions.length - state.toolDecisionMaxHistory);
|
|
537425
538074
|
}
|
|
@@ -556083,8 +556732,10 @@ __export(dist_exports3, {
|
|
|
556083
556732
|
checkMilestoneComplete: () => checkMilestoneComplete,
|
|
556084
556733
|
claimAssertion: () => claimAssertion,
|
|
556085
556734
|
classifyHandoff: () => classifyHandoff,
|
|
556735
|
+
classifyOllamaProcesses: () => classifyOllamaProcesses,
|
|
556086
556736
|
cleanForStorage: () => cleanForStorage,
|
|
556087
556737
|
cleanScaffolding: () => cleanScaffolding,
|
|
556738
|
+
cleanupStaleOllamaProcesses: () => cleanupStaleOllamaProcesses,
|
|
556088
556739
|
clearTurnState: () => clearTurnState,
|
|
556089
556740
|
combineValidatorResults: () => combineValidatorResults,
|
|
556090
556741
|
compilePersonalityPrompt: () => compilePersonalityPrompt,
|
|
@@ -556162,6 +556813,7 @@ __export(dist_exports3, {
|
|
|
556162
556813
|
resolveDefaultPoolConfig: () => resolveDefaultPoolConfig,
|
|
556163
556814
|
resolveModelProfile: () => resolveModelProfile,
|
|
556164
556815
|
restoreAgentTasks: () => restoreAgentTasks,
|
|
556816
|
+
scanOllamaProcesses: () => scanOllamaProcesses,
|
|
556165
556817
|
scoreHandoff: () => scoreHandoff,
|
|
556166
556818
|
sealMilestone: () => sealMilestone,
|
|
556167
556819
|
sealMilestoneState: () => sealMilestoneState,
|
|
@@ -556196,6 +556848,7 @@ var init_dist8 = __esm({
|
|
|
556196
556848
|
init_retryController();
|
|
556197
556849
|
init_agenticRunner();
|
|
556198
556850
|
init_ollama_pool();
|
|
556851
|
+
init_ollama_pool_cleanup();
|
|
556199
556852
|
init_modelProfile();
|
|
556200
556853
|
init_pressure_gate();
|
|
556201
556854
|
init_constraint_learner();
|
|
@@ -557336,10 +557989,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
557336
557989
|
wordTimestamps: false
|
|
557337
557990
|
});
|
|
557338
557991
|
if (outputDir) {
|
|
557339
|
-
const { basename:
|
|
557992
|
+
const { basename: basename31 } = await import("node:path");
|
|
557340
557993
|
const transcriptDir = join97(outputDir, ".omnius", "transcripts");
|
|
557341
557994
|
mkdirSync45(transcriptDir, { recursive: true });
|
|
557342
|
-
const outFile = join97(transcriptDir, `${
|
|
557995
|
+
const outFile = join97(transcriptDir, `${basename31(filePath)}.txt`);
|
|
557343
557996
|
writeFileSync40(outFile, result.text, "utf-8");
|
|
557344
557997
|
}
|
|
557345
557998
|
return {
|
|
@@ -557355,10 +558008,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
557355
558008
|
const fb = await transcribeFileViaWhisper(filePath, this.config.model);
|
|
557356
558009
|
if (fb) {
|
|
557357
558010
|
if (outputDir) {
|
|
557358
|
-
const { basename:
|
|
558011
|
+
const { basename: basename31 } = await import("node:path");
|
|
557359
558012
|
const transcriptDir = join97(outputDir, ".omnius", "transcripts");
|
|
557360
558013
|
mkdirSync45(transcriptDir, { recursive: true });
|
|
557361
|
-
const outFile = join97(transcriptDir, `${
|
|
558014
|
+
const outFile = join97(transcriptDir, `${basename31(filePath)}.txt`);
|
|
557362
558015
|
writeFileSync40(outFile, fb.text, "utf-8");
|
|
557363
558016
|
}
|
|
557364
558017
|
return fb;
|
|
@@ -561531,6 +562184,8 @@ var init_command_registry = __esm({
|
|
|
561531
562184
|
["/wizard", "Alias for /setup"],
|
|
561532
562185
|
["/parallel", "Show current Ollama parallel inference slots"],
|
|
561533
562186
|
["/parallel <1-15>", "Set parallel slots (restarts Ollama, max 15)"],
|
|
562187
|
+
["/ollama cleanup", "Dry-run stale Ollama pool process cleanup"],
|
|
562188
|
+
["/ollama cleanup --execute", "Terminate guarded stale Ollama pool runners"],
|
|
561534
562189
|
["/mcp", "Show MCP server/tool status and controls"],
|
|
561535
562190
|
["/mcp reload", "Reload MCP servers and tools"],
|
|
561536
562191
|
["/update", "Check for updates and auto-install"],
|
|
@@ -561999,7 +562654,7 @@ var init_command_registry = __esm({
|
|
|
561999
562654
|
"deny",
|
|
562000
562655
|
"sethome"
|
|
562001
562656
|
]);
|
|
562002
|
-
DESTRUCTIVE = /* @__PURE__ */ new Set(["destroy", "stop", "rollback", "update", "upgrade", "deny", "daemon"]);
|
|
562657
|
+
DESTRUCTIVE = /* @__PURE__ */ new Set(["destroy", "stop", "rollback", "update", "upgrade", "deny", "daemon", "ollama"]);
|
|
562003
562658
|
NETWORKED = /* @__PURE__ */ new Set([
|
|
562004
562659
|
"endpoint",
|
|
562005
562660
|
"update",
|
|
@@ -562458,6 +563113,7 @@ var init_text_selection = __esm({
|
|
|
562458
563113
|
// packages/cli/src/tui/task-complete-box.ts
|
|
562459
563114
|
var task_complete_box_exports = {};
|
|
562460
563115
|
__export(task_complete_box_exports, {
|
|
563116
|
+
TASK_COMPLETE_GREEN_256: () => TASK_COMPLETE_GREEN_256,
|
|
562461
563117
|
buildBoxLines: () => buildBoxLines,
|
|
562462
563118
|
buildSessionHistoryBoxLines: () => buildSessionHistoryBoxLines,
|
|
562463
563119
|
deriveTitle: () => deriveTitle,
|
|
@@ -562468,7 +563124,8 @@ __export(task_complete_box_exports, {
|
|
|
562468
563124
|
});
|
|
562469
563125
|
function deriveTitle(task) {
|
|
562470
563126
|
if (!task || !task.trim()) return "Task Complete";
|
|
562471
|
-
const
|
|
563127
|
+
const source = task.replace(/^[\s\S]*?\n---\s*\n\s*NEW TASK:\s*/i, "").replace(/^NEW TASK:\s*/i, "").replace(/<task-handoff>[\s\S]*?<\/task-handoff>/gi, " ").replace(/<session-recap>[\s\S]*?<\/session-recap>/gi, " ").replace(/^\[task_(?:boundary|summary)\][\s\S]*?(?=\n\n|$)/gim, " ");
|
|
563128
|
+
const cleaned = source.replace(/```[\s\S]*?```/g, " ").replace(/`[^`]+`/g, " ").replace(/^#{1,6}\s*Previous Task:.*$/gim, " ").replace(/^Prior (?:goal|task):.*$/gim, " ").replace(/\([^)]*\)/g, " ").replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
562472
563129
|
if (!cleaned) return "Task Complete";
|
|
562473
563130
|
const firstSentence = cleaned.split(/(?<=[.!?:])\s/)[0] ?? cleaned;
|
|
562474
563131
|
const words = firstSentence.split(/\s+/).filter((w) => w.length > 0);
|
|
@@ -562805,7 +563462,7 @@ function detectProvenanceAnchors(toolOutputs) {
|
|
|
562805
563462
|
}
|
|
562806
563463
|
return [...out].slice(0, 16);
|
|
562807
563464
|
}
|
|
562808
|
-
var BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, BOX_TJ_L, BOX_TJ_R, RESET, GREEN, FG_BORDER, FG_TITLE, FG_METRIC, FG_LABEL;
|
|
563465
|
+
var BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, BOX_TJ_L, BOX_TJ_R, RESET, TASK_COMPLETE_GREEN_256, GREEN, FG_BORDER, FG_TITLE, FG_METRIC, FG_LABEL;
|
|
562809
563466
|
var init_task_complete_box = __esm({
|
|
562810
563467
|
"packages/cli/src/tui/task-complete-box.ts"() {
|
|
562811
563468
|
"use strict";
|
|
@@ -562819,9 +563476,10 @@ var init_task_complete_box = __esm({
|
|
|
562819
563476
|
BOX_TJ_L = "├";
|
|
562820
563477
|
BOX_TJ_R = "┤";
|
|
562821
563478
|
RESET = "\x1B[0m";
|
|
562822
|
-
|
|
562823
|
-
|
|
562824
|
-
|
|
563479
|
+
TASK_COMPLETE_GREEN_256 = 154;
|
|
563480
|
+
GREEN = `\x1B[38;5;${TASK_COMPLETE_GREEN_256}m`;
|
|
563481
|
+
FG_BORDER = `\x1B[38;5;${TASK_COMPLETE_GREEN_256}m`;
|
|
563482
|
+
FG_TITLE = `\x1B[1;38;5;${TASK_COMPLETE_GREEN_256}m`;
|
|
562825
563483
|
FG_METRIC = "\x1B[38;5;222m";
|
|
562826
563484
|
FG_LABEL = "\x1B[38;5;147m";
|
|
562827
563485
|
}
|
|
@@ -569232,7 +569890,7 @@ __export(omnius_directory_exports, {
|
|
|
569232
569890
|
writeTaskHandoff: () => writeTaskHandoff2
|
|
569233
569891
|
});
|
|
569234
569892
|
import { appendFileSync as appendFileSync5, cpSync as cpSync2, existsSync as existsSync88, mkdirSync as mkdirSync50, readFileSync as readFileSync70, writeFileSync as writeFileSync45, readdirSync as readdirSync29, statSync as statSync32, unlinkSync as unlinkSync15, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync4 } from "node:fs";
|
|
569235
|
-
import { join as join104, relative as relative9, basename as
|
|
569893
|
+
import { join as join104, relative as relative9, basename as basename18, dirname as dirname29 } from "node:path";
|
|
569236
569894
|
import { homedir as homedir31 } from "node:os";
|
|
569237
569895
|
import { createHash as createHash20 } from "node:crypto";
|
|
569238
569896
|
function findGitRoot(startDir) {
|
|
@@ -569428,7 +570086,7 @@ function writeIndexData(repoRoot, filename, data) {
|
|
|
569428
570086
|
}
|
|
569429
570087
|
function generateProjectMap(repoRoot) {
|
|
569430
570088
|
const sections = [];
|
|
569431
|
-
const repoName2 =
|
|
570089
|
+
const repoName2 = basename18(repoRoot);
|
|
569432
570090
|
sections.push(`# Project Map: ${repoName2}
|
|
569433
570091
|
`);
|
|
569434
570092
|
sections.push(`> Auto-generated by omnius. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -570645,7 +571303,7 @@ var init_braille_spinner = __esm({
|
|
|
570645
571303
|
});
|
|
570646
571304
|
|
|
570647
571305
|
// packages/cli/src/tui/disk-monitor.ts
|
|
570648
|
-
import { execFile as
|
|
571306
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
570649
571307
|
import { promisify as promisify5 } from "node:util";
|
|
570650
571308
|
function unavailableDiskMetrics(path12 = process.cwd()) {
|
|
570651
571309
|
return {
|
|
@@ -570694,7 +571352,7 @@ var execFileAsync4;
|
|
|
570694
571352
|
var init_disk_monitor = __esm({
|
|
570695
571353
|
"packages/cli/src/tui/disk-monitor.ts"() {
|
|
570696
571354
|
"use strict";
|
|
570697
|
-
execFileAsync4 = promisify5(
|
|
571355
|
+
execFileAsync4 = promisify5(execFile6);
|
|
570698
571356
|
}
|
|
570699
571357
|
});
|
|
570700
571358
|
|
|
@@ -571682,7 +572340,7 @@ function setTerminalTitle(task, version4) {
|
|
|
571682
572340
|
const title = task ? `${task.slice(0, 60)} · ${ver}` : ver;
|
|
571683
572341
|
process.stdout.write(`\x1B]2;${title}\x07`);
|
|
571684
572342
|
}
|
|
571685
|
-
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_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, StatusBar;
|
|
572343
|
+
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_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_ACCENT_GREEN, HEADER_ACCENT_BOLD_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, StatusBar;
|
|
571686
572344
|
var init_status_bar = __esm({
|
|
571687
572345
|
"packages/cli/src/tui/status-bar.ts"() {
|
|
571688
572346
|
"use strict";
|
|
@@ -571861,6 +572519,10 @@ var init_status_bar = __esm({
|
|
|
571861
572519
|
TEXT_PRIMARY = tuiTextPrimary() < 0 ? 252 : tuiTextPrimary();
|
|
571862
572520
|
TEXT_DIM = tuiTextDim();
|
|
571863
572521
|
NO_SUB_AGENTS_HEADER_LABEL = " no sub-agents ";
|
|
572522
|
+
HEADER_ACCENT_GREEN = 154;
|
|
572523
|
+
HEADER_ACCENT_BOLD_FG = `\x1B[1;38;5;${HEADER_ACCENT_GREEN}m`;
|
|
572524
|
+
HEADER_BUTTON_BG = `\x1B[48;5;${HEADER_ACCENT_GREEN}m`;
|
|
572525
|
+
HEADER_BUTTON_FG = "\x1B[38;5;0m";
|
|
571864
572526
|
BOX_TL3 = "╭";
|
|
571865
572527
|
BOX_TR3 = "╮";
|
|
571866
572528
|
BOX_BL3 = "╰";
|
|
@@ -571976,6 +572638,9 @@ var init_status_bar = __esm({
|
|
|
571976
572638
|
/** True while resize is in-flight (between first SIGWINCH and debounce settle).
|
|
571977
572639
|
* Suppresses ALL footer renders to prevent separator debris at intermediate sizes. */
|
|
571978
572640
|
_resizing = false;
|
|
572641
|
+
/** Last absolute row where the footer box top was painted. Used to clear
|
|
572642
|
+
* stale footer chrome when the terminal grows and the footer moves down. */
|
|
572643
|
+
_lastFooterPaintTop = 0;
|
|
571979
572644
|
/**
|
|
571980
572645
|
* Depth-counted content write guard. Incremented by beginContentWrite(),
|
|
571981
572646
|
* decremented by endContentWrite(). Footer is only redrawn and cursor
|
|
@@ -572217,7 +572882,7 @@ var init_status_bar = __esm({
|
|
|
572217
572882
|
text += `${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
|
|
572218
572883
|
width += 1;
|
|
572219
572884
|
}
|
|
572220
|
-
text +=
|
|
572885
|
+
text += `${HEADER_ACCENT_BOLD_FG}${PANEL_BG_SEQ}${segment}`;
|
|
572221
572886
|
width += segment.length;
|
|
572222
572887
|
}
|
|
572223
572888
|
return { text, width, separatorOffsets };
|
|
@@ -572283,22 +572948,10 @@ var init_status_bar = __esm({
|
|
|
572283
572948
|
return fg2;
|
|
572284
572949
|
};
|
|
572285
572950
|
const decorateMenuButton = (cmd, label) => {
|
|
572286
|
-
|
|
572287
|
-
|
|
572288
|
-
|
|
572289
|
-
|
|
572290
|
-
return linkify(
|
|
572291
|
-
cmd,
|
|
572292
|
-
`\x1B[38;5;${BRAND_FG}m\x1B[48;5;${BRAND_BG}m ${label} \x1B[0m${PANEL_BG_SEQ}`
|
|
572293
|
-
);
|
|
572294
|
-
} else {
|
|
572295
|
-
const WHITE_BG = 15;
|
|
572296
|
-
const BLACK_FG = 0;
|
|
572297
|
-
return linkify(
|
|
572298
|
-
cmd,
|
|
572299
|
-
`\x1B[38;5;${BLACK_FG}m\x1B[48;5;${WHITE_BG}m ${label} \x1B[0m${PANEL_BG_SEQ}`
|
|
572300
|
-
);
|
|
572301
|
-
}
|
|
572951
|
+
return linkify(
|
|
572952
|
+
cmd,
|
|
572953
|
+
`${HEADER_BUTTON_FG}${HEADER_BUTTON_BG} ${label} \x1B[0m${PANEL_BG_SEQ}`
|
|
572954
|
+
);
|
|
572302
572955
|
};
|
|
572303
572956
|
const renderBtn = (cmd, label) => {
|
|
572304
572957
|
const fg2 = buttonFg(cmd);
|
|
@@ -573776,7 +574429,12 @@ var init_status_bar = __esm({
|
|
|
573776
574429
|
/** Handle terminal resize — debounced to prevent separator stacking during drag */
|
|
573777
574430
|
handleResize() {
|
|
573778
574431
|
if (!this.active) return;
|
|
574432
|
+
const prevRows = termRows();
|
|
574433
|
+
const prevCols = termCols();
|
|
574434
|
+
setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
|
|
574435
|
+
this._rebuildHeaderPanels();
|
|
573779
574436
|
this._resizing = true;
|
|
574437
|
+
this.renderFooterResizeFrame(prevRows, prevCols);
|
|
573780
574438
|
if (this._resizeTimer) clearTimeout(this._resizeTimer);
|
|
573781
574439
|
this._resizeTimer = setTimeout(() => {
|
|
573782
574440
|
this._resizeTimer = null;
|
|
@@ -573805,15 +574463,20 @@ var init_status_bar = __esm({
|
|
|
573805
574463
|
for (let row = clearStart; row <= rows; row++) {
|
|
573806
574464
|
buf += `\x1B[${row};1H\x1B[2K`;
|
|
573807
574465
|
}
|
|
574466
|
+
const boxInnerP = w - 2;
|
|
574467
|
+
buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_TL3}${BOX_H3.repeat(Math.max(0, boxInnerP))}${BOX_TR3}${RESET4}${PANEL_BG_SEQ}`;
|
|
573808
574468
|
for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
|
|
573809
|
-
const row = pos.inputStartRow + i2;
|
|
574469
|
+
const row = pos.inputStartRow + 1 + i2;
|
|
573810
574470
|
const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
|
|
573811
|
-
|
|
574471
|
+
const lineContent = `${prefix}${inputWrap.lines[i2]}`;
|
|
574472
|
+
buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
574473
|
+
buf += `${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
|
|
574474
|
+
buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row};${w}H${BOX_FG}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
|
|
573812
574475
|
}
|
|
573813
|
-
const boxInnerP = w - 2;
|
|
573814
574476
|
buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${BOX_FG}${BOX_BL3}${BOX_H3.repeat(Math.max(0, boxInnerP))}${BOX_BR3}${RESET4}${PANEL_BG_SEQ}`;
|
|
573815
|
-
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}\x1B[?7h\x1B[${pos.inputStartRow};1H`;
|
|
574477
|
+
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}\x1B[?7h\x1B[${pos.inputStartRow + 1};1H`;
|
|
573816
574478
|
this.termWrite(buf);
|
|
574479
|
+
this.rememberFooterPaint(pos.inputStartRow);
|
|
573817
574480
|
if (this._bannerRefresh) this._bannerRefresh();
|
|
573818
574481
|
} else {
|
|
573819
574482
|
this.applyScrollRegion(true);
|
|
@@ -573837,7 +574500,7 @@ var init_status_bar = __esm({
|
|
|
573837
574500
|
if (this.writeDepth === 0) {
|
|
573838
574501
|
this.parkCursorInInput();
|
|
573839
574502
|
} else {
|
|
573840
|
-
this.termWrite(`\x1B[${pos.inputStartRow};1H\x1B[?25l`);
|
|
574503
|
+
this.termWrite(`\x1B[${pos.inputStartRow + 1};1H\x1B[?25l`);
|
|
573841
574504
|
}
|
|
573842
574505
|
}
|
|
573843
574506
|
/** Register a callback that fires AT THE END of _handleResizeImmediate.
|
|
@@ -573846,6 +574509,34 @@ var init_status_bar = __esm({
|
|
|
573846
574509
|
setOnResizeFinalized(cb) {
|
|
573847
574510
|
this._onResizeFinalized = cb;
|
|
573848
574511
|
}
|
|
574512
|
+
/**
|
|
574513
|
+
* Leading-edge resize paint used to keep the footer locked to the new
|
|
574514
|
+
* terminal geometry immediately, matching the header/banner path. The
|
|
574515
|
+
* debounced resize transaction still runs afterward to do the heavier
|
|
574516
|
+
* scrollback cleanup once dragging settles.
|
|
574517
|
+
*/
|
|
574518
|
+
renderFooterResizeFrame(prevRows, prevCols) {
|
|
574519
|
+
if (!this.active) return;
|
|
574520
|
+
const rows = termRows();
|
|
574521
|
+
const w = getTermWidth();
|
|
574522
|
+
const previousRows = prevRows > 0 ? prevRows : rows;
|
|
574523
|
+
const widthChanged = prevCols > 0 && prevCols !== termCols();
|
|
574524
|
+
const oldFooterTop = this._lastFooterPaintTop > 0 ? this._lastFooterPaintTop : Math.max(1, previousRows - this._currentFooterHeight + 1);
|
|
574525
|
+
this.updateFooterHeight(w);
|
|
574526
|
+
const pos = this.rowPositions(rows);
|
|
574527
|
+
this.applyScrollRegion();
|
|
574528
|
+
if (widthChanged || oldFooterTop !== pos.inputStartRow) {
|
|
574529
|
+
this.clearFooterTransitionRows(oldFooterTop, pos.inputStartRow);
|
|
574530
|
+
}
|
|
574531
|
+
this.fillContentArea();
|
|
574532
|
+
this.repaintContent();
|
|
574533
|
+
this.refreshTasksPanelAfterLayoutChange();
|
|
574534
|
+
if (this.writeDepth > 0) {
|
|
574535
|
+
this.renderInputRowDuringStream(true);
|
|
574536
|
+
} else {
|
|
574537
|
+
this.renderFooterAndPositionInput(true);
|
|
574538
|
+
}
|
|
574539
|
+
}
|
|
573849
574540
|
/** Public cursor parking hook for command renderers and resize finalizers. */
|
|
573850
574541
|
parkCursor() {
|
|
573851
574542
|
this.parkCursorInInput();
|
|
@@ -575022,8 +575713,11 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575022
575713
|
* Does NOT set DECSTBM — the scroll region is maintained by
|
|
575023
575714
|
* applyScrollRegion() and beginContentWrite().
|
|
575024
575715
|
*/
|
|
575025
|
-
|
|
575026
|
-
|
|
575716
|
+
rememberFooterPaint(top) {
|
|
575717
|
+
this._lastFooterPaintTop = top;
|
|
575718
|
+
}
|
|
575719
|
+
renderFooterAndPositionInput(force = false) {
|
|
575720
|
+
if (!this.active || this._resizing && !force) return;
|
|
575027
575721
|
const rows = termRows();
|
|
575028
575722
|
const w = getTermWidth();
|
|
575029
575723
|
const oldFooterTop = Math.max(1, rows - this._currentFooterHeight + 1);
|
|
@@ -575081,6 +575775,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575081
575775
|
buf += `\x1B[${cursorTermRow};${inputWrap.cursorCol}H${CURSOR_BLINK_BLOCK}\x1B[?25h`;
|
|
575082
575776
|
}
|
|
575083
575777
|
this.termWrite(buf);
|
|
575778
|
+
this.rememberFooterPaint(pos.inputStartRow);
|
|
575084
575779
|
}
|
|
575085
575780
|
/**
|
|
575086
575781
|
* Redraw footer while preserving the current cursor position.
|
|
@@ -575094,13 +575789,13 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575094
575789
|
* IMPORTANT: Does NOT set DECSTBM here — setting the scroll region between
|
|
575095
575790
|
* cursor save/restore corrupts the restore position on many terminals.
|
|
575096
575791
|
*/
|
|
575097
|
-
renderFooterPreserveCursor() {
|
|
575098
|
-
if (!this.active || this._resizing) return;
|
|
575792
|
+
renderFooterPreserveCursor(force = false) {
|
|
575793
|
+
if (!this.active || this._resizing && !force) return;
|
|
575099
575794
|
if (this.footerHeightChanged()) {
|
|
575100
575795
|
if (this.writeDepth > 0) {
|
|
575101
|
-
this.renderInputRowDuringStream();
|
|
575796
|
+
this.renderInputRowDuringStream(force);
|
|
575102
575797
|
} else {
|
|
575103
|
-
this.renderFooterAndPositionInput();
|
|
575798
|
+
this.renderFooterAndPositionInput(force);
|
|
575104
575799
|
}
|
|
575105
575800
|
return;
|
|
575106
575801
|
}
|
|
@@ -575128,6 +575823,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575128
575823
|
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}\x1B[?7h\x1B8` + // DEC restore cursor
|
|
575129
575824
|
(this.writeDepth === 0 ? `${CURSOR_BLINK_BLOCK}\x1B[?25h` : "");
|
|
575130
575825
|
this.termWrite(buf);
|
|
575826
|
+
this.rememberFooterPaint(pos.inputStartRow);
|
|
575131
575827
|
if (pos.tabBarRow > 0) this.renderAgentTabs();
|
|
575132
575828
|
}
|
|
575133
575829
|
/**
|
|
@@ -575135,8 +575831,8 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575135
575831
|
* Uses DEC save/restore cursor so the streaming cursor position is preserved.
|
|
575136
575832
|
* If footer height changed, also updates DECSTBM and redraws full footer.
|
|
575137
575833
|
*/
|
|
575138
|
-
renderInputRowDuringStream() {
|
|
575139
|
-
if (!this.active || this._resizing || !this.inputStateProvider) return;
|
|
575834
|
+
renderInputRowDuringStream(force = false) {
|
|
575835
|
+
if (!this.active || this._resizing && !force || !this.inputStateProvider) return;
|
|
575140
575836
|
const rows = termRows();
|
|
575141
575837
|
const w = getTermWidth();
|
|
575142
575838
|
const oldFooterHeight = this._currentFooterHeight;
|
|
@@ -575201,6 +575897,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575201
575897
|
}
|
|
575202
575898
|
const w1 = this._origWrite ?? this._trueStdoutWrite;
|
|
575203
575899
|
w1.call(process.stdout, buf);
|
|
575900
|
+
this.rememberFooterPaint(pos.inputStartRow);
|
|
575204
575901
|
if (heightDelta !== 0) this.refreshTasksPanelAfterLayoutChange();
|
|
575205
575902
|
} else {
|
|
575206
575903
|
let buf = "\x1B7\x1B[?25l\x1B[?7l";
|
|
@@ -575232,6 +575929,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
575232
575929
|
buf += `\x1B[${pos.metricsRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildMetricsLine()}${RESET4}${PANEL_BG_SEQ}`;
|
|
575233
575930
|
buf += "\x1B[?7h\x1B8\x1B[?25l";
|
|
575234
575931
|
this.termWrite(buf);
|
|
575932
|
+
this.rememberFooterPaint(pos.inputStartRow);
|
|
575235
575933
|
}
|
|
575236
575934
|
}
|
|
575237
575935
|
/**
|
|
@@ -580408,7 +581106,7 @@ var init_platforms = __esm({
|
|
|
580408
581106
|
|
|
580409
581107
|
// packages/cli/src/tui/workspace-explorer.ts
|
|
580410
581108
|
import { existsSync as existsSync93, readdirSync as readdirSync31, readFileSync as readFileSync75, statSync as statSync34 } from "node:fs";
|
|
580411
|
-
import { basename as
|
|
581109
|
+
import { basename as basename19, extname as extname12, join as join108, relative as relative10, resolve as resolve38 } from "node:path";
|
|
580412
581110
|
function exploreWorkspace(root, options2 = {}) {
|
|
580413
581111
|
const query = (options2.query ?? "").trim().toLowerCase();
|
|
580414
581112
|
const maxResults = options2.maxResults ?? 80;
|
|
@@ -580525,7 +581223,7 @@ function classifyWorkspaceFile(path12) {
|
|
|
580525
581223
|
if (lower.includes(".test.") || lower.includes(".spec.") || lower.includes("/tests/")) return "test";
|
|
580526
581224
|
if (SOURCE_EXT.has(ext)) return "source";
|
|
580527
581225
|
if (DOC_EXT2.has(ext)) return "doc";
|
|
580528
|
-
if (CONFIG_EXT.has(ext) ||
|
|
581226
|
+
if (CONFIG_EXT.has(ext) || basename19(lower).startsWith("dockerfile")) return "config";
|
|
580529
581227
|
if (ASSET_EXT.has(ext)) return "asset";
|
|
580530
581228
|
return "other";
|
|
580531
581229
|
}
|
|
@@ -580537,7 +581235,7 @@ function scoreWorkspaceFile(entry, query) {
|
|
|
580537
581235
|
if (entry.path.startsWith("packages/cli/src/")) score += 5;
|
|
580538
581236
|
if (query) {
|
|
580539
581237
|
const lower = entry.path.toLowerCase();
|
|
580540
|
-
const name10 =
|
|
581238
|
+
const name10 = basename19(lower);
|
|
580541
581239
|
if (name10.startsWith(query)) score += 20;
|
|
580542
581240
|
if (lower.includes(`/${query}`)) score += 12;
|
|
580543
581241
|
if (lower.includes(query)) score += 8;
|
|
@@ -591992,6 +592690,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
591992
592690
|
case "parallel":
|
|
591993
592691
|
await handleParallel(arg, ctx3);
|
|
591994
592692
|
return "handled";
|
|
592693
|
+
case "ollama":
|
|
592694
|
+
await handleOllama(arg, ctx3);
|
|
592695
|
+
return "handled";
|
|
591995
592696
|
case "mcp":
|
|
591996
592697
|
case "mcps":
|
|
591997
592698
|
await handleMcp(arg, ctx3);
|
|
@@ -598042,14 +598743,14 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
598042
598743
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
598043
598744
|
continue;
|
|
598044
598745
|
}
|
|
598045
|
-
const { basename:
|
|
598746
|
+
const { basename: basename31, join: pathJoin } = await import("node:path");
|
|
598046
598747
|
const {
|
|
598047
598748
|
copyFileSync: copyFileSync5,
|
|
598048
598749
|
mkdirSync: mkdirSync81,
|
|
598049
598750
|
existsSync: exists2
|
|
598050
598751
|
} = await import("node:fs");
|
|
598051
598752
|
const { homedir: homedir53 } = await import("node:os");
|
|
598052
|
-
const modelName =
|
|
598753
|
+
const modelName = basename31(onnxDrop.path, ".onnx").replace(
|
|
598053
598754
|
/[^a-zA-Z0-9_-]/g,
|
|
598054
598755
|
"-"
|
|
598055
598756
|
);
|
|
@@ -598436,7 +599137,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
598436
599137
|
copyFileSync: cpf,
|
|
598437
599138
|
mkdirSync: mkd
|
|
598438
599139
|
} = __require("node:fs");
|
|
598439
|
-
const { basename:
|
|
599140
|
+
const { basename: basename31, join: pjoin } = __require("node:path");
|
|
598440
599141
|
if (!fe(src2)) {
|
|
598441
599142
|
renderError(`File not found: ${src2}`);
|
|
598442
599143
|
helpers.render();
|
|
@@ -598449,7 +599150,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
598449
599150
|
"clone-refs"
|
|
598450
599151
|
);
|
|
598451
599152
|
mkd(refsDir, { recursive: true });
|
|
598452
|
-
const destName =
|
|
599153
|
+
const destName = basename31(src2);
|
|
598453
599154
|
const dest = pjoin(refsDir, destName);
|
|
598454
599155
|
cpf(src2, dest);
|
|
598455
599156
|
renderInfo(`Imported "${destName}" → ${dest}`);
|
|
@@ -599582,6 +600283,113 @@ ${escapedContent}EOF'`, {
|
|
|
599582
600283
|
}
|
|
599583
600284
|
}
|
|
599584
600285
|
}
|
|
600286
|
+
async function handleOllama(arg, ctx3) {
|
|
600287
|
+
const parts = arg.trim().split(/\s+/).filter(Boolean);
|
|
600288
|
+
const subcommand = parts[0] ?? "status";
|
|
600289
|
+
if (!["cleanup", "clean", "processes", "scan", "status"].includes(subcommand)) {
|
|
600290
|
+
renderInfo("Usage: /ollama cleanup [--dry-run|--execute] [--no-inference]");
|
|
600291
|
+
return;
|
|
600292
|
+
}
|
|
600293
|
+
const execute = parts.includes("--execute") || parts.includes("--yes") || parts.includes("--kill");
|
|
600294
|
+
const dryRun = parts.includes("--dry-run") || !execute;
|
|
600295
|
+
const useInference = parts.includes("--no-inference") ? false : "auto";
|
|
600296
|
+
const scanOnly = subcommand === "processes" || subcommand === "scan" || subcommand === "status";
|
|
600297
|
+
try {
|
|
600298
|
+
const orchestrator = await Promise.resolve().then(() => (init_dist8(), dist_exports3));
|
|
600299
|
+
const poolConfig = orchestrator.resolveDefaultPoolConfig();
|
|
600300
|
+
let poolStatus = null;
|
|
600301
|
+
try {
|
|
600302
|
+
if (orchestrator.shouldUseOllamaPoolForBaseUrl(poolConfig.baseInstanceUrl)) {
|
|
600303
|
+
poolStatus = await orchestrator.getOllamaPool({ baseInstanceUrl: poolConfig.baseInstanceUrl }).status();
|
|
600304
|
+
}
|
|
600305
|
+
} catch {
|
|
600306
|
+
poolStatus = null;
|
|
600307
|
+
}
|
|
600308
|
+
const report2 = scanOnly ? await orchestrator.scanOllamaProcesses({
|
|
600309
|
+
baseInstanceUrl: poolConfig.baseInstanceUrl,
|
|
600310
|
+
poolPortStart: poolConfig.spawnPortStart,
|
|
600311
|
+
poolStatus
|
|
600312
|
+
}) : await orchestrator.cleanupStaleOllamaProcesses({
|
|
600313
|
+
dryRun,
|
|
600314
|
+
useInference,
|
|
600315
|
+
baseInstanceUrl: poolConfig.baseInstanceUrl,
|
|
600316
|
+
poolPortStart: poolConfig.spawnPortStart,
|
|
600317
|
+
poolStatus
|
|
600318
|
+
});
|
|
600319
|
+
renderOllamaCleanupReport(report2, { scanOnly, dryRun });
|
|
600320
|
+
} catch (err) {
|
|
600321
|
+
renderError(`Ollama cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
600322
|
+
}
|
|
600323
|
+
}
|
|
600324
|
+
function renderOllamaCleanupReport(report2, opts) {
|
|
600325
|
+
const decisionByPid = new Map(report2.decisions.map((d2) => [d2.pid, d2]));
|
|
600326
|
+
safeLog("");
|
|
600327
|
+
safeLog(` ${c3.bold("Ollama Pool Process Hygiene")}`);
|
|
600328
|
+
safeLog(` ${c3.dim("Base:")} ${report2.baseInstanceUrl}`);
|
|
600329
|
+
safeLog(` ${c3.dim("Protected ports:")} ${report2.protectedPorts.join(", ")}`);
|
|
600330
|
+
safeLog(` ${c3.dim("Pool ports:")} ${report2.poolPortStart}+`);
|
|
600331
|
+
if (report2.systemdOllamaMainPid) {
|
|
600332
|
+
safeLog(` ${c3.dim("systemd ollama.service PID:")} ${report2.systemdOllamaMainPid}`);
|
|
600333
|
+
}
|
|
600334
|
+
if (typeof report2.usedInference === "boolean") {
|
|
600335
|
+
safeLog(` ${c3.dim("Inference:")} ${report2.usedInference ? c3.green("used") : c3.yellow("fallback/programmatic")}`);
|
|
600336
|
+
if (report2.inferenceFallbackReason) {
|
|
600337
|
+
safeLog(` ${c3.dim("Inference fallback:")} ${report2.inferenceFallbackReason}`);
|
|
600338
|
+
}
|
|
600339
|
+
}
|
|
600340
|
+
safeLog("");
|
|
600341
|
+
if (report2.processes.length === 0) {
|
|
600342
|
+
safeLog(` ${c3.green("No ollama serve processes found outside normal service discovery.")}`);
|
|
600343
|
+
} else {
|
|
600344
|
+
safeLog(` ${c3.dim("PID PORTS CPU AGE ACTION CLASSIFICATION")}`);
|
|
600345
|
+
safeLog(` ${c3.dim("-".repeat(78))}`);
|
|
600346
|
+
for (const proc of report2.processes) {
|
|
600347
|
+
const d2 = decisionByPid.get(proc.pid);
|
|
600348
|
+
const action = d2?.action === "terminate" ? c3.red(opts.scanOnly || opts.dryRun ? "would kill" : "kill") : c3.green("keep");
|
|
600349
|
+
const ports = proc.ports.length ? proc.ports.join(",") : "-";
|
|
600350
|
+
const cpu = proc.cpuPct === null ? "?" : proc.cpuPct.toFixed(1);
|
|
600351
|
+
const age = formatShortMs(proc.elapsedMs);
|
|
600352
|
+
safeLog(
|
|
600353
|
+
` ${String(proc.pid).padEnd(8)} ${ports.padEnd(12)} ${cpu.padStart(5)} ${age.padEnd(9)} ${stripAnsiPad(action, 11)} ${d2?.classification ?? "unknown"}`
|
|
600354
|
+
);
|
|
600355
|
+
if (d2?.reasons?.length) {
|
|
600356
|
+
safeLog(` ${c3.dim(d2.reasons.join("; "))}`);
|
|
600357
|
+
}
|
|
600358
|
+
}
|
|
600359
|
+
}
|
|
600360
|
+
if (report2.terminated && report2.terminated.length > 0) {
|
|
600361
|
+
safeLog("");
|
|
600362
|
+
for (const item of report2.terminated) {
|
|
600363
|
+
const verb = item.signal === "dry-run" ? "Would terminate" : "Terminated";
|
|
600364
|
+
safeLog(` ${verb} PID ${item.pid} (${item.signal}${item.verified ? ", verified" : ""})`);
|
|
600365
|
+
}
|
|
600366
|
+
}
|
|
600367
|
+
if (report2.errors && report2.errors.length > 0) {
|
|
600368
|
+
safeLog("");
|
|
600369
|
+
for (const err of report2.errors) {
|
|
600370
|
+
safeLog(` ${c3.red(`PID ${err.pid}: ${err.error}`)}`);
|
|
600371
|
+
}
|
|
600372
|
+
}
|
|
600373
|
+
if (!opts.scanOnly && opts.dryRun) {
|
|
600374
|
+
safeLog("");
|
|
600375
|
+
safeLog(` ${c3.dim("Dry run only. Execute with:")} ${c3.cyan("/ollama cleanup --execute")}`);
|
|
600376
|
+
}
|
|
600377
|
+
safeLog("");
|
|
600378
|
+
}
|
|
600379
|
+
function formatShortMs(ms) {
|
|
600380
|
+
if (ms === null) return "?";
|
|
600381
|
+
const sec = Math.max(0, Math.floor(ms / 1e3));
|
|
600382
|
+
if (sec < 60) return `${sec}s`;
|
|
600383
|
+
const min = Math.floor(sec / 60);
|
|
600384
|
+
if (min < 60) return `${min}m`;
|
|
600385
|
+
const hr = Math.floor(min / 60);
|
|
600386
|
+
if (hr < 48) return `${hr}h`;
|
|
600387
|
+
return `${Math.floor(hr / 24)}d`;
|
|
600388
|
+
}
|
|
600389
|
+
function stripAnsiPad(value2, width) {
|
|
600390
|
+
const raw = value2.replace(/\x1b\[[0-9;]*m/g, "");
|
|
600391
|
+
return value2 + " ".repeat(Math.max(0, width - raw.length));
|
|
600392
|
+
}
|
|
599585
600393
|
async function handleMcp(subcommand, ctx3) {
|
|
599586
600394
|
const manager = ctx3.getMcpManager?.();
|
|
599587
600395
|
if (!manager) {
|
|
@@ -601775,7 +602583,7 @@ var init_commands = __esm({
|
|
|
601775
602583
|
|
|
601776
602584
|
// packages/cli/src/tui/project-context.ts
|
|
601777
602585
|
import { existsSync as existsSync102, readFileSync as readFileSync82, readdirSync as readdirSync34 } from "node:fs";
|
|
601778
|
-
import { join as join115, basename as
|
|
602586
|
+
import { join as join115, basename as basename20 } from "node:path";
|
|
601779
602587
|
import { execSync as execSync53 } from "node:child_process";
|
|
601780
602588
|
import { homedir as homedir39 } from "node:os";
|
|
601781
602589
|
function getModelTier(modelName) {
|
|
@@ -601856,7 +602664,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
601856
602664
|
try {
|
|
601857
602665
|
const raw = readFileSync82(join115(dir, file), "utf-8");
|
|
601858
602666
|
const entries = JSON.parse(raw);
|
|
601859
|
-
const topic =
|
|
602667
|
+
const topic = basename20(file, ".json");
|
|
601860
602668
|
for (const [k, v] of Object.entries(entries)) {
|
|
601861
602669
|
if (!v?.value) continue;
|
|
601862
602670
|
all2.push({ topic, key: k, value: String(v.value), scope, ts: v.timestamp ?? "" });
|
|
@@ -602120,7 +602928,7 @@ __export(visual_identity_association_exports, {
|
|
|
602120
602928
|
formatVisualIdentityAssociationContext: () => formatVisualIdentityAssociationContext,
|
|
602121
602929
|
stageVisualIdentityAssertion: () => stageVisualIdentityAssertion
|
|
602122
602930
|
});
|
|
602123
|
-
import { basename as
|
|
602931
|
+
import { basename as basename21 } from "node:path";
|
|
602124
602932
|
function normalizePersonName(name10) {
|
|
602125
602933
|
return name10.trim().toLowerCase().replace(/\s+/g, " ");
|
|
602126
602934
|
}
|
|
@@ -602442,7 +603250,7 @@ async function associateVisualIdentityFromImage(options2) {
|
|
|
602442
603250
|
relation: "same_person_candidate",
|
|
602443
603251
|
confidence: match.confidence,
|
|
602444
603252
|
assertedBy: { id: "visual_memory", displayName: "visual_memory", isBot: true },
|
|
602445
|
-
note: `Prior enrolled visual-memory face match for ${
|
|
603253
|
+
note: `Prior enrolled visual-memory face match for ${basename21(options2.imagePath)}`
|
|
602446
603254
|
}]
|
|
602447
603255
|
});
|
|
602448
603256
|
if (result2.episodeId) committedEpisodeIds.push(result2.episodeId);
|
|
@@ -602487,7 +603295,7 @@ async function associateVisualIdentityFromImage(options2) {
|
|
|
602487
603295
|
relation: "depicts",
|
|
602488
603296
|
confidence: item.confidence,
|
|
602489
603297
|
assertedBy: item.sender || options2.sender,
|
|
602490
|
-
note: item.note || `Applied explicit pending identity assertion to ${
|
|
603298
|
+
note: item.note || `Applied explicit pending identity assertion to ${basename21(options2.imagePath)}`
|
|
602491
603299
|
}]
|
|
602492
603300
|
});
|
|
602493
603301
|
if (result2.episodeId) committedEpisodeIds.push(result2.episodeId);
|
|
@@ -602545,7 +603353,7 @@ var init_visual_identity_association = __esm({
|
|
|
602545
603353
|
|
|
602546
603354
|
// packages/cli/src/tui/identity-memory-tool.ts
|
|
602547
603355
|
import { existsSync as existsSync103 } from "node:fs";
|
|
602548
|
-
import { basename as
|
|
603356
|
+
import { basename as basename22, extname as extname14, resolve as resolve41 } from "node:path";
|
|
602549
603357
|
function personKey2(name10) {
|
|
602550
603358
|
return `person:${name10.trim().toLowerCase().replace(/\s+/g, " ")}`;
|
|
602551
603359
|
}
|
|
@@ -602614,7 +603422,7 @@ async function resolveMediaFromArgs(args, opts) {
|
|
|
602614
603422
|
path: path12,
|
|
602615
603423
|
media,
|
|
602616
603424
|
modality: inferModality(media),
|
|
602617
|
-
label:
|
|
603425
|
+
label: basename22(path12)
|
|
602618
603426
|
};
|
|
602619
603427
|
}
|
|
602620
603428
|
function edgeDirection(edge, nodeId, otherText) {
|
|
@@ -602772,7 +603580,7 @@ var init_identity_memory_tool = __esm({
|
|
|
602772
603580
|
} else if (shouldEnrollFace) {
|
|
602773
603581
|
faceLine = "face enrollment: skipped because no resolved image path was available";
|
|
602774
603582
|
}
|
|
602775
|
-
const mediaLine = resolvedMedia ? `media: ${resolvedMedia.label ||
|
|
603583
|
+
const mediaLine = resolvedMedia ? `media: ${resolvedMedia.label || basename22(resolvedMedia.path)} (${resolvedMedia.path})` : "media: none; stored as scoped textual identity evidence only";
|
|
602776
603584
|
const output = [
|
|
602777
603585
|
`Stored identity evidence for ${name10}.`,
|
|
602778
603586
|
`relation: ${relation}`,
|
|
@@ -603713,7 +604521,7 @@ var init_banner = __esm({
|
|
|
603713
604521
|
|
|
603714
604522
|
// packages/cli/src/tui/carousel-descriptors.ts
|
|
603715
604523
|
import { existsSync as existsSync105, readFileSync as readFileSync84, writeFileSync as writeFileSync53, mkdirSync as mkdirSync59, readdirSync as readdirSync35 } from "node:fs";
|
|
603716
|
-
import { join as join118, basename as
|
|
604524
|
+
import { join as join118, basename as basename23 } from "node:path";
|
|
603717
604525
|
function loadToolProfile(repoRoot) {
|
|
603718
604526
|
const filePath = join118(repoRoot, OMNIUS_DIR, "context", TOOL_PROFILE_FILE);
|
|
603719
604527
|
try {
|
|
@@ -603809,7 +604617,7 @@ function generateDescriptors(repoRoot) {
|
|
|
603809
604617
|
extractFromSessions(repoRoot, tags);
|
|
603810
604618
|
extractFromMemory(repoRoot, tags);
|
|
603811
604619
|
extractFromToolProfile(profile, tags);
|
|
603812
|
-
const repoName2 =
|
|
604620
|
+
const repoName2 = basename23(repoRoot);
|
|
603813
604621
|
if (repoName2 && !tags.includes(repoName2)) {
|
|
603814
604622
|
tags.push(repoName2);
|
|
603815
604623
|
}
|
|
@@ -605019,7 +605827,7 @@ var init_promptLoader3 = __esm({
|
|
|
605019
605827
|
|
|
605020
605828
|
// packages/cli/src/tui/dream-engine.ts
|
|
605021
605829
|
import { mkdirSync as mkdirSync61, writeFileSync as writeFileSync54, readFileSync as readFileSync86, existsSync as existsSync107, readdirSync as readdirSync36 } from "node:fs";
|
|
605022
|
-
import { join as join121, basename as
|
|
605830
|
+
import { join as join121, basename as basename24 } from "node:path";
|
|
605023
605831
|
import { execSync as execSync54 } from "node:child_process";
|
|
605024
605832
|
function setDreamWriteContent(fn) {
|
|
605025
605833
|
_dreamWriteContent = fn;
|
|
@@ -605232,7 +606040,7 @@ var init_dream_engine = __esm({
|
|
|
605232
606040
|
const rawPath = String(args["path"] ?? "");
|
|
605233
606041
|
const content = String(args["content"] ?? "");
|
|
605234
606042
|
if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
605235
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join121(this.autoresearchDir,
|
|
606043
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join121(this.autoresearchDir, basename24(rawPath)) : join121(this.autoresearchDir, rawPath);
|
|
605236
606044
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
605237
606045
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .omnius/autoresearch/", durationMs: Date.now() - start2 };
|
|
605238
606046
|
}
|
|
@@ -605267,7 +606075,7 @@ var init_dream_engine = __esm({
|
|
|
605267
606075
|
const rawPath = String(args["path"] ?? "");
|
|
605268
606076
|
const oldStr = String(args["old_string"] ?? "");
|
|
605269
606077
|
const newStr = String(args["new_string"] ?? "");
|
|
605270
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join121(this.autoresearchDir,
|
|
606078
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join121(this.autoresearchDir, basename24(rawPath)) : join121(this.autoresearchDir, rawPath);
|
|
605271
606079
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
605272
606080
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .omnius/autoresearch/", durationMs: Date.now() - start2 };
|
|
605273
606081
|
}
|
|
@@ -605320,7 +606128,7 @@ var init_dream_engine = __esm({
|
|
|
605320
606128
|
const rawPath = String(args["path"] ?? "");
|
|
605321
606129
|
const content = String(args["content"] ?? "");
|
|
605322
606130
|
if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
605323
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join121(this.dreamsDir,
|
|
606131
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join121(this.dreamsDir, basename24(rawPath)) : join121(this.dreamsDir, rawPath);
|
|
605324
606132
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
605325
606133
|
return { success: false, output: "", error: "Dream mode: writes are confined to .omnius/dreams/", durationMs: Date.now() - start2 };
|
|
605326
606134
|
}
|
|
@@ -605355,7 +606163,7 @@ var init_dream_engine = __esm({
|
|
|
605355
606163
|
const rawPath = String(args["path"] ?? "");
|
|
605356
606164
|
const oldStr = String(args["old_string"] ?? "");
|
|
605357
606165
|
const newStr = String(args["new_string"] ?? "");
|
|
605358
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join121(this.dreamsDir,
|
|
606166
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join121(this.dreamsDir, basename24(rawPath)) : join121(this.dreamsDir, rawPath);
|
|
605359
606167
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
605360
606168
|
return { success: false, output: "", error: "Dream mode: edits are confined to .omnius/dreams/", durationMs: Date.now() - start2 };
|
|
605361
606169
|
}
|
|
@@ -606952,7 +607760,7 @@ var init_bless_engine = __esm({
|
|
|
606952
607760
|
|
|
606953
607761
|
// packages/cli/src/tui/dmn-engine.ts
|
|
606954
607762
|
import { existsSync as existsSync108, readFileSync as readFileSync87, writeFileSync as writeFileSync55, mkdirSync as mkdirSync62, readdirSync as readdirSync37, unlinkSync as unlinkSync19 } from "node:fs";
|
|
606955
|
-
import { join as join122, basename as
|
|
607763
|
+
import { join as join122, basename as basename25 } from "node:path";
|
|
606956
607764
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
606957
607765
|
const competenceReport = competence.length > 0 ? competence.map((c9) => {
|
|
606958
607766
|
const rate = c9.attempts > 0 ? Math.round(c9.successes / c9.attempts * 100) : 0;
|
|
@@ -607497,9 +608305,9 @@ OUTPUT: Call task_complete with JSON:
|
|
|
607497
608305
|
confidence: this.extractConfidence(gateResult)
|
|
607498
608306
|
});
|
|
607499
608307
|
workspace.evidenceAccumulated = this.extractConfidence(gateResult);
|
|
607500
|
-
const
|
|
608308
|
+
const decision2 = gateResult.includes('"GO"') || gateResult.toLowerCase().includes("decision.*go") ? "go" : "nogo";
|
|
607501
608309
|
const evScore = Math.round(workspace.evidenceAccumulated * 100);
|
|
607502
|
-
const voiceFinal =
|
|
608310
|
+
const voiceFinal = decision2 === "go" ? `Decision: GO (evidence ${evScore}%). I know what to do next. Let's move.` : `Decision: NOGO (evidence ${evScore}%). Not enough clarity to act. Better to rest and gather more information.`;
|
|
607503
608311
|
workspace.innerVoice.push(voiceFinal);
|
|
607504
608312
|
onEvent?.({
|
|
607505
608313
|
type: "status",
|
|
@@ -607703,7 +608511,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
607703
608511
|
try {
|
|
607704
608512
|
const files = readdirSync37(dir).filter((f2) => f2.endsWith(".json"));
|
|
607705
608513
|
for (const f2 of files) {
|
|
607706
|
-
const topic =
|
|
608514
|
+
const topic = basename25(f2, ".json");
|
|
607707
608515
|
if (!topics.includes(topic)) topics.push(topic);
|
|
607708
608516
|
}
|
|
607709
608517
|
} catch {
|
|
@@ -607757,7 +608565,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
607757
608565
|
|
|
607758
608566
|
// packages/cli/src/tui/snr-engine.ts
|
|
607759
608567
|
import { existsSync as existsSync109, readdirSync as readdirSync38, readFileSync as readFileSync88 } from "node:fs";
|
|
607760
|
-
import { join as join123, basename as
|
|
608568
|
+
import { join as join123, basename as basename26 } from "node:path";
|
|
607761
608569
|
function computeDPrime(signalScores, noiseScores) {
|
|
607762
608570
|
if (signalScores.length === 0 || noiseScores.length === 0) return 0;
|
|
607763
608571
|
const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
|
|
@@ -608051,7 +608859,7 @@ Call task_complete with the JSON array when done.`,
|
|
|
608051
608859
|
try {
|
|
608052
608860
|
const files = readdirSync38(dir).filter((f2) => f2.endsWith(".json"));
|
|
608053
608861
|
for (const f2 of files) {
|
|
608054
|
-
const topic =
|
|
608862
|
+
const topic = basename26(f2, ".json");
|
|
608055
608863
|
if (topics.length > 0 && !topics.includes(topic)) continue;
|
|
608056
608864
|
try {
|
|
608057
608865
|
const data = JSON.parse(readFileSync88(join123(dir, f2), "utf-8"));
|
|
@@ -609534,7 +610342,7 @@ import {
|
|
|
609534
610342
|
} from "node:fs";
|
|
609535
610343
|
import { mkdir as mkdir19 } from "node:fs/promises";
|
|
609536
610344
|
import {
|
|
609537
|
-
basename as
|
|
610345
|
+
basename as basename27,
|
|
609538
610346
|
dirname as dirname34,
|
|
609539
610347
|
extname as extname15,
|
|
609540
610348
|
isAbsolute as isAbsolute7,
|
|
@@ -609768,7 +610576,7 @@ function guardPath(root, rawPath) {
|
|
|
609768
610576
|
error: `Path escapes the public creative workspace. Use a relative path under ${rootAbs}.`
|
|
609769
610577
|
};
|
|
609770
610578
|
}
|
|
609771
|
-
if (
|
|
610579
|
+
if (basename27(abs) === MANIFEST_FILE) {
|
|
609772
610580
|
return { ok: false, error: "The creative workspace manifest is internal and cannot be edited." };
|
|
609773
610581
|
}
|
|
609774
610582
|
return { ok: true, path: { abs, rel } };
|
|
@@ -609860,7 +610668,7 @@ function rememberCreated(root, absPath) {
|
|
|
609860
610668
|
manifest.objects[rel] = {
|
|
609861
610669
|
logicalRel: rel,
|
|
609862
610670
|
storedRel,
|
|
609863
|
-
originalName:
|
|
610671
|
+
originalName: basename27(guarded.path.abs),
|
|
609864
610672
|
prefixBytes: prefix.length,
|
|
609865
610673
|
encrypted: true,
|
|
609866
610674
|
key: key.toString("base64"),
|
|
@@ -609911,7 +610719,7 @@ function materializeTelegramCreativeArtifactForSend(root, rawPath) {
|
|
|
609911
610719
|
}
|
|
609912
610720
|
const stageDir = join124(rootAbs, SEND_DIR, `${Date.now()}-${randomBytes21(8).toString("hex")}`);
|
|
609913
610721
|
mkdirSync63(stageDir, { recursive: true });
|
|
609914
|
-
const staged = join124(stageDir, object.originalName ||
|
|
610722
|
+
const staged = join124(stageDir, object.originalName || basename27(rel));
|
|
609915
610723
|
writeFileSync56(staged, payload);
|
|
609916
610724
|
return {
|
|
609917
610725
|
ok: true,
|
|
@@ -610222,23 +611030,23 @@ var init_stimulation = __esm({
|
|
|
610222
611030
|
context: this.formatContext(input.channelId)
|
|
610223
611031
|
};
|
|
610224
611032
|
}
|
|
610225
|
-
applyAgentDecision(channelId,
|
|
611033
|
+
applyAgentDecision(channelId, decision2, nowMs = Date.now()) {
|
|
610226
611034
|
const state = this.stateFor(channelId, nowMs);
|
|
610227
|
-
if (Number.isFinite(
|
|
610228
|
-
state.attention = clamp017(Number(
|
|
610229
|
-
} else if (Number.isFinite(
|
|
610230
|
-
state.attention = clamp017(state.attention + Number(
|
|
611035
|
+
if (Number.isFinite(decision2.attentionScore)) {
|
|
611036
|
+
state.attention = clamp017(Number(decision2.attentionScore));
|
|
611037
|
+
} else if (Number.isFinite(decision2.attentionDelta)) {
|
|
611038
|
+
state.attention = clamp017(state.attention + Number(decision2.attentionDelta));
|
|
610231
611039
|
} else {
|
|
610232
|
-
state.attention = clamp017(state.attention + (
|
|
611040
|
+
state.attention = clamp017(state.attention + (decision2.shouldReply ? 0.22 : -0.1));
|
|
610233
611041
|
}
|
|
610234
|
-
if (
|
|
610235
|
-
state.attention = Math.max(state.attention, PHASE_FLOORS[
|
|
610236
|
-
state.phase =
|
|
611042
|
+
if (decision2.phase) {
|
|
611043
|
+
state.attention = Math.max(state.attention, PHASE_FLOORS[decision2.phase]);
|
|
611044
|
+
state.phase = decision2.phase;
|
|
610237
611045
|
} else {
|
|
610238
611046
|
state.phase = phaseFromAttention(state.attention);
|
|
610239
611047
|
}
|
|
610240
|
-
state.consecutiveNoReply =
|
|
610241
|
-
state.nextAnalysisAfterMessages = Number.isFinite(
|
|
611048
|
+
state.consecutiveNoReply = decision2.shouldReply ? 0 : state.consecutiveNoReply + 1;
|
|
611049
|
+
state.nextAnalysisAfterMessages = Number.isFinite(decision2.nextAnalysisAfterMessages) ? Math.max(1, Math.floor(Number(decision2.nextAnalysisAfterMessages))) : void 0;
|
|
610242
611050
|
state.lastAnalysisAtMs = nowMs;
|
|
610243
611051
|
state.messagesSinceAnalysis = 0;
|
|
610244
611052
|
state.updatedAtMs = nowMs;
|
|
@@ -611324,7 +612132,7 @@ function buildTelegramReflectionExtractionPrompt(options2) {
|
|
|
611324
612132
|
episodes || "none"
|
|
611325
612133
|
].join("\n");
|
|
611326
612134
|
}
|
|
611327
|
-
function
|
|
612135
|
+
function parseJsonObject2(raw) {
|
|
611328
612136
|
const text = raw.trim();
|
|
611329
612137
|
if (!text) return null;
|
|
611330
612138
|
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
|
|
@@ -611338,7 +612146,7 @@ function parseJsonObject(raw) {
|
|
|
611338
612146
|
}
|
|
611339
612147
|
}
|
|
611340
612148
|
function parseTelegramReflectionExtraction(raw) {
|
|
611341
|
-
const parsed =
|
|
612149
|
+
const parsed = parseJsonObject2(raw);
|
|
611342
612150
|
if (!parsed) return null;
|
|
611343
612151
|
const tags = Array.isArray(parsed.tags) ? parsed.tags.map((item) => {
|
|
611344
612152
|
const obj = item;
|
|
@@ -612376,7 +613184,7 @@ var init_vision_ingress = __esm({
|
|
|
612376
613184
|
|
|
612377
613185
|
// packages/cli/src/tui/telegram-bridge.ts
|
|
612378
613186
|
import { mkdirSync as mkdirSync65, existsSync as existsSync113, unlinkSync as unlinkSync22, readdirSync as readdirSync40, statSync as statSync39, statfsSync as statfsSync5, readFileSync as readFileSync92, writeFileSync as writeFileSync59, appendFileSync as appendFileSync9 } from "node:fs";
|
|
612379
|
-
import { join as join127, resolve as resolve43, basename as
|
|
613187
|
+
import { join as join127, resolve as resolve43, basename as basename28, relative as relative13, isAbsolute as isAbsolute8, extname as extname16 } from "node:path";
|
|
612380
613188
|
import { homedir as homedir40 } from "node:os";
|
|
612381
613189
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
612382
613190
|
import { createHash as createHash24, randomBytes as randomBytes22, randomInt } from "node:crypto";
|
|
@@ -614631,25 +615439,25 @@ External acquisition contract:
|
|
|
614631
615439
|
this.subAgentViewCallbacks.onStatus(viewId, "running");
|
|
614632
615440
|
return viewId;
|
|
614633
615441
|
}
|
|
614634
|
-
writeTelegramAttentionDecision(viewId,
|
|
614635
|
-
const route =
|
|
615442
|
+
writeTelegramAttentionDecision(viewId, decision2) {
|
|
615443
|
+
const route = decision2.shouldReply ? `reply via ${decision2.route}` : "silent";
|
|
614636
615444
|
const attention = [
|
|
614637
|
-
|
|
614638
|
-
|
|
614639
|
-
|
|
615445
|
+
decision2.attentionState ? `state=${decision2.attentionState}` : "",
|
|
615446
|
+
decision2.attentionDelta !== void 0 ? `delta=${decision2.attentionDelta.toFixed(2)}` : "",
|
|
615447
|
+
decision2.attentionScore !== void 0 ? `score=${decision2.attentionScore.toFixed(2)}` : ""
|
|
614640
615448
|
].filter(Boolean).join(", ");
|
|
614641
615449
|
const cadence = [
|
|
614642
|
-
|
|
615450
|
+
decision2.nextCheckAfterMessages !== void 0 ? `after ${decision2.nextCheckAfterMessages} message(s)` : ""
|
|
614643
615451
|
].filter(Boolean).join(" or ");
|
|
614644
615452
|
const lines = [
|
|
614645
|
-
`decision: ${route} (${
|
|
615453
|
+
`decision: ${route} (${decision2.source}, confidence ${decision2.confidence.toFixed(2)})`,
|
|
614646
615454
|
attention ? `attention: ${attention}` : "",
|
|
614647
|
-
`reason: ${
|
|
614648
|
-
|
|
614649
|
-
|
|
614650
|
-
|
|
614651
|
-
|
|
614652
|
-
|
|
615455
|
+
`reason: ${decision2.reason}`,
|
|
615456
|
+
decision2.diagnosticNote ? `router diagnostic: ${decision2.diagnosticNote}` : "",
|
|
615457
|
+
decision2.silentDisposition ? `silent disposition: ${decision2.silentDisposition}` : "",
|
|
615458
|
+
decision2.mentalNote ? `mental note: ${decision2.mentalNote}` : "",
|
|
615459
|
+
decision2.memoryNote ? `memory note: ${decision2.memoryNote}` : "",
|
|
615460
|
+
decision2.relationshipNote ? `relationship note: ${decision2.relationshipNote}` : "",
|
|
614653
615461
|
cadence ? `next attention sample: ${cadence}` : ""
|
|
614654
615462
|
].filter(Boolean);
|
|
614655
615463
|
if (viewId && this.subAgentViewCallbacks) {
|
|
@@ -614658,15 +615466,15 @@ External acquisition contract:
|
|
|
614658
615466
|
this.subAgentViewCallbacks.onComplete(viewId);
|
|
614659
615467
|
}
|
|
614660
615468
|
}
|
|
614661
|
-
mirrorTelegramAttentionDecision(msg,
|
|
614662
|
-
const route =
|
|
614663
|
-
const primary = `attention decision: ${route} (${
|
|
615469
|
+
mirrorTelegramAttentionDecision(msg, decision2) {
|
|
615470
|
+
const route = decision2.shouldReply ? `reply via ${decision2.route}` : "silent";
|
|
615471
|
+
const primary = `attention decision: ${route} (${decision2.source}, confidence ${decision2.confidence.toFixed(2)}) - ${decision2.reason}`;
|
|
614664
615472
|
const notes2 = [
|
|
614665
|
-
|
|
614666
|
-
|
|
614667
|
-
|
|
614668
|
-
|
|
614669
|
-
|
|
615473
|
+
decision2.diagnosticNote ? `router diagnostic: ${decision2.diagnosticNote}` : "",
|
|
615474
|
+
decision2.silentDisposition ? `silent reflection: ${decision2.silentDisposition}` : "",
|
|
615475
|
+
decision2.mentalNote ? `mental note: ${decision2.mentalNote}` : "",
|
|
615476
|
+
decision2.memoryNote ? `memory note: ${decision2.memoryNote}` : "",
|
|
615477
|
+
decision2.relationshipNote ? `relationship note: ${decision2.relationshipNote}` : ""
|
|
614670
615478
|
].filter(Boolean);
|
|
614671
615479
|
this.tuiWrite(() => {
|
|
614672
615480
|
renderTelegramSubAgentEvent(msg.username, primary);
|
|
@@ -614675,17 +615483,17 @@ External acquisition contract:
|
|
|
614675
615483
|
}
|
|
614676
615484
|
});
|
|
614677
615485
|
}
|
|
614678
|
-
deliverTelegramAttentionDecision(sessionKey, msg, viewId,
|
|
614679
|
-
this.writeTelegramAttentionDecision(viewId,
|
|
614680
|
-
this.mirrorTelegramAttentionDecision(msg,
|
|
615486
|
+
deliverTelegramAttentionDecision(sessionKey, msg, viewId, decision2, salienceSignals, daydreamOpportunities = this.latestTelegramDaydreamOpportunityInputs(sessionKey)) {
|
|
615487
|
+
this.writeTelegramAttentionDecision(viewId, decision2);
|
|
615488
|
+
this.mirrorTelegramAttentionDecision(msg, decision2);
|
|
614681
615489
|
this.commitTelegramSocialDecision(
|
|
614682
615490
|
sessionKey,
|
|
614683
615491
|
msg,
|
|
614684
|
-
|
|
615492
|
+
decision2,
|
|
614685
615493
|
salienceSignals,
|
|
614686
615494
|
daydreamOpportunities
|
|
614687
615495
|
);
|
|
614688
|
-
this.applyTelegramStimulationDecision(sessionKey,
|
|
615496
|
+
this.applyTelegramStimulationDecision(sessionKey, decision2);
|
|
614689
615497
|
}
|
|
614690
615498
|
normalizeTelegramCommandText(input) {
|
|
614691
615499
|
const trimmed = input.trim();
|
|
@@ -616032,40 +616840,40 @@ ${mediaContext}` : ""
|
|
|
616032
616840
|
timeoutMs: Math.min(Math.max(this.agentConfig.timeoutMs ?? 3e4, 5e3), 2e4),
|
|
616033
616841
|
think: false
|
|
616034
616842
|
});
|
|
616035
|
-
const
|
|
616843
|
+
const decision2 = parseTelegramReflectionFollowupDecision(result.choices[0]?.message?.content ?? "");
|
|
616036
616844
|
state.lastFollowupArtifactAt = artifact.generatedAt;
|
|
616037
|
-
if (!
|
|
616845
|
+
if (!decision2) {
|
|
616038
616846
|
this.saveTelegramConversationState(sessionKey);
|
|
616039
616847
|
return { sent: false, reason: "model returned no usable follow-up decision" };
|
|
616040
616848
|
}
|
|
616041
|
-
if (!
|
|
616849
|
+
if (!decision2.shouldSend || !decision2.text || decision2.confidence < 0.66) {
|
|
616042
616850
|
this.saveTelegramConversationState(sessionKey);
|
|
616043
|
-
return { sent: false, reason:
|
|
616851
|
+
return { sent: false, reason: decision2.reason || "model chose silence" };
|
|
616044
616852
|
}
|
|
616045
|
-
const replyTo =
|
|
616853
|
+
const replyTo = decision2.replyToMessageId && candidateMessageIds.includes(decision2.replyToMessageId) ? decision2.replyToMessageId : void 0;
|
|
616046
616854
|
const chatId = this.telegramChatIdFromArtifact(artifact);
|
|
616047
616855
|
const sentMessageId = await this.sendMessageHTML(
|
|
616048
616856
|
chatId,
|
|
616049
|
-
convertMarkdownToTelegramHTML(
|
|
616857
|
+
convertMarkdownToTelegramHTML(decision2.text),
|
|
616050
616858
|
replyTo
|
|
616051
616859
|
);
|
|
616052
616860
|
this.recordTelegramAssistantMessage({
|
|
616053
616861
|
chatId,
|
|
616054
616862
|
chatType: artifact.chatType,
|
|
616055
616863
|
chatTitle: artifact.chatTitle,
|
|
616056
|
-
text:
|
|
616864
|
+
text: decision2.text,
|
|
616057
616865
|
username: this.state.botUsername || "omnius",
|
|
616058
616866
|
firstName: "Omnius",
|
|
616059
616867
|
fromUserId: 0,
|
|
616060
616868
|
messageId: sentMessageId ?? 0
|
|
616061
|
-
},
|
|
616869
|
+
}, decision2.text, "chat", {
|
|
616062
616870
|
messageId: sentMessageId,
|
|
616063
616871
|
replyToMessageId: replyTo
|
|
616064
616872
|
});
|
|
616065
616873
|
state.lastFollowupAt = now;
|
|
616066
616874
|
this.saveTelegramConversationState(sessionKey);
|
|
616067
|
-
this.tuiWrite(() => renderTelegramSubAgentEvent("reflection", `sent scoped Telegram follow-up (${
|
|
616068
|
-
return { sent: true, reason:
|
|
616875
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent("reflection", `sent scoped Telegram follow-up (${decision2.confidence.toFixed(2)}): ${decision2.reason}`));
|
|
616876
|
+
return { sent: true, reason: decision2.reason };
|
|
616069
616877
|
} catch (err) {
|
|
616070
616878
|
state.lastFollowupArtifactAt = artifact.generatedAt;
|
|
616071
616879
|
this.saveTelegramConversationState(sessionKey);
|
|
@@ -616115,7 +616923,7 @@ ${mediaContext}` : ""
|
|
|
616115
616923
|
}
|
|
616116
616924
|
return opportunities;
|
|
616117
616925
|
}
|
|
616118
|
-
commitTelegramSocialDecision(sessionKey, msg,
|
|
616926
|
+
commitTelegramSocialDecision(sessionKey, msg, decision2, salienceSignals, daydreamOpportunities = this.latestTelegramDaydreamOpportunityInputs(sessionKey)) {
|
|
616119
616927
|
try {
|
|
616120
616928
|
commitTelegramSocialDecision(this.telegramSocialStateForSession(sessionKey), {
|
|
616121
616929
|
sessionKey,
|
|
@@ -616124,15 +616932,15 @@ ${mediaContext}` : ""
|
|
|
616124
616932
|
messageThreadId: msg.messageThreadId,
|
|
616125
616933
|
sender: this.telegramMessageSocialActorInput(msg),
|
|
616126
616934
|
replyToMessageId: msg.replyToMessageId,
|
|
616127
|
-
route:
|
|
616128
|
-
shouldReply:
|
|
616129
|
-
confidence:
|
|
616130
|
-
reason:
|
|
616131
|
-
source:
|
|
616132
|
-
silentDisposition:
|
|
616133
|
-
mentalNote:
|
|
616134
|
-
memoryNote:
|
|
616135
|
-
relationshipNote:
|
|
616935
|
+
route: decision2.route,
|
|
616936
|
+
shouldReply: decision2.shouldReply,
|
|
616937
|
+
confidence: decision2.confidence,
|
|
616938
|
+
reason: decision2.reason,
|
|
616939
|
+
source: decision2.source,
|
|
616940
|
+
silentDisposition: decision2.silentDisposition,
|
|
616941
|
+
mentalNote: decision2.mentalNote,
|
|
616942
|
+
memoryNote: decision2.memoryNote,
|
|
616943
|
+
relationshipNote: decision2.relationshipNote,
|
|
616136
616944
|
salienceSignals,
|
|
616137
616945
|
self: this.telegramSelfSocialActorInput(),
|
|
616138
616946
|
daydreamOpportunities
|
|
@@ -616357,7 +617165,7 @@ ${mediaContext}` : ""
|
|
|
616357
617165
|
}
|
|
616358
617166
|
const matchingEntry = mediaEntries.find((entry) => {
|
|
616359
617167
|
if (resolve43(entry.localPath) === resolve43(raw)) return true;
|
|
616360
|
-
if (
|
|
617168
|
+
if (basename28(entry.localPath) === raw) return true;
|
|
616361
617169
|
if (entry.fileUniqueId === raw || entry.fileId === raw) return true;
|
|
616362
617170
|
if (entry.messageId && String(entry.messageId) === raw) return true;
|
|
616363
617171
|
if (entry.messageId && `message_id:${entry.messageId}` === raw.toLowerCase()) return true;
|
|
@@ -616394,7 +617202,7 @@ ${mediaContext}` : ""
|
|
|
616394
617202
|
}
|
|
616395
617203
|
return entries.find((entry2) => {
|
|
616396
617204
|
if (resolve43(entry2.localPath) === resolve43(ref)) return true;
|
|
616397
|
-
if (
|
|
617205
|
+
if (basename28(entry2.localPath) === ref) return true;
|
|
616398
617206
|
if (entry2.fileUniqueId === ref || entry2.fileId === ref) return true;
|
|
616399
617207
|
if (entry2.messageId && String(entry2.messageId) === ref) return true;
|
|
616400
617208
|
return false;
|
|
@@ -616422,7 +617230,7 @@ ${mediaContext}` : ""
|
|
|
616422
617230
|
caption: entry.caption
|
|
616423
617231
|
},
|
|
616424
617232
|
modality,
|
|
616425
|
-
label: `Telegram message_id ${entry.messageId || "unknown"} ${
|
|
617233
|
+
label: `Telegram message_id ${entry.messageId || "unknown"} ${basename28(entry.localPath)}`,
|
|
616426
617234
|
extractedContent: entry.extractedContent
|
|
616427
617235
|
};
|
|
616428
617236
|
}
|
|
@@ -617531,8 +618339,8 @@ ${cardLines.join("\n")}`);
|
|
|
617531
618339
|
const caption = entry.caption ? ` caption=${telegramContextJsonString(entry.caption, 120)}` : "";
|
|
617532
618340
|
const extracted = entry.extractedContent ? `
|
|
617533
618341
|
extracted=${telegramContextJsonString(entry.extractedContent.replace(/\s+/g, " "), 220)}` : "";
|
|
617534
|
-
const alias = entry.messageId ? `message_id:${entry.messageId}` :
|
|
617535
|
-
return `- ${alias}${replyMark}: ${kind}; file ${
|
|
618342
|
+
const alias = entry.messageId ? `message_id:${entry.messageId}` : basename28(entry.localPath);
|
|
618343
|
+
return `- ${alias}${replyMark}: ${kind}; file ${basename28(entry.localPath)}${caption}${extracted}`;
|
|
617536
618344
|
});
|
|
617537
618345
|
sections.push([
|
|
617538
618346
|
"### Recent Chat Media",
|
|
@@ -617643,13 +618451,13 @@ ${lines.join("\n")}`);
|
|
|
617643
618451
|
const resolvedReply = this.resolveTelegramReplyContext(this.sessionKeyForMessage(msg), msg);
|
|
617644
618452
|
return Boolean(resolvedReply?.sender?.isSelf);
|
|
617645
618453
|
}
|
|
617646
|
-
applyTelegramStimulationDecision(sessionKey,
|
|
618454
|
+
applyTelegramStimulationDecision(sessionKey, decision2) {
|
|
617647
618455
|
this.stimulation.applyAgentDecision(sessionKey, {
|
|
617648
|
-
shouldReply:
|
|
617649
|
-
phase:
|
|
617650
|
-
attentionDelta:
|
|
617651
|
-
attentionScore:
|
|
617652
|
-
nextAnalysisAfterMessages:
|
|
618456
|
+
shouldReply: decision2.shouldReply,
|
|
618457
|
+
phase: decision2.attentionState,
|
|
618458
|
+
attentionDelta: decision2.attentionDelta,
|
|
618459
|
+
attentionScore: decision2.attentionScore,
|
|
618460
|
+
nextAnalysisAfterMessages: decision2.nextCheckAfterMessages
|
|
617653
618461
|
});
|
|
617654
618462
|
}
|
|
617655
618463
|
async telegramRouterJsonCompletion(backend, request, diagnostics) {
|
|
@@ -618832,22 +619640,22 @@ Join: ${newUrl}`);
|
|
|
618832
619640
|
const isGroup = msg.chatType !== "private";
|
|
618833
619641
|
if (isGroup) {
|
|
618834
619642
|
const attentionViewId2 = this.registerTelegramAttentionView(msg, existing.toolContext || toolContext, "active Telegram thread");
|
|
618835
|
-
const
|
|
619643
|
+
const decision3 = await this.inferTelegramInteractionDecision(msg, existing.toolContext || toolContext);
|
|
618836
619644
|
this.deliverTelegramAttentionDecision(
|
|
618837
619645
|
sessionKey,
|
|
618838
619646
|
msg,
|
|
618839
619647
|
attentionViewId2,
|
|
618840
|
-
|
|
619648
|
+
decision3,
|
|
618841
619649
|
this.telegramMessageIdentitySalienceSignals(msg),
|
|
618842
619650
|
this.markLatestTelegramDaydreamOpportunitiesConsidered(sessionKey, msg)
|
|
618843
619651
|
);
|
|
618844
|
-
this.markLastTelegramUserMessageMode(msg,
|
|
619652
|
+
this.markLastTelegramUserMessageMode(msg, decision3.shouldReply ? "steering" : "ambient");
|
|
618845
619653
|
this.subAgentViewCallbacks?.onWrite(
|
|
618846
619654
|
existing.viewId,
|
|
618847
|
-
`live steering: ${
|
|
619655
|
+
`live steering: ${decision3.shouldReply ? decision3.route : "no_reply"} (${decision3.source}, confidence ${decision3.confidence.toFixed(2)}): ${decision3.reason}`
|
|
618848
619656
|
);
|
|
618849
|
-
if (!
|
|
618850
|
-
this.maybeLogTelegramGroupSkip(msg, `live inference: no steering — ${
|
|
619657
|
+
if (!decision3.shouldReply) {
|
|
619658
|
+
this.maybeLogTelegramGroupSkip(msg, `live inference: no steering — ${decision3.reason}`);
|
|
618851
619659
|
return;
|
|
618852
619660
|
}
|
|
618853
619661
|
}
|
|
@@ -618876,25 +619684,25 @@ Join: ${newUrl}`);
|
|
|
618876
619684
|
return;
|
|
618877
619685
|
}
|
|
618878
619686
|
const attentionViewId = this.registerTelegramAttentionView(msg, toolContext);
|
|
618879
|
-
const
|
|
619687
|
+
const decision2 = await this.inferTelegramInteractionDecision(msg, toolContext);
|
|
618880
619688
|
this.deliverTelegramAttentionDecision(
|
|
618881
619689
|
sessionKey,
|
|
618882
619690
|
msg,
|
|
618883
619691
|
attentionViewId,
|
|
618884
|
-
|
|
619692
|
+
decision2,
|
|
618885
619693
|
this.telegramMessageIdentitySalienceSignals(msg),
|
|
618886
619694
|
this.markLatestTelegramDaydreamOpportunitiesConsidered(sessionKey, msg)
|
|
618887
619695
|
);
|
|
618888
|
-
this.markLastTelegramUserMessageMode(msg,
|
|
619696
|
+
this.markLastTelegramUserMessageMode(msg, decision2.shouldReply ? decision2.route : "ambient");
|
|
618889
619697
|
this.subAgentViewCallbacks?.onWrite(
|
|
618890
619698
|
this.viewIdForMessage(msg),
|
|
618891
|
-
`live route: ${
|
|
619699
|
+
`live route: ${decision2.shouldReply ? decision2.route : "no_reply"} (${decision2.source}, confidence ${decision2.confidence.toFixed(2)}): ${decision2.reason}`
|
|
618892
619700
|
);
|
|
618893
|
-
if (!
|
|
618894
|
-
this.maybeLogTelegramGroupSkip(msg, `live inference: no reply — ${
|
|
619701
|
+
if (!decision2.shouldReply) {
|
|
619702
|
+
this.maybeLogTelegramGroupSkip(msg, `live inference: no reply — ${decision2.reason}`);
|
|
618895
619703
|
return;
|
|
618896
619704
|
}
|
|
618897
|
-
if (
|
|
619705
|
+
if (decision2.route === "chat") {
|
|
618898
619706
|
await this.handleTelegramChatCompletion(msg, toolContext);
|
|
618899
619707
|
return;
|
|
618900
619708
|
}
|
|
@@ -621211,12 +622019,12 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
621211
622019
|
};
|
|
621212
622020
|
});
|
|
621213
622021
|
const dryRun = effective.dryRunByDefault === true;
|
|
621214
|
-
const
|
|
622022
|
+
const requireAdmin2 = effective.requireAdminForMutation !== false;
|
|
621215
622023
|
const keyboard = [];
|
|
621216
622024
|
for (let idx = 0; idx < rows.length; idx += 2) keyboard.push(rows.slice(idx, idx + 2));
|
|
621217
622025
|
keyboard.push([
|
|
621218
622026
|
{ text: `${dryRun ? "[x]" : "[ ]"} Dry run`, callback_data: `omni:v1:tgtool:${state.nonce}:flag:dryrun` },
|
|
621219
|
-
{ text: `${
|
|
622027
|
+
{ text: `${requireAdmin2 ? "[x]" : "[ ]"} Admin mutations`, callback_data: `omni:v1:tgtool:${state.nonce}:flag:admin` }
|
|
621220
622028
|
]);
|
|
621221
622029
|
const scopeLabel = state.policyScope === "chat" ? `chat ${String(state.policyChatId)}` : "global";
|
|
621222
622030
|
return {
|
|
@@ -621567,12 +622375,12 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
621567
622375
|
return { success: true, output: `No recent ${kind} media is available in this Telegram chat scope.`, durationMs: performance.now() - start2 };
|
|
621568
622376
|
}
|
|
621569
622377
|
const lines = entries.map((entry, index) => {
|
|
621570
|
-
const pathAlias = entry.messageId ? `message_id:${entry.messageId}` :
|
|
622378
|
+
const pathAlias = entry.messageId ? `message_id:${entry.messageId}` : basename28(entry.localPath);
|
|
621571
622379
|
const parts = [
|
|
621572
622380
|
`${index + 1}. message_id ${entry.messageId || "unknown"}`,
|
|
621573
622381
|
currentMsg?.replyToMessageId === entry.messageId ? "replied-to" : "",
|
|
621574
622382
|
telegramCachedMediaIsImage(entry) ? "image" : telegramCachedMediaIsPdf(entry) ? "pdf" : telegramCachedMediaIsAudio(entry) ? "audio" : telegramCachedMediaIsVideo(entry) ? "video" : entry.mediaType,
|
|
621575
|
-
`file=${
|
|
622383
|
+
`file=${basename28(entry.localPath)}`,
|
|
621576
622384
|
`path_alias=${pathAlias}`,
|
|
621577
622385
|
entry.caption ? `caption=${telegramContextJsonString(entry.caption, 140)}` : ""
|
|
621578
622386
|
].filter(Boolean);
|
|
@@ -621699,8 +622507,8 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
621699
622507
|
if (bridge.telegramFileSendAlreadyDeliveredForMessage(currentMsg, sendFingerprint)) {
|
|
621700
622508
|
return {
|
|
621701
622509
|
success: true,
|
|
621702
|
-
output: `Telegram file already sent in this turn: ${
|
|
621703
|
-
llmContent: `Already sent ${
|
|
622510
|
+
output: `Telegram file already sent in this turn: ${basename28(file.path)} as ${kind} to ${String(target.chatId)}`,
|
|
622511
|
+
llmContent: `Already sent ${basename28(file.path)} to Telegram as ${kind}; do not send it again.`,
|
|
621704
622512
|
durationMs: performance.now() - start2,
|
|
621705
622513
|
mutated: false,
|
|
621706
622514
|
mutatedFiles: []
|
|
@@ -621717,8 +622525,8 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
621717
622525
|
bridge.rememberTelegramDeliveredArtifactForMessage(currentMsg, ledgerPath);
|
|
621718
622526
|
return {
|
|
621719
622527
|
success: true,
|
|
621720
|
-
output: `Sent Telegram file: ${
|
|
621721
|
-
llmContent: `Sent ${
|
|
622528
|
+
output: `Sent Telegram file: ${basename28(file.path)} as ${kind} to ${String(target.chatId)}${messageId ? ` (message_id ${messageId})` : ""}`,
|
|
622529
|
+
llmContent: `Sent ${basename28(file.path)} to Telegram as ${kind}.`,
|
|
621722
622530
|
durationMs: performance.now() - start2,
|
|
621723
622531
|
mutated: false,
|
|
621724
622532
|
mutatedFiles: []
|
|
@@ -622172,7 +622980,7 @@ ${text}`.trim());
|
|
|
622172
622980
|
if (!existsSync113(media.value)) throw new Error(`File does not exist: ${media.value}`);
|
|
622173
622981
|
const buffer2 = readFileSync92(media.value);
|
|
622174
622982
|
const boundary = `----omnius-media-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
622175
|
-
const filename =
|
|
622983
|
+
const filename = basename28(media.value);
|
|
622176
622984
|
const contentType = mimeForPath(media.value, media.kind);
|
|
622177
622985
|
const parts = [];
|
|
622178
622986
|
const addField = (name10, value2) => {
|
|
@@ -622412,7 +623220,7 @@ Content-Type: ${contentType}\r
|
|
|
622412
623220
|
continue;
|
|
622413
623221
|
}
|
|
622414
623222
|
const buffer2 = readFileSync92(pathOrFileId);
|
|
622415
|
-
const filename =
|
|
623223
|
+
const filename = basename28(pathOrFileId);
|
|
622416
623224
|
parts.push(Buffer.from(`--${boundary}\r
|
|
622417
623225
|
`));
|
|
622418
623226
|
parts.push(Buffer.from(
|
|
@@ -623514,7 +624322,7 @@ __export(projects_exports, {
|
|
|
623514
624322
|
});
|
|
623515
624323
|
import { readFileSync as readFileSync94, writeFileSync as writeFileSync61, mkdirSync as mkdirSync67, existsSync as existsSync115, statSync as statSync40, renameSync as renameSync7 } from "node:fs";
|
|
623516
624324
|
import { homedir as homedir42 } from "node:os";
|
|
623517
|
-
import { basename as
|
|
624325
|
+
import { basename as basename29, join as join129, resolve as resolve44 } from "node:path";
|
|
623518
624326
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
623519
624327
|
function readAll2() {
|
|
623520
624328
|
try {
|
|
@@ -623562,7 +624370,7 @@ function registerProject(root, pid) {
|
|
|
623562
624370
|
} else {
|
|
623563
624371
|
entry = {
|
|
623564
624372
|
root: canonical,
|
|
623565
|
-
name:
|
|
624373
|
+
name: basename29(canonical) || canonical,
|
|
623566
624374
|
firstSeen: now,
|
|
623567
624375
|
lastSeen: now,
|
|
623568
624376
|
pid: pid ?? null,
|
|
@@ -626937,6 +627745,8 @@ async function tryRouteV1(ctx3) {
|
|
|
626937
627745
|
if (pathname === "/v1/tor/status" && method === "GET") return handleTorStatus(ctx3);
|
|
626938
627746
|
if (pathname === "/v1/tor/enable" && method === "POST") return handleTorEnable(ctx3);
|
|
626939
627747
|
if (pathname === "/v1/tor/disable" && method === "POST") return handleTorDisable(ctx3);
|
|
627748
|
+
if (pathname === "/v1/ollama/pool/processes" && method === "GET") return handleOllamaPoolProcesses(ctx3);
|
|
627749
|
+
if (pathname === "/v1/ollama/pool/cleanup" && method === "POST") return handleOllamaPoolCleanup(ctx3);
|
|
626940
627750
|
if (pathname === "/v1/tools" && method === "GET") {
|
|
626941
627751
|
return handleListTools(ctx3);
|
|
626942
627752
|
}
|
|
@@ -627282,6 +628092,109 @@ async function handleCallMcp(ctx3, name10) {
|
|
|
627282
628092
|
return true;
|
|
627283
628093
|
}
|
|
627284
628094
|
}
|
|
628095
|
+
function requestScope(ctx3) {
|
|
628096
|
+
const reqAuth = ctx3.req;
|
|
628097
|
+
return ctx3.scope ?? reqAuth._authScope ?? "read";
|
|
628098
|
+
}
|
|
628099
|
+
function requestOrigin(ctx3) {
|
|
628100
|
+
const remoteIp = (ctx3.req.socket?.remoteAddress || "").replace(/^::ffff:/, "");
|
|
628101
|
+
return /^(127\.\d+\.\d+\.\d+|::1|localhost)$/.test(remoteIp) ? "loopback" : "remote";
|
|
628102
|
+
}
|
|
628103
|
+
function requireAdmin(ctx3, detail) {
|
|
628104
|
+
if (requestScope(ctx3) === "admin") return true;
|
|
628105
|
+
sendProblem(ctx3.res, problemDetails({
|
|
628106
|
+
type: P.forbidden,
|
|
628107
|
+
status: 403,
|
|
628108
|
+
title: "Admin scope required",
|
|
628109
|
+
detail,
|
|
628110
|
+
instance: ctx3.requestId
|
|
628111
|
+
}));
|
|
628112
|
+
return false;
|
|
628113
|
+
}
|
|
628114
|
+
async function buildOllamaCleanupPoolStatus(mod2) {
|
|
628115
|
+
try {
|
|
628116
|
+
const poolConfig = mod2.resolveDefaultPoolConfig();
|
|
628117
|
+
if (!mod2.shouldUseOllamaPoolForBaseUrl(poolConfig.baseInstanceUrl)) return null;
|
|
628118
|
+
return await mod2.getOllamaPool({ baseInstanceUrl: poolConfig.baseInstanceUrl }).status();
|
|
628119
|
+
} catch {
|
|
628120
|
+
return null;
|
|
628121
|
+
}
|
|
628122
|
+
}
|
|
628123
|
+
async function handleOllamaPoolProcesses(ctx3) {
|
|
628124
|
+
if (!requireAdmin(ctx3, "Ollama process inventory exposes local PIDs and ports.")) return true;
|
|
628125
|
+
const { res, requestId } = ctx3;
|
|
628126
|
+
try {
|
|
628127
|
+
const mod2 = await Promise.resolve().then(() => (init_dist8(), dist_exports3));
|
|
628128
|
+
const poolConfig = mod2.resolveDefaultPoolConfig();
|
|
628129
|
+
const poolStatus = await buildOllamaCleanupPoolStatus(mod2);
|
|
628130
|
+
const report2 = await mod2.scanOllamaProcesses({
|
|
628131
|
+
baseInstanceUrl: poolConfig.baseInstanceUrl,
|
|
628132
|
+
poolPortStart: poolConfig.spawnPortStart,
|
|
628133
|
+
poolStatus
|
|
628134
|
+
});
|
|
628135
|
+
sendJson(res, 200, report2);
|
|
628136
|
+
return true;
|
|
628137
|
+
} catch (err) {
|
|
628138
|
+
sendProblem(res, problemDetails({
|
|
628139
|
+
type: P.internalError,
|
|
628140
|
+
status: 500,
|
|
628141
|
+
title: "Ollama process scan failed",
|
|
628142
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
628143
|
+
instance: requestId
|
|
628144
|
+
}));
|
|
628145
|
+
return true;
|
|
628146
|
+
}
|
|
628147
|
+
}
|
|
628148
|
+
async function handleOllamaPoolCleanup(ctx3) {
|
|
628149
|
+
if (!requireAdmin(ctx3, "Cleaning stale Ollama processes requires admin scope.")) return true;
|
|
628150
|
+
if (requestOrigin(ctx3) !== "loopback") {
|
|
628151
|
+
sendProblem(ctx3.res, problemDetails({
|
|
628152
|
+
type: P.forbidden,
|
|
628153
|
+
status: 403,
|
|
628154
|
+
title: "Loopback required",
|
|
628155
|
+
detail: "Ollama process cleanup may only be requested from loopback.",
|
|
628156
|
+
instance: ctx3.requestId
|
|
628157
|
+
}));
|
|
628158
|
+
return true;
|
|
628159
|
+
}
|
|
628160
|
+
const { req: req2, res, requestId, user } = ctx3;
|
|
628161
|
+
try {
|
|
628162
|
+
const body = await parseJsonBodyStrict(req2).catch(() => ({}));
|
|
628163
|
+
const mod2 = await Promise.resolve().then(() => (init_dist8(), dist_exports3));
|
|
628164
|
+
const poolConfig = mod2.resolveDefaultPoolConfig();
|
|
628165
|
+
const poolStatus = await buildOllamaCleanupPoolStatus(mod2);
|
|
628166
|
+
const dryRun = body["dry_run"] === false ? false : true;
|
|
628167
|
+
const useInferenceRaw = body["use_inference"];
|
|
628168
|
+
const useInference = useInferenceRaw === false ? false : useInferenceRaw === true ? true : "auto";
|
|
628169
|
+
const report2 = await mod2.cleanupStaleOllamaProcesses({
|
|
628170
|
+
dryRun,
|
|
628171
|
+
useInference,
|
|
628172
|
+
baseInstanceUrl: poolConfig.baseInstanceUrl,
|
|
628173
|
+
poolPortStart: poolConfig.spawnPortStart,
|
|
628174
|
+
poolStatus
|
|
628175
|
+
});
|
|
628176
|
+
publishEvent("ollama.pool.cleanup", {
|
|
628177
|
+
dry_run: report2.dryRun,
|
|
628178
|
+
used_inference: report2.usedInference,
|
|
628179
|
+
terminated: report2.terminated.length,
|
|
628180
|
+
errors: report2.errors.length
|
|
628181
|
+
}, {
|
|
628182
|
+
subject: user ?? "anonymous",
|
|
628183
|
+
aimsControl: "A.6.2.6"
|
|
628184
|
+
});
|
|
628185
|
+
sendJson(res, 200, report2);
|
|
628186
|
+
return true;
|
|
628187
|
+
} catch (err) {
|
|
628188
|
+
sendProblem(res, problemDetails({
|
|
628189
|
+
type: P.internalError,
|
|
628190
|
+
status: 500,
|
|
628191
|
+
title: "Ollama process cleanup failed",
|
|
628192
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
628193
|
+
instance: requestId
|
|
628194
|
+
}));
|
|
628195
|
+
return true;
|
|
628196
|
+
}
|
|
628197
|
+
}
|
|
627285
628198
|
function memoryDbPaths2(baseDir = process.cwd()) {
|
|
627286
628199
|
const dir = join136(baseDir, ".omnius");
|
|
627287
628200
|
return {
|
|
@@ -638353,6 +639266,7 @@ function getOpenApiSpec() {
|
|
|
638353
639266
|
{ name: "Sessions", description: "Omnius task session archive" },
|
|
638354
639267
|
{ name: "Context", description: "Session context save/restore/compact" },
|
|
638355
639268
|
{ name: "Nexus", description: "P2P peer mesh and sponsor directory" },
|
|
639269
|
+
{ name: "Ollama", description: "Local Ollama pool status and process hygiene" },
|
|
638356
639270
|
{ name: "Tools", description: "Agentic tool registry" },
|
|
638357
639271
|
{ name: "Engines", description: "Long-running TUI engines (dream, bless, call, listen, telegram, expose)" },
|
|
638358
639272
|
{ name: "Voice", description: "TTS / ASR / voice-clone pipeline. REST surface for synthesis (/v1/voice/tts) and transcription (/v1/voice/transcribe), full-duplex voicechat over WebSocket (/v1/voicechat/ws), and clone reference management (upload/from-URL/multipart/raw)." },
|
|
@@ -638515,6 +639429,23 @@ function getOpenApiSpec() {
|
|
|
638515
639429
|
}
|
|
638516
639430
|
},
|
|
638517
639431
|
"/v1/system": { get: { summary: "System info + GPU/RAM/CPU", tags: ["Metering"], responses: { 200: { description: "System snapshot" } } } },
|
|
639432
|
+
"/v1/ollama/pool/processes": {
|
|
639433
|
+
get: {
|
|
639434
|
+
summary: "Scan local Ollama pool processes",
|
|
639435
|
+
tags: ["Ollama"],
|
|
639436
|
+
description: "Admin-scope inventory of local `ollama serve` PIDs, listening ports, protected base-service classification, and stale pool cleanup decisions. This endpoint does not terminate processes.",
|
|
639437
|
+
responses: { 200: { description: "Ollama process scan report" }, ...ErrorResponses }
|
|
639438
|
+
}
|
|
639439
|
+
},
|
|
639440
|
+
"/v1/ollama/pool/cleanup": {
|
|
639441
|
+
post: {
|
|
639442
|
+
summary: "Clean up stale Ollama pool processes",
|
|
639443
|
+
tags: ["Ollama"],
|
|
639444
|
+
description: "Loopback/admin-only guarded cleanup. Defaults to dry_run=true. Body: {dry_run?: boolean, use_inference?: boolean}. Hard rules always protect port 11434, the configured base port, systemd ollama.service, and live tracked pool runners.",
|
|
639445
|
+
requestBody: { required: false, content: { "application/json": { schema: { type: "object", properties: { dry_run: { type: "boolean", default: true }, use_inference: { type: "boolean", default: true } } } } } },
|
|
639446
|
+
responses: { 200: { description: "Cleanup report" }, ...ErrorResponses }
|
|
639447
|
+
}
|
|
639448
|
+
},
|
|
638518
639449
|
// ───── PT-02: Skills ─────
|
|
638519
639450
|
"/v1/skills": {
|
|
638520
639451
|
get: {
|
|
@@ -639696,7 +640627,7 @@ __export(embedding_workers_exports, {
|
|
|
639696
640627
|
startEmbeddingWorkers: () => startEmbeddingWorkers,
|
|
639697
640628
|
stopEmbeddingWorkers: () => stopEmbeddingWorkers
|
|
639698
640629
|
});
|
|
639699
|
-
import { basename as
|
|
640630
|
+
import { basename as basename30, join as join140 } from "node:path";
|
|
639700
640631
|
function startEmbeddingWorkers(opts) {
|
|
639701
640632
|
if (_running) return;
|
|
639702
640633
|
_running = true;
|
|
@@ -639762,7 +640693,7 @@ async function runEmbeddingTask(modality, episodeId, taskId, opts) {
|
|
|
639762
640693
|
try {
|
|
639763
640694
|
if (!_aligner) {
|
|
639764
640695
|
const stateRoot = process.env.OMNIUS_DIR || process.cwd();
|
|
639765
|
-
const omniusDir =
|
|
640696
|
+
const omniusDir = basename30(stateRoot) === ".omnius" ? stateRoot : join140(stateRoot, ".omnius");
|
|
639766
640697
|
const memDir = join140(omniusDir, "memory");
|
|
639767
640698
|
_aligner = new EmbeddingAligner(
|
|
639768
640699
|
`${modality}-${emb.length}`,
|