omnius 1.0.368 → 1.0.369
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 +811 -282
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9629,6 +9629,14 @@ var init_vision = __esm({
|
|
|
9629
9629
|
type: "string",
|
|
9630
9630
|
description: "Path to the image file (PNG, JPG, GIF, WebP, BMP, TIFF)"
|
|
9631
9631
|
},
|
|
9632
|
+
path: {
|
|
9633
|
+
type: "string",
|
|
9634
|
+
description: "Alias for image path"
|
|
9635
|
+
},
|
|
9636
|
+
file: {
|
|
9637
|
+
type: "string",
|
|
9638
|
+
description: "Alias for image path"
|
|
9639
|
+
},
|
|
9632
9640
|
action: {
|
|
9633
9641
|
type: "string",
|
|
9634
9642
|
enum: ["caption", "query", "detect", "point"],
|
|
@@ -9664,13 +9672,13 @@ var init_vision = __esm({
|
|
|
9664
9672
|
}
|
|
9665
9673
|
async execute(args) {
|
|
9666
9674
|
const start2 = performance.now();
|
|
9667
|
-
const rawPath = args["image"];
|
|
9675
|
+
const rawPath = args["image"] ?? args["path"] ?? args["file"];
|
|
9668
9676
|
const action = args["action"] ?? "caption";
|
|
9669
9677
|
const prompt = args["prompt"];
|
|
9670
9678
|
const length4 = args["length"] ?? "normal";
|
|
9671
9679
|
const preferredModel = normalizeVisionModelName(args["model"]);
|
|
9672
9680
|
if (!rawPath) {
|
|
9673
|
-
return { success: false, output: "", error: "image path is required", durationMs: 0 };
|
|
9681
|
+
return { success: false, output: "", error: "image path is required (accepted keys: image, path, file)", durationMs: 0 };
|
|
9674
9682
|
}
|
|
9675
9683
|
if ((action === "query" || action === "detect" || action === "point") && !prompt) {
|
|
9676
9684
|
return {
|
|
@@ -35488,11 +35496,13 @@ var init_image = __esm({
|
|
|
35488
35496
|
ImageReadTool = class {
|
|
35489
35497
|
workingDir;
|
|
35490
35498
|
name = "image_read";
|
|
35491
|
-
description = "Read an image file and return its base64 encoding, dimensions, and OCR text extraction. The base64 data can be used for multimodal model input. Supports: PNG, JPG, GIF, WebP, BMP, TIFF, SVG.";
|
|
35499
|
+
description = "Read an image file and return its base64 encoding, dimensions, and OCR text extraction. The base64 data can be used for multimodal model input. For semantic visual understanding, object/person identification, or captions, prefer vision first (Moondream) and use image_read for metadata/OCR/raw image ingress. Supports: PNG, JPG, GIF, WebP, BMP, TIFF, SVG.";
|
|
35492
35500
|
parameters = {
|
|
35493
35501
|
type: "object",
|
|
35494
35502
|
properties: {
|
|
35495
35503
|
path: { type: "string", description: "Path to the image file" },
|
|
35504
|
+
file: { type: "string", description: "Alias for path" },
|
|
35505
|
+
image: { type: "string", description: "Alias for path" },
|
|
35496
35506
|
ocr: { type: "boolean", description: "Extract text via OCR (default: true if tesseract available)" },
|
|
35497
35507
|
max_size_kb: { type: "number", description: "Maximum file size in KB to read (default: 10240 = 10MB)" }
|
|
35498
35508
|
},
|
|
@@ -35503,11 +35513,11 @@ var init_image = __esm({
|
|
|
35503
35513
|
}
|
|
35504
35514
|
async execute(args) {
|
|
35505
35515
|
const start2 = Date.now();
|
|
35506
|
-
const rawPath = String(args["path"] ?? "");
|
|
35516
|
+
const rawPath = String(args["path"] ?? args["file"] ?? args["image"] ?? "");
|
|
35507
35517
|
const doOcr = args["ocr"] !== false;
|
|
35508
35518
|
const maxSizeKb = typeof args["max_size_kb"] === "number" ? args["max_size_kb"] : 10240;
|
|
35509
35519
|
if (!rawPath) {
|
|
35510
|
-
return { success: false, output: "", error: "path is required", durationMs: 0 };
|
|
35520
|
+
return { success: false, output: "", error: "path is required (accepted keys: path, file, image)", durationMs: 0 };
|
|
35511
35521
|
}
|
|
35512
35522
|
const fullPath = resolve19(this.workingDir, rawPath);
|
|
35513
35523
|
if (!existsSync31(fullPath)) {
|
|
@@ -269267,8 +269277,8 @@ var require_pattern = __commonJS({
|
|
|
269267
269277
|
}
|
|
269268
269278
|
exports.endsWithSlashGlobStar = endsWithSlashGlobStar;
|
|
269269
269279
|
function isAffectDepthOfReadingPattern(pattern) {
|
|
269270
|
-
const
|
|
269271
|
-
return endsWithSlashGlobStar(pattern) || isStaticPattern(
|
|
269280
|
+
const basename40 = path12.basename(pattern);
|
|
269281
|
+
return endsWithSlashGlobStar(pattern) || isStaticPattern(basename40);
|
|
269272
269282
|
}
|
|
269273
269283
|
exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
|
|
269274
269284
|
function expandPatternsWithBraceExpansion(patterns) {
|
|
@@ -273144,7 +273154,7 @@ print("${sentinel}")
|
|
|
273144
273154
|
if (!this.proc || this.proc.killed) {
|
|
273145
273155
|
return { success: false, path: "" };
|
|
273146
273156
|
}
|
|
273147
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
273157
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
273148
273158
|
const sessionDir2 = join43(this.cwd, ".omnius", "rlm");
|
|
273149
273159
|
mkdirSync106(sessionDir2, { recursive: true });
|
|
273150
273160
|
const sessionPath2 = join43(sessionDir2, "session.json");
|
|
@@ -273170,7 +273180,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
273170
273180
|
trajectoryCount: this.trajectory.length,
|
|
273171
273181
|
subCallCount: this.subCallCount
|
|
273172
273182
|
};
|
|
273173
|
-
|
|
273183
|
+
writeFileSync90(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
|
|
273174
273184
|
return { success: true, path: sessionPath2 };
|
|
273175
273185
|
}
|
|
273176
273186
|
} catch {
|
|
@@ -273789,7 +273799,7 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
273789
273799
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
273790
273800
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
273791
273801
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
273792
|
-
const { readFileSync: readFileSync133, writeFileSync:
|
|
273802
|
+
const { readFileSync: readFileSync133, writeFileSync: writeFileSync90, existsSync: existsSync164, mkdirSync: mkdirSync106 } = __require("node:fs");
|
|
273793
273803
|
const metaDir = join44(this.cwd, ".omnius", "memory", "metabolism");
|
|
273794
273804
|
const storeFile = join44(metaDir, "store.json");
|
|
273795
273805
|
if (!existsSync164(storeFile))
|
|
@@ -273821,7 +273831,7 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
273821
273831
|
}
|
|
273822
273832
|
if (updated) {
|
|
273823
273833
|
mkdirSync106(metaDir, { recursive: true });
|
|
273824
|
-
|
|
273834
|
+
writeFileSync90(storeFile, JSON.stringify(store2, null, 2));
|
|
273825
273835
|
}
|
|
273826
273836
|
}
|
|
273827
273837
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -274267,7 +274277,7 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
274267
274277
|
}
|
|
274268
274278
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
274269
274279
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
274270
|
-
const { readFileSync: readFileSync133, writeFileSync:
|
|
274280
|
+
const { readFileSync: readFileSync133, writeFileSync: writeFileSync90, existsSync: existsSync164, mkdirSync: mkdirSync106 } = __require("node:fs");
|
|
274271
274281
|
const dir = join46(this.cwd, ".omnius", "arche");
|
|
274272
274282
|
const archiveFile = join46(dir, "variants.json");
|
|
274273
274283
|
let variants = [];
|
|
@@ -274289,7 +274299,7 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
274289
274299
|
if (variants.length > 50)
|
|
274290
274300
|
variants = variants.slice(-50);
|
|
274291
274301
|
mkdirSync106(dir, { recursive: true });
|
|
274292
|
-
|
|
274302
|
+
writeFileSync90(archiveFile, JSON.stringify(variants, null, 2));
|
|
274293
274303
|
}
|
|
274294
274304
|
async saveArchive(variants) {
|
|
274295
274305
|
const dir = join46(this.cwd, ".omnius", "arche");
|
|
@@ -321828,9 +321838,9 @@ ${lanes.join("\n")}
|
|
|
321828
321838
|
function isJsonEqual(a2, b) {
|
|
321829
321839
|
return a2 === b || typeof a2 === "object" && a2 !== null && typeof b === "object" && b !== null && equalOwnProperties(a2, b, isJsonEqual);
|
|
321830
321840
|
}
|
|
321831
|
-
function parsePseudoBigInt(
|
|
321841
|
+
function parsePseudoBigInt(stringValue3) {
|
|
321832
321842
|
let log2Base;
|
|
321833
|
-
switch (
|
|
321843
|
+
switch (stringValue3.charCodeAt(1)) {
|
|
321834
321844
|
// "x" in "0x123"
|
|
321835
321845
|
case 98:
|
|
321836
321846
|
case 66:
|
|
@@ -321845,19 +321855,19 @@ ${lanes.join("\n")}
|
|
|
321845
321855
|
log2Base = 4;
|
|
321846
321856
|
break;
|
|
321847
321857
|
default:
|
|
321848
|
-
const nIndex =
|
|
321858
|
+
const nIndex = stringValue3.length - 1;
|
|
321849
321859
|
let nonZeroStart = 0;
|
|
321850
|
-
while (
|
|
321860
|
+
while (stringValue3.charCodeAt(nonZeroStart) === 48) {
|
|
321851
321861
|
nonZeroStart++;
|
|
321852
321862
|
}
|
|
321853
|
-
return
|
|
321863
|
+
return stringValue3.slice(nonZeroStart, nIndex) || "0";
|
|
321854
321864
|
}
|
|
321855
|
-
const startIndex = 2, endIndex =
|
|
321865
|
+
const startIndex = 2, endIndex = stringValue3.length - 1;
|
|
321856
321866
|
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
|
321857
321867
|
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
|
321858
321868
|
for (let i2 = endIndex - 1, bitOffset = 0; i2 >= startIndex; i2--, bitOffset += log2Base) {
|
|
321859
321869
|
const segment = bitOffset >>> 4;
|
|
321860
|
-
const digitChar =
|
|
321870
|
+
const digitChar = stringValue3.charCodeAt(i2);
|
|
321861
321871
|
const digit = digitChar <= 57 ? digitChar - 48 : 10 + digitChar - (digitChar <= 70 ? 65 : 97);
|
|
321862
321872
|
const shiftedDigit = digit << (bitOffset & 15);
|
|
321863
321873
|
segments[segment] |= shiftedDigit;
|
|
@@ -435385,9 +435395,9 @@ ${lanes.join("\n")}
|
|
|
435385
435395
|
/*ignoreCase*/
|
|
435386
435396
|
false
|
|
435387
435397
|
)) {
|
|
435388
|
-
const
|
|
435389
|
-
if (
|
|
435390
|
-
const name10 = removeSuffix(removePrefix(
|
|
435398
|
+
const basename40 = getBaseFileName(a2.fileName);
|
|
435399
|
+
if (basename40 === "lib.d.ts" || basename40 === "lib.es6.d.ts") return 0;
|
|
435400
|
+
const name10 = removeSuffix(removePrefix(basename40, "lib."), ".d.ts");
|
|
435391
435401
|
const index = libs.indexOf(name10);
|
|
435392
435402
|
if (index !== -1) return index + 1;
|
|
435393
435403
|
}
|
|
@@ -499313,8 +499323,8 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
499313
499323
|
}
|
|
499314
499324
|
};
|
|
499315
499325
|
for (const file of files) {
|
|
499316
|
-
const
|
|
499317
|
-
if (
|
|
499326
|
+
const basename40 = getBaseFileName(file);
|
|
499327
|
+
if (basename40 === "package.json" || basename40 === "bower.json") {
|
|
499318
499328
|
createProjectWatcher(
|
|
499319
499329
|
file,
|
|
499320
499330
|
"FileWatcher"
|
|
@@ -502998,8 +503008,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
502998
503008
|
var _a;
|
|
502999
503009
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
503000
503010
|
if (!fileOrDirectoryPath) return;
|
|
503001
|
-
const
|
|
503002
|
-
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (
|
|
503011
|
+
const basename40 = getBaseFileName(fileOrDirectoryPath);
|
|
503012
|
+
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename40 === "package.json" || basename40 === "node_modules")) {
|
|
503003
503013
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
503004
503014
|
var _a2;
|
|
503005
503015
|
(_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
|
|
@@ -511902,7 +511912,7 @@ var require_path_browserify = __commonJS({
|
|
|
511902
511912
|
if (hasRoot && end === 1) return "//";
|
|
511903
511913
|
return path12.slice(0, end);
|
|
511904
511914
|
},
|
|
511905
|
-
basename: function
|
|
511915
|
+
basename: function basename40(path12, ext) {
|
|
511906
511916
|
if (ext !== void 0 && typeof ext !== "string") throw new TypeError('"ext" argument must be a string');
|
|
511907
511917
|
assertPath(path12);
|
|
511908
511918
|
var start2 = 0;
|
|
@@ -546587,7 +546597,57 @@ function visualMemoryPythonEnv(extra = {}) {
|
|
|
546587
546597
|
applyMediaCudaDeviceFilterToEnv(env2, "vision");
|
|
546588
546598
|
return env2;
|
|
546589
546599
|
}
|
|
546590
|
-
|
|
546600
|
+
function stringArg2(args, ...keys) {
|
|
546601
|
+
for (const key of keys) {
|
|
546602
|
+
const value2 = args[key];
|
|
546603
|
+
if (typeof value2 === "string" && value2.trim())
|
|
546604
|
+
return value2.trim();
|
|
546605
|
+
}
|
|
546606
|
+
return "";
|
|
546607
|
+
}
|
|
546608
|
+
function stringListArg(value2) {
|
|
546609
|
+
if (Array.isArray(value2)) {
|
|
546610
|
+
return value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
|
|
546611
|
+
}
|
|
546612
|
+
if (typeof value2 === "string" && value2.trim())
|
|
546613
|
+
return [value2.trim()];
|
|
546614
|
+
return [];
|
|
546615
|
+
}
|
|
546616
|
+
function imagePathArg(args) {
|
|
546617
|
+
return stringArg2(args, "image", "path", "file", "media");
|
|
546618
|
+
}
|
|
546619
|
+
function associationLabelArg(args) {
|
|
546620
|
+
return stringArg2(args, "name", "label", "title", "object", "person") || stringListArg(args["labels"])[0] || stringListArg(args["aliases"])[0] || "";
|
|
546621
|
+
}
|
|
546622
|
+
function pyLiteral(value2) {
|
|
546623
|
+
return JSON.stringify(value2);
|
|
546624
|
+
}
|
|
546625
|
+
function normalizeVisualMemoryAction(args) {
|
|
546626
|
+
const raw = stringArg2(args, "action").toLowerCase();
|
|
546627
|
+
if (!raw) {
|
|
546628
|
+
if (imagePathArg(args) && associationLabelArg(args))
|
|
546629
|
+
return "teach";
|
|
546630
|
+
if (imagePathArg(args))
|
|
546631
|
+
return "recognize";
|
|
546632
|
+
return "";
|
|
546633
|
+
}
|
|
546634
|
+
if (raw === "learn" || raw === "remember" || raw === "associate")
|
|
546635
|
+
return "teach";
|
|
546636
|
+
if (raw === "score" || raw === "classify")
|
|
546637
|
+
return "describe";
|
|
546638
|
+
return raw;
|
|
546639
|
+
}
|
|
546640
|
+
function summarizeProcessFailure(stdout, stderr) {
|
|
546641
|
+
const normalize2 = (text2) => text2.replace(/\r/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
546642
|
+
const lines = [
|
|
546643
|
+
...normalize2(stderr).map((line) => `stderr: ${line}`),
|
|
546644
|
+
...normalize2(stdout).map((line) => `stdout: ${line}`)
|
|
546645
|
+
];
|
|
546646
|
+
if (lines.length === 0)
|
|
546647
|
+
return "Vision ML script failed";
|
|
546648
|
+
return lines.slice(-24).join("\n").slice(-1800);
|
|
546649
|
+
}
|
|
546650
|
+
var VMEM_DIR, VENV_DIR2, VENV_PY, VENV_PIP2, VISUAL_MEMORY_ACTIONS, VisualMemoryTool;
|
|
546591
546651
|
var init_visual_memory = __esm({
|
|
546592
546652
|
"packages/execution/dist/tools/visual-memory.js"() {
|
|
546593
546653
|
"use strict";
|
|
@@ -546596,24 +546656,45 @@ var init_visual_memory = __esm({
|
|
|
546596
546656
|
VENV_DIR2 = join80(homedir20(), ".omnius", "vision-ml-venv");
|
|
546597
546657
|
VENV_PY = join80(VENV_DIR2, "bin", "python3");
|
|
546598
546658
|
VENV_PIP2 = join80(VENV_DIR2, "bin", "pip");
|
|
546659
|
+
VISUAL_MEMORY_ACTIONS = /* @__PURE__ */ new Set(["detect", "enroll", "identify", "teach", "recognize", "describe", "list", "forget"]);
|
|
546599
546660
|
VisualMemoryTool = class {
|
|
546600
546661
|
name = "visual_memory";
|
|
546601
|
-
description = "Persistent visual memory —
|
|
546662
|
+
description = "Persistent visual memory — automatically associate names/labels with images and recognize familiar faces/objects across sessions. When a user, filename, manifest, or surrounding text provides a name or label for a new image, call teach/enroll immediately to store that association. If an image is unlabeled, call vision first for a Moondream caption, then recognize/identify against this memory; ask the user for a label only when the identity is still unknown. FACE actions: 'detect' faces in image, 'enroll' a person (name + photo), 'identify' known faces. OBJECT actions: 'teach' an object (label + photo), 'recognize' taught objects, 'describe' CLIP scores for candidate labels. MEMORY actions: 'list' all enrolled faces/objects, 'forget' a person/object. Use this to remember people, learn to recognize tools/items, and build persistent visual knowledge about the physical environment. Works with camera_capture output.";
|
|
546602
546663
|
parameters = {
|
|
546603
546664
|
type: "object",
|
|
546604
546665
|
properties: {
|
|
546605
546666
|
action: {
|
|
546606
546667
|
type: "string",
|
|
546607
|
-
enum: ["detect", "enroll", "identify", "teach", "recognize", "list", "forget"],
|
|
546608
|
-
description: "Action: detect/enroll/identify faces, teach/recognize objects, list/forget memory"
|
|
546668
|
+
enum: ["detect", "enroll", "identify", "teach", "recognize", "describe", "list", "forget"],
|
|
546669
|
+
description: "Action: detect/enroll/identify faces, teach/recognize/describe objects, list/forget memory. If omitted with image+label/name, teach is inferred; with image only, recognize is inferred."
|
|
546609
546670
|
},
|
|
546610
546671
|
image: {
|
|
546611
546672
|
type: "string",
|
|
546612
|
-
description: "Path to image file (JPEG/PNG). Required for detect/enroll/identify/teach/recognize."
|
|
546673
|
+
description: "Path to image file (JPEG/PNG). Required for detect/enroll/identify/teach/recognize/describe."
|
|
546674
|
+
},
|
|
546675
|
+
path: {
|
|
546676
|
+
type: "string",
|
|
546677
|
+
description: "Alias for image path."
|
|
546678
|
+
},
|
|
546679
|
+
file: {
|
|
546680
|
+
type: "string",
|
|
546681
|
+
description: "Alias for image path."
|
|
546682
|
+
},
|
|
546683
|
+
media: {
|
|
546684
|
+
type: "string",
|
|
546685
|
+
description: "Alias for image path."
|
|
546613
546686
|
},
|
|
546614
546687
|
name: {
|
|
546615
546688
|
type: "string",
|
|
546616
|
-
description: "Person name (for 'enroll') or object label (for 'teach').
|
|
546689
|
+
description: "Person name (for 'enroll') or object label (for 'teach')."
|
|
546690
|
+
},
|
|
546691
|
+
label: {
|
|
546692
|
+
type: "string",
|
|
546693
|
+
description: "Alias for name when teaching an object or enrolling a person from an associated label."
|
|
546694
|
+
},
|
|
546695
|
+
title: {
|
|
546696
|
+
type: "string",
|
|
546697
|
+
description: "Alias for name/label when a manifest or metadata title identifies the visual subject."
|
|
546617
546698
|
},
|
|
546618
546699
|
id: {
|
|
546619
546700
|
type: "string",
|
|
@@ -546630,15 +546711,23 @@ var init_visual_memory = __esm({
|
|
|
546630
546711
|
},
|
|
546631
546712
|
labels: {
|
|
546632
546713
|
type: "array",
|
|
546633
|
-
description: "
|
|
546714
|
+
description: "Candidate text labels to score against image for CLIP recognize/describe. For teach, labels[0] is accepted as the object label when name/label is omitted.",
|
|
546715
|
+
items: { type: "string" }
|
|
546716
|
+
},
|
|
546717
|
+
aliases: {
|
|
546718
|
+
type: "array",
|
|
546719
|
+
description: "Additional label aliases. aliases[0] is accepted as the primary label when name/label/labels are omitted.",
|
|
546634
546720
|
items: { type: "string" }
|
|
546635
546721
|
}
|
|
546636
546722
|
},
|
|
546637
|
-
required: [
|
|
546723
|
+
required: []
|
|
546638
546724
|
};
|
|
546639
546725
|
async execute(args) {
|
|
546640
|
-
const action = args
|
|
546726
|
+
const action = normalizeVisualMemoryAction(args);
|
|
546641
546727
|
const start2 = performance.now();
|
|
546728
|
+
if (!VISUAL_MEMORY_ACTIONS.has(action)) {
|
|
546729
|
+
return { success: false, output: "", error: `Unknown action: ${action || "(none)"}. Use teach with image+name/label to remember, recognize with image to recall, or vision first for unlabeled semantic captioning.`, durationMs: performance.now() - start2 };
|
|
546730
|
+
}
|
|
546642
546731
|
if (!await this.ensureVenv()) {
|
|
546643
546732
|
return { success: false, output: "", error: "Could not set up vision ML environment. Needs Python 3.10+.", durationMs: performance.now() - start2 };
|
|
546644
546733
|
}
|
|
@@ -546656,6 +546745,11 @@ var init_visual_memory = __esm({
|
|
|
546656
546745
|
return await this.teachObject(args, start2);
|
|
546657
546746
|
case "recognize":
|
|
546658
546747
|
return await this.recognizeObjects(args, start2);
|
|
546748
|
+
case "describe":
|
|
546749
|
+
return await this.recognizeObjects({
|
|
546750
|
+
...args,
|
|
546751
|
+
threshold: typeof args["threshold"] === "number" ? args["threshold"] : -1
|
|
546752
|
+
}, start2);
|
|
546659
546753
|
case "list":
|
|
546660
546754
|
return await this.listMemory(start2);
|
|
546661
546755
|
case "forget":
|
|
@@ -546671,7 +546765,7 @@ var init_visual_memory = __esm({
|
|
|
546671
546765
|
// Face Detection
|
|
546672
546766
|
// =========================================================================
|
|
546673
546767
|
async detectFaces(args, start2) {
|
|
546674
|
-
const image = args
|
|
546768
|
+
const image = imagePathArg(args);
|
|
546675
546769
|
if (!image || !existsSync66(image)) {
|
|
546676
546770
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546677
546771
|
}
|
|
@@ -546684,7 +546778,7 @@ app = FaceAnalysis(name='buffalo_s', providers=['CUDAExecutionProvider', 'CPUExe
|
|
|
546684
546778
|
app.prepare(ctx_id=0, det_size=(640, 640))
|
|
546685
546779
|
|
|
546686
546780
|
import cv2
|
|
546687
|
-
img = cv2.imread(
|
|
546781
|
+
img = cv2.imread(${pyLiteral(image)})
|
|
546688
546782
|
if img is None:
|
|
546689
546783
|
print(json.dumps({"success": False, "error": "Could not read image"}))
|
|
546690
546784
|
sys.exit(0)
|
|
@@ -546716,8 +546810,8 @@ ${JSON.stringify(result.faces, null, 2)}`, durationMs: performance.now() - start
|
|
|
546716
546810
|
// Face Enrollment
|
|
546717
546811
|
// =========================================================================
|
|
546718
546812
|
async enrollFace(args, start2) {
|
|
546719
|
-
const image = args
|
|
546720
|
-
const name10 = args
|
|
546813
|
+
const image = imagePathArg(args);
|
|
546814
|
+
const name10 = associationLabelArg(args);
|
|
546721
546815
|
if (!image || !existsSync66(image))
|
|
546722
546816
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546723
546817
|
if (!name10)
|
|
@@ -546730,7 +546824,7 @@ app = FaceAnalysis(name='buffalo_s', providers=['CUDAExecutionProvider', 'CPUExe
|
|
|
546730
546824
|
app.prepare(ctx_id=0, det_size=(640, 640))
|
|
546731
546825
|
|
|
546732
546826
|
import cv2
|
|
546733
|
-
img = cv2.imread(
|
|
546827
|
+
img = cv2.imread(${pyLiteral(image)})
|
|
546734
546828
|
if img is None:
|
|
546735
546829
|
print(json.dumps({"success": False, "error": "Could not read image"}))
|
|
546736
546830
|
sys.exit(0)
|
|
@@ -546751,9 +546845,9 @@ if os.path.exists(db_path):
|
|
|
546751
546845
|
with open(db_path) as f:
|
|
546752
546846
|
db = json.load(f)
|
|
546753
546847
|
|
|
546754
|
-
person_id =
|
|
546848
|
+
person_id = ${pyLiteral(name10)}.lower().replace(" ", "_").replace("'", "")
|
|
546755
546849
|
if person_id not in db:
|
|
546756
|
-
db[person_id] = {"name":
|
|
546850
|
+
db[person_id] = {"name": ${pyLiteral(name10)}, "embeddings": [], "created_at": time.time()}
|
|
546757
546851
|
|
|
546758
546852
|
db[person_id]["embeddings"].append(embedding)
|
|
546759
546853
|
db[person_id]["updated_at"] = time.time()
|
|
@@ -546765,7 +546859,7 @@ with open(db_path, "w") as f:
|
|
|
546765
546859
|
print(json.dumps({
|
|
546766
546860
|
"success": True,
|
|
546767
546861
|
"person_id": person_id,
|
|
546768
|
-
"name":
|
|
546862
|
+
"name": ${pyLiteral(name10)},
|
|
546769
546863
|
"samples": sample_count,
|
|
546770
546864
|
"total_people": len(db),
|
|
546771
546865
|
"confidence": float(face.det_score),
|
|
@@ -546786,7 +546880,7 @@ print(json.dumps({
|
|
|
546786
546880
|
// Face Identification
|
|
546787
546881
|
// =========================================================================
|
|
546788
546882
|
async identifyFaces(args, start2) {
|
|
546789
|
-
const image = args
|
|
546883
|
+
const image = imagePathArg(args);
|
|
546790
546884
|
if (!image || !existsSync66(image))
|
|
546791
546885
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546792
546886
|
const threshold = args["threshold"] || 0.5;
|
|
@@ -546799,7 +546893,7 @@ app = FaceAnalysis(name='buffalo_s', providers=['CUDAExecutionProvider', 'CPUExe
|
|
|
546799
546893
|
app.prepare(ctx_id=0, det_size=(640, 640))
|
|
546800
546894
|
|
|
546801
546895
|
import cv2
|
|
546802
|
-
img = cv2.imread(
|
|
546896
|
+
img = cv2.imread(${pyLiteral(image)})
|
|
546803
546897
|
if img is None:
|
|
546804
546898
|
print(json.dumps({"success": False, "error": "Could not read image"}))
|
|
546805
546899
|
sys.exit(0)
|
|
@@ -546883,23 +546977,34 @@ ${lines.join("\n")}`,
|
|
|
546883
546977
|
// Object Teaching (CLIP/SigLIP)
|
|
546884
546978
|
// =========================================================================
|
|
546885
546979
|
async teachObject(args, start2) {
|
|
546886
|
-
const image = args
|
|
546887
|
-
const label = args
|
|
546980
|
+
const image = imagePathArg(args);
|
|
546981
|
+
const label = associationLabelArg(args);
|
|
546888
546982
|
if (!image || !existsSync66(image))
|
|
546889
546983
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546890
546984
|
if (!label)
|
|
546891
546985
|
return { success: false, output: "", error: "Provide a label for the object.", durationMs: performance.now() - start2 };
|
|
546986
|
+
const aliases = [...new Set([
|
|
546987
|
+
label,
|
|
546988
|
+
...stringListArg(args["labels"]),
|
|
546989
|
+
...stringListArg(args["aliases"])
|
|
546990
|
+
].map((item) => item.trim()).filter(Boolean))];
|
|
546892
546991
|
const result = await this.runVisionPython(`
|
|
546893
|
-
import json, sys, os, time
|
|
546992
|
+
import json, sys, os, time, hashlib
|
|
546894
546993
|
import torch
|
|
546895
546994
|
from PIL import Image
|
|
546896
546995
|
from transformers import CLIPProcessor, CLIPModel
|
|
546897
546996
|
|
|
546997
|
+
image_path = ${pyLiteral(image)}
|
|
546998
|
+
label = ${pyLiteral(label)}
|
|
546999
|
+
aliases = ${JSON.stringify(aliases)}
|
|
547000
|
+
with open(image_path, "rb") as f:
|
|
547001
|
+
image_hash = hashlib.sha256(f.read()).hexdigest()
|
|
547002
|
+
|
|
546898
547003
|
# Use CLIP ViT-B/32 — good balance of speed and quality
|
|
546899
547004
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
546900
547005
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
546901
547006
|
|
|
546902
|
-
img = Image.open(
|
|
547007
|
+
img = Image.open(image_path).convert("RGB")
|
|
546903
547008
|
inputs = processor(images=img, return_tensors="pt")
|
|
546904
547009
|
with torch.no_grad():
|
|
546905
547010
|
image_features = model.get_image_features(**inputs)
|
|
@@ -546907,13 +547012,16 @@ with torch.no_grad():
|
|
|
546907
547012
|
|
|
546908
547013
|
embedding = image_features[0].cpu().numpy().tolist()
|
|
546909
547014
|
|
|
546910
|
-
# Also embed the text label for cross-modal retrieval
|
|
546911
|
-
text_inputs = processor(text=
|
|
547015
|
+
# Also embed the text label and aliases for cross-modal retrieval
|
|
547016
|
+
text_inputs = processor(text=aliases, return_tensors="pt", padding=True)
|
|
546912
547017
|
with torch.no_grad():
|
|
546913
547018
|
text_features = model.get_text_features(**text_inputs)
|
|
546914
547019
|
text_features = text_features / text_features.norm(dim=-1, keepdim=True)
|
|
546915
547020
|
|
|
546916
|
-
|
|
547021
|
+
text_embeddings = {}
|
|
547022
|
+
for i, alias in enumerate(aliases):
|
|
547023
|
+
text_embeddings[alias] = text_features[i].cpu().numpy().tolist()
|
|
547024
|
+
text_embedding = text_embeddings[aliases[0]]
|
|
546917
547025
|
|
|
546918
547026
|
# Store in object database
|
|
546919
547027
|
db_path = "${VMEM_DIR}/objects.json"
|
|
@@ -546922,12 +547030,19 @@ if os.path.exists(db_path):
|
|
|
546922
547030
|
with open(db_path) as f:
|
|
546923
547031
|
db = json.load(f)
|
|
546924
547032
|
|
|
546925
|
-
obj_id =
|
|
547033
|
+
obj_id = label.lower().replace(" ", "_").replace("'", "")
|
|
546926
547034
|
if obj_id not in db:
|
|
546927
|
-
db[obj_id] = {"label":
|
|
547035
|
+
db[obj_id] = {"label": label, "aliases": [], "image_embeddings": [], "image_hashes": [], "text_embeddings": {}, "text_embedding": text_embedding, "created_at": time.time()}
|
|
546928
547036
|
|
|
546929
|
-
db[obj_id]
|
|
547037
|
+
existing_hashes = set(db[obj_id].get("image_hashes", []))
|
|
547038
|
+
duplicate_sample = image_hash in existing_hashes
|
|
547039
|
+
if not duplicate_sample:
|
|
547040
|
+
db[obj_id].setdefault("image_embeddings", []).append(embedding)
|
|
547041
|
+
db[obj_id].setdefault("image_hashes", []).append(image_hash)
|
|
546930
547042
|
db[obj_id]["text_embedding"] = text_embedding # update with latest
|
|
547043
|
+
db[obj_id].setdefault("text_embeddings", {}).update(text_embeddings)
|
|
547044
|
+
merged_aliases = list(dict.fromkeys([db[obj_id].get("label", label)] + db[obj_id].get("aliases", []) + aliases))
|
|
547045
|
+
db[obj_id]["aliases"] = merged_aliases
|
|
546931
547046
|
db[obj_id]["updated_at"] = time.time()
|
|
546932
547047
|
sample_count = len(db[obj_id]["image_embeddings"])
|
|
546933
547048
|
|
|
@@ -546937,10 +547052,12 @@ with open(db_path, "w") as f:
|
|
|
546937
547052
|
print(json.dumps({
|
|
546938
547053
|
"success": True,
|
|
546939
547054
|
"object_id": obj_id,
|
|
546940
|
-
"label":
|
|
547055
|
+
"label": label,
|
|
547056
|
+
"aliases": merged_aliases,
|
|
546941
547057
|
"samples": sample_count,
|
|
546942
547058
|
"total_objects": len(db),
|
|
546943
547059
|
"embedding_dim": len(embedding),
|
|
547060
|
+
"duplicate_sample": duplicate_sample,
|
|
546944
547061
|
}))
|
|
546945
547062
|
`, 12e4);
|
|
546946
547063
|
if (!result.success)
|
|
@@ -546949,7 +547066,9 @@ print(json.dumps({
|
|
|
546949
547066
|
success: true,
|
|
546950
547067
|
output: `Taught object "${result.label}" (ID: ${result.object_id})
|
|
546951
547068
|
Samples: ${result.samples}
|
|
546952
|
-
|
|
547069
|
+
Aliases: ${(result.aliases || []).join(", ") || result.label}
|
|
547070
|
+
` + (result.duplicate_sample ? ` Duplicate sample skipped for same image hash
|
|
547071
|
+
` : "") + ` Embedding: ${result.embedding_dim}d CLIP vector
|
|
546953
547072
|
Total objects in memory: ${result.total_objects}`,
|
|
546954
547073
|
durationMs: performance.now() - start2
|
|
546955
547074
|
};
|
|
@@ -546958,11 +547077,11 @@ print(json.dumps({
|
|
|
546958
547077
|
// Object Recognition
|
|
546959
547078
|
// =========================================================================
|
|
546960
547079
|
async recognizeObjects(args, start2) {
|
|
546961
|
-
const image = args
|
|
547080
|
+
const image = imagePathArg(args);
|
|
546962
547081
|
if (!image || !existsSync66(image))
|
|
546963
547082
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546964
|
-
const threshold = args["threshold"]
|
|
546965
|
-
const extraLabels = args["labels"]
|
|
547083
|
+
const threshold = typeof args["threshold"] === "number" ? args["threshold"] : 0.3;
|
|
547084
|
+
const extraLabels = stringListArg(args["labels"]);
|
|
546966
547085
|
const wantsJson = args["format"] === "json" || args["json"] === true;
|
|
546967
547086
|
const result = await this.runVisionPython(`
|
|
546968
547087
|
import json, sys, os, numpy as np
|
|
@@ -546973,7 +547092,7 @@ from transformers import CLIPProcessor, CLIPModel
|
|
|
546973
547092
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
546974
547093
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
546975
547094
|
|
|
546976
|
-
img = Image.open(
|
|
547095
|
+
img = Image.open(${pyLiteral(image)}).convert("RGB")
|
|
546977
547096
|
|
|
546978
547097
|
# Get image embedding
|
|
546979
547098
|
inputs = processor(images=img, return_tensors="pt")
|
|
@@ -546994,13 +547113,30 @@ if os.path.exists(db_path):
|
|
|
546994
547113
|
matches = []
|
|
546995
547114
|
for obj_id, data in db.items():
|
|
546996
547115
|
best_sim = -1
|
|
546997
|
-
for emb in data
|
|
547116
|
+
for emb in data.get("image_embeddings", []):
|
|
546998
547117
|
sim = float(np.dot(query, np.array(emb, dtype=np.float32)))
|
|
546999
547118
|
if sim > best_sim:
|
|
547000
547119
|
best_sim = sim
|
|
547001
547120
|
|
|
547002
|
-
# Also score against text label
|
|
547003
|
-
text_sim =
|
|
547121
|
+
# Also score against all stored text label/alias embeddings
|
|
547122
|
+
text_sim = -1
|
|
547123
|
+
best_text_label = data.get("label", obj_id)
|
|
547124
|
+
text_embeddings = data.get("text_embeddings")
|
|
547125
|
+
if isinstance(text_embeddings, dict) and text_embeddings:
|
|
547126
|
+
iterable = text_embeddings.items()
|
|
547127
|
+
elif data.get("text_embedding") is not None:
|
|
547128
|
+
iterable = [(data.get("label", obj_id), data["text_embedding"])]
|
|
547129
|
+
else:
|
|
547130
|
+
iterable = []
|
|
547131
|
+
for alias, emb in iterable:
|
|
547132
|
+
sim = float(np.dot(query, np.array(emb, dtype=np.float32)))
|
|
547133
|
+
if sim > text_sim:
|
|
547134
|
+
text_sim = sim
|
|
547135
|
+
best_text_label = alias
|
|
547136
|
+
if text_sim < 0:
|
|
547137
|
+
text_sim = 0
|
|
547138
|
+
if best_sim < 0:
|
|
547139
|
+
best_sim = 0
|
|
547004
547140
|
|
|
547005
547141
|
# Blend: 60% image similarity, 40% text similarity
|
|
547006
547142
|
blended = 0.6 * best_sim + 0.4 * text_sim
|
|
@@ -547008,6 +547144,8 @@ for obj_id, data in db.items():
|
|
|
547008
547144
|
matches.append({
|
|
547009
547145
|
"object_id": obj_id,
|
|
547010
547146
|
"label": data["label"],
|
|
547147
|
+
"matched_alias": best_text_label,
|
|
547148
|
+
"aliases": data.get("aliases", []),
|
|
547011
547149
|
"image_similarity": round(best_sim, 3),
|
|
547012
547150
|
"text_similarity": round(text_sim, 3),
|
|
547013
547151
|
"blended_score": round(blended, 3),
|
|
@@ -547089,7 +547227,7 @@ ${objects.join("\n") || " (none taught)"}`,
|
|
|
547089
547227
|
};
|
|
547090
547228
|
}
|
|
547091
547229
|
async forgetEntry(args, start2) {
|
|
547092
|
-
const id = (args
|
|
547230
|
+
const id = stringArg2(args, "id", "name", "label").toLowerCase().replace(/\s/g, "_");
|
|
547093
547231
|
if (!id)
|
|
547094
547232
|
return { success: false, output: "", error: "Provide the ID or name of the person/object to forget.", durationMs: performance.now() - start2 };
|
|
547095
547233
|
let removed = false;
|
|
@@ -547165,7 +547303,7 @@ ${objects.join("\n") || " (none taught)"}`,
|
|
|
547165
547303
|
}
|
|
547166
547304
|
}
|
|
547167
547305
|
}
|
|
547168
|
-
throw new Error(
|
|
547306
|
+
throw new Error(summarizeProcessFailure(stdout, stderr));
|
|
547169
547307
|
}
|
|
547170
547308
|
}
|
|
547171
547309
|
};
|
|
@@ -558355,6 +558493,15 @@ function nowIso2(now2 = /* @__PURE__ */ new Date()) {
|
|
|
558355
558493
|
function cleanText(value2, max = 600) {
|
|
558356
558494
|
return String(value2 ?? "").replace(/\s+/g, " ").trim().slice(0, max);
|
|
558357
558495
|
}
|
|
558496
|
+
function normalizeEvidencePath(value2) {
|
|
558497
|
+
return String(value2 ?? "").trim().replace(/^file:\/\//i, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "");
|
|
558498
|
+
}
|
|
558499
|
+
function cleanTargetPaths(paths) {
|
|
558500
|
+
if (!Array.isArray(paths))
|
|
558501
|
+
return [];
|
|
558502
|
+
const cleaned = paths.map(normalizeEvidencePath).filter((path12) => path12.length > 0).slice(0, 20);
|
|
558503
|
+
return [...new Set(cleaned)];
|
|
558504
|
+
}
|
|
558358
558505
|
function convertPipesToUnicode(text2) {
|
|
558359
558506
|
return text2.replace(/\|/g, "│");
|
|
558360
558507
|
}
|
|
@@ -558430,6 +558577,7 @@ function deriveClaimsFromProposedText(input) {
|
|
|
558430
558577
|
});
|
|
558431
558578
|
}
|
|
558432
558579
|
function recordCompletionEvidence(ledger, evidence) {
|
|
558580
|
+
const targetPaths = cleanTargetPaths(evidence.targetPaths);
|
|
558433
558581
|
const entry = {
|
|
558434
558582
|
id: evidence.id ?? nextId2("ev", ledger.evidence.length),
|
|
558435
558583
|
kind: evidence.kind,
|
|
@@ -558437,7 +558585,8 @@ function recordCompletionEvidence(ledger, evidence) {
|
|
|
558437
558585
|
summary: cleanText(evidence.summary, 1200),
|
|
558438
558586
|
toolName: evidence.toolName,
|
|
558439
558587
|
success: evidence.success,
|
|
558440
|
-
rawRef: evidence.rawRef
|
|
558588
|
+
rawRef: evidence.rawRef,
|
|
558589
|
+
...targetPaths.length > 0 ? { targetPaths } : {}
|
|
558441
558590
|
};
|
|
558442
558591
|
return {
|
|
558443
558592
|
...ledger,
|
|
@@ -558457,7 +558606,8 @@ function recordToolEvidence(ledger, input) {
|
|
|
558457
558606
|
toolName: input.name,
|
|
558458
558607
|
success: input.success,
|
|
558459
558608
|
summary,
|
|
558460
|
-
rawRef: input.rawRef
|
|
558609
|
+
rawRef: input.rawRef,
|
|
558610
|
+
targetPaths: input.targetPaths
|
|
558461
558611
|
});
|
|
558462
558612
|
}
|
|
558463
558613
|
function addCompletionClaims(ledger, claims) {
|
|
@@ -558596,6 +558746,55 @@ function isMutationEvidence(entry) {
|
|
|
558596
558746
|
return true;
|
|
558597
558747
|
return entry.success === true && /^(file_write|file_edit|file_patch|batch_edit)$/.test(entry.toolName ?? "");
|
|
558598
558748
|
}
|
|
558749
|
+
function evidenceTargetPaths(entry) {
|
|
558750
|
+
const explicit = cleanTargetPaths(entry.targetPaths);
|
|
558751
|
+
if (explicit.length > 0)
|
|
558752
|
+
return explicit;
|
|
558753
|
+
const paths = [];
|
|
558754
|
+
if (entry.rawRef?.startsWith("file://")) {
|
|
558755
|
+
paths.push(entry.rawRef.slice("file://".length));
|
|
558756
|
+
}
|
|
558757
|
+
const fileChange = entry.summary.match(/\bfile change:\s*([^\s,;]+)/i);
|
|
558758
|
+
if (fileChange?.[1])
|
|
558759
|
+
paths.push(fileChange[1]);
|
|
558760
|
+
const quotedPathRe = /"(?:path|file_path|file|filename|filepath|filePath)"\s*:\s*"([^"]+)"/g;
|
|
558761
|
+
for (const match of entry.summary.matchAll(quotedPathRe)) {
|
|
558762
|
+
if (match[1])
|
|
558763
|
+
paths.push(match[1]);
|
|
558764
|
+
}
|
|
558765
|
+
const loosePathRe = /\b(?:path|file_path|file|filename|filepath|filePath)=([^,\s}\]]+)/g;
|
|
558766
|
+
for (const match of entry.summary.matchAll(loosePathRe)) {
|
|
558767
|
+
if (match[1])
|
|
558768
|
+
paths.push(match[1].replace(/^["']|["']$/g, ""));
|
|
558769
|
+
}
|
|
558770
|
+
return cleanTargetPaths(paths);
|
|
558771
|
+
}
|
|
558772
|
+
function pathsEquivalent(a2, b) {
|
|
558773
|
+
const left = normalizeEvidencePath(a2);
|
|
558774
|
+
const right = normalizeEvidencePath(b);
|
|
558775
|
+
if (!left || !right)
|
|
558776
|
+
return false;
|
|
558777
|
+
return left === right || left.endsWith(`/${right}`) || right.endsWith(`/${left}`);
|
|
558778
|
+
}
|
|
558779
|
+
function isVerificationNeutralPath(path12) {
|
|
558780
|
+
const normalized = normalizeEvidencePath(path12).toLowerCase();
|
|
558781
|
+
const base3 = normalized.split("/").pop() ?? normalized;
|
|
558782
|
+
if (/\.(md|mdx|markdown|txt|rst|adoc)$/.test(base3))
|
|
558783
|
+
return true;
|
|
558784
|
+
if (/^(readme|changelog|changes|license|licence|notice|implementation_notes)(?:\.[^.]+)?$/.test(base3))
|
|
558785
|
+
return true;
|
|
558786
|
+
if (normalized.includes("/docs/") || normalized.startsWith("docs/"))
|
|
558787
|
+
return true;
|
|
558788
|
+
return false;
|
|
558789
|
+
}
|
|
558790
|
+
function isVerificationInvalidatingMutation(entry) {
|
|
558791
|
+
if (!isMutationEvidence(entry))
|
|
558792
|
+
return false;
|
|
558793
|
+
const paths = evidenceTargetPaths(entry);
|
|
558794
|
+
if (paths.length === 0)
|
|
558795
|
+
return true;
|
|
558796
|
+
return paths.some((path12) => !isVerificationNeutralPath(path12));
|
|
558797
|
+
}
|
|
558599
558798
|
function isSuccessfulVerificationEvidence(entry) {
|
|
558600
558799
|
if (entry.success !== true)
|
|
558601
558800
|
return false;
|
|
@@ -558627,14 +558826,72 @@ function isStaleEditEvidence(entry) {
|
|
|
558627
558826
|
const text2 = entry.summary.toLowerCase();
|
|
558628
558827
|
return /stale edit loop blocked|old[_ -]?string|old text|expected[_ -]?hash|context mismatch|no occurrences|could not find/.test(text2);
|
|
558629
558828
|
}
|
|
558829
|
+
function staleEditResolvedByLaterMutation(evidence, failedEntry, failedIndex) {
|
|
558830
|
+
const failedPaths = evidenceTargetPaths(failedEntry);
|
|
558831
|
+
if (failedPaths.length === 0)
|
|
558832
|
+
return false;
|
|
558833
|
+
for (const later of evidence.slice(failedIndex + 1)) {
|
|
558834
|
+
if (!isMutationEvidence(later) || later.success !== true)
|
|
558835
|
+
continue;
|
|
558836
|
+
const laterPaths = evidenceTargetPaths(later);
|
|
558837
|
+
if (laterPaths.some((laterPath) => failedPaths.some((failedPath) => pathsEquivalent(laterPath, failedPath)))) {
|
|
558838
|
+
return true;
|
|
558839
|
+
}
|
|
558840
|
+
}
|
|
558841
|
+
return false;
|
|
558842
|
+
}
|
|
558843
|
+
function extractClaimedAllTestsPassedCount(text2) {
|
|
558844
|
+
const match = text2.match(/\ball\s+(\d{1,6})\s+tests?\s+(?:pass|passed|passing)\b/i);
|
|
558845
|
+
return match?.[1] ? Number(match[1]) : null;
|
|
558846
|
+
}
|
|
558847
|
+
function extractObservedSuccessfulTestCount(text2) {
|
|
558848
|
+
const normalized = text2.replace(/\s+/g, " ");
|
|
558849
|
+
const testsPassed = normalized.match(/\btests?\s+(\d{1,6})\s+passed\b/i);
|
|
558850
|
+
if (testsPassed?.[1])
|
|
558851
|
+
return Number(testsPassed[1]);
|
|
558852
|
+
const testsLine = normalized.match(/\btests?\s*:?\s*(\d{1,6})\b/i);
|
|
558853
|
+
const passLine = normalized.match(/\bpass(?:ed)?\s*:?\s*(\d{1,6})\b/i);
|
|
558854
|
+
if (testsLine?.[1])
|
|
558855
|
+
return Number(testsLine[1]);
|
|
558856
|
+
if (passLine?.[1])
|
|
558857
|
+
return Number(passLine[1]);
|
|
558858
|
+
const passedTests = normalized.match(/\b(\d{1,6})\s+tests?\s+passed\b/i);
|
|
558859
|
+
if (passedTests?.[1])
|
|
558860
|
+
return Number(passedTests[1]);
|
|
558861
|
+
return null;
|
|
558862
|
+
}
|
|
558863
|
+
function latestObservedSuccessfulTestCount(evidence) {
|
|
558864
|
+
for (let index = evidence.length - 1; index >= 0; index--) {
|
|
558865
|
+
const entry = evidence[index];
|
|
558866
|
+
if (entry.success !== true || verificationFamily(entry) !== "test")
|
|
558867
|
+
continue;
|
|
558868
|
+
const count = extractObservedSuccessfulTestCount(entry.summary);
|
|
558869
|
+
if (count !== null && Number.isFinite(count))
|
|
558870
|
+
return count;
|
|
558871
|
+
}
|
|
558872
|
+
return null;
|
|
558873
|
+
}
|
|
558874
|
+
function appendTestCountOverclaims(ledger, unresolved) {
|
|
558875
|
+
const observed = latestObservedSuccessfulTestCount(ledger.evidence);
|
|
558876
|
+
if (observed === null)
|
|
558877
|
+
return unresolved;
|
|
558878
|
+
let next = unresolved;
|
|
558879
|
+
for (const claim of ledger.proposedClaims) {
|
|
558880
|
+
const claimed = extractClaimedAllTestsPassedCount(claim.text);
|
|
558881
|
+
if (claimed === null || claimed === observed)
|
|
558882
|
+
continue;
|
|
558883
|
+
next = appendUnresolved(next, `Completion claim overstates verification: claimed all ${claimed} tests pass, but latest successful test evidence reported ${observed}.`, claim.id);
|
|
558884
|
+
}
|
|
558885
|
+
return next;
|
|
558886
|
+
}
|
|
558630
558887
|
function finalizeCompletionLedgerTruth(ledger) {
|
|
558631
558888
|
let unresolved = [...ledger.unresolved];
|
|
558632
|
-
let
|
|
558889
|
+
let lastVerificationInvalidatingMutation = -1;
|
|
558633
558890
|
let lastVerification = -1;
|
|
558634
558891
|
const lastSuccessfulVerificationByFamily = /* @__PURE__ */ new Map();
|
|
558635
558892
|
ledger.evidence.forEach((entry, index) => {
|
|
558636
|
-
if (
|
|
558637
|
-
|
|
558893
|
+
if (isVerificationInvalidatingMutation(entry))
|
|
558894
|
+
lastVerificationInvalidatingMutation = index;
|
|
558638
558895
|
if (isSuccessfulVerificationEvidence(entry)) {
|
|
558639
558896
|
lastVerification = index;
|
|
558640
558897
|
const family = verificationFamily(entry);
|
|
@@ -558650,13 +558907,14 @@ function finalizeCompletionLedgerTruth(ledger) {
|
|
|
558650
558907
|
unresolved = appendUnresolved(unresolved, `Verification failed or did not prove success: ${entry.summary}`, entry.id);
|
|
558651
558908
|
}
|
|
558652
558909
|
}
|
|
558653
|
-
if (isStaleEditEvidence(entry)) {
|
|
558910
|
+
if (isStaleEditEvidence(entry) && !staleEditResolvedByLaterMutation(ledger.evidence, entry, index)) {
|
|
558654
558911
|
unresolved = appendUnresolved(unresolved, `Stale edit failure remains unresolved: ${entry.summary}`, entry.id);
|
|
558655
558912
|
}
|
|
558656
558913
|
});
|
|
558657
|
-
if (lastVerification >= 0 &&
|
|
558914
|
+
if (lastVerification >= 0 && lastVerificationInvalidatingMutation > lastVerification) {
|
|
558658
558915
|
unresolved = appendUnresolved(unresolved, "File changes occurred after the last successful verification; final verification is stale.", "verification_freshness");
|
|
558659
558916
|
}
|
|
558917
|
+
unresolved = appendTestCountOverclaims(ledger, unresolved);
|
|
558660
558918
|
const status = ledger.status === "blocked" || ledger.status === "request_changes" ? ledger.status : unresolved.length > 0 ? "incomplete_verification" : ledger.status;
|
|
558661
558919
|
return {
|
|
558662
558920
|
...ledger,
|
|
@@ -564299,12 +564557,12 @@ var init_reflectionBuffer = __esm({
|
|
|
564299
564557
|
if (!this.persistPath)
|
|
564300
564558
|
return;
|
|
564301
564559
|
try {
|
|
564302
|
-
const { writeFileSync:
|
|
564560
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106, existsSync: existsSync164 } = __require("node:fs");
|
|
564303
564561
|
const { join: join179 } = __require("node:path");
|
|
564304
564562
|
const dir = join179(this.persistPath, "..");
|
|
564305
564563
|
if (!existsSync164(dir))
|
|
564306
564564
|
mkdirSync106(dir, { recursive: true });
|
|
564307
|
-
|
|
564565
|
+
writeFileSync90(this.persistPath, JSON.stringify(this.state, null, 2));
|
|
564308
564566
|
} catch {
|
|
564309
564567
|
}
|
|
564310
564568
|
}
|
|
@@ -567915,12 +568173,12 @@ var init_adversaryStream = __esm({
|
|
|
567915
568173
|
if (!this.persistPath)
|
|
567916
568174
|
return;
|
|
567917
568175
|
try {
|
|
567918
|
-
const { writeFileSync:
|
|
568176
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106, existsSync: existsSync164 } = __require("node:fs");
|
|
567919
568177
|
const { dirname: dirname54 } = __require("node:path");
|
|
567920
568178
|
const dir = dirname54(this.persistPath);
|
|
567921
568179
|
if (!existsSync164(dir))
|
|
567922
568180
|
mkdirSync106(dir, { recursive: true });
|
|
567923
|
-
|
|
568181
|
+
writeFileSync90(this.persistPath, JSON.stringify({ ledger: this.ledger }, null, 2));
|
|
567924
568182
|
} catch {
|
|
567925
568183
|
}
|
|
567926
568184
|
}
|
|
@@ -571961,12 +572219,14 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
571961
572219
|
if (!this._completionLedger || input.toolName === "task_complete")
|
|
571962
572220
|
return;
|
|
571963
572221
|
const realFileMutation = input.realFileMutation ?? this._isRealProjectMutation(input.toolName, input.result);
|
|
571964
|
-
const
|
|
572222
|
+
const attemptedTargetPaths = this._extractToolTargetPaths(input.toolName, input.args, input.result);
|
|
572223
|
+
const realMutationPaths = input.realMutationPaths ?? (realFileMutation ? attemptedTargetPaths : []);
|
|
571965
572224
|
this._completionLedger = recordToolEvidence(this._completionLedger, {
|
|
571966
572225
|
name: input.toolName,
|
|
571967
572226
|
success: input.result.success,
|
|
571968
572227
|
outputPreview: (input.outputPreview ?? this._toolEvidencePreview(input.result)).toString().slice(0, 500),
|
|
571969
|
-
argsKey: input.argsKey.slice(0, 300)
|
|
572228
|
+
argsKey: input.argsKey.slice(0, 300),
|
|
572229
|
+
targetPaths: attemptedTargetPaths
|
|
571970
572230
|
});
|
|
571971
572231
|
if (realFileMutation && realMutationPaths.length > 0) {
|
|
571972
572232
|
for (const filePath of realMutationPaths) {
|
|
@@ -571975,7 +572235,8 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
571975
572235
|
toolName: input.toolName,
|
|
571976
572236
|
success: true,
|
|
571977
572237
|
summary: `file change: ${filePath}`,
|
|
571978
|
-
rawRef: `file://${filePath}
|
|
572238
|
+
rawRef: `file://${filePath}`,
|
|
572239
|
+
targetPaths: [filePath]
|
|
571979
572240
|
});
|
|
571980
572241
|
}
|
|
571981
572242
|
}
|
|
@@ -575393,7 +575654,8 @@ Rewrite it now for ${ctx3.model}.`;
|
|
|
575393
575654
|
run_in_background: ["background", "background_run", "async"],
|
|
575394
575655
|
max_turns: ["maxTurns", "turns"],
|
|
575395
575656
|
timeout_ms: ["timeoutMs", "timeout"],
|
|
575396
|
-
path: ["file", "filepath", "file_path", "filename"],
|
|
575657
|
+
path: ["file", "image", "media", "filepath", "file_path", "filename"],
|
|
575658
|
+
image: ["path", "file", "media", "filepath", "file_path", "filename"],
|
|
575397
575659
|
command: ["cmd", "shell_command"],
|
|
575398
575660
|
query: ["prompt", "task", "message", "input", "text"]
|
|
575399
575661
|
};
|
|
@@ -582419,7 +582681,7 @@ ${caveat}` : caveat;
|
|
|
582419
582681
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
582420
582682
|
});
|
|
582421
582683
|
try {
|
|
582422
|
-
const { mkdirSync: mkdirSync106, readdirSync: readdirSync59, statSync: statSync59, unlinkSync: unlinkSync36, writeFileSync:
|
|
582684
|
+
const { mkdirSync: mkdirSync106, readdirSync: readdirSync59, statSync: statSync59, unlinkSync: unlinkSync36, writeFileSync: writeFileSync90 } = __require("node:fs");
|
|
582423
582685
|
const { join: join179 } = __require("node:path");
|
|
582424
582686
|
const contextDir = join179(this._workingDirectory || process.cwd(), ".omnius", "context");
|
|
582425
582687
|
mkdirSync106(contextDir, { recursive: true });
|
|
@@ -582466,14 +582728,14 @@ ${caveat}` : caveat;
|
|
|
582466
582728
|
mkdirSync106(kgSummaryDir, { recursive: true });
|
|
582467
582729
|
const summaryFilename = `kg-summary-${this._sessionId}.md`;
|
|
582468
582730
|
const outPath = join179(kgSummaryDir, summaryFilename);
|
|
582469
|
-
|
|
582470
|
-
|
|
582471
|
-
|
|
582731
|
+
writeFileSync90(outPath, lines.join("\n"), "utf-8");
|
|
582732
|
+
writeFileSync90(join179(kgSummaryDir, "latest.md"), lines.join("\n"), "utf-8");
|
|
582733
|
+
writeFileSync90(join179(contextDir, `kg-summary-latest.md`), [
|
|
582472
582734
|
"Latest KG summary moved to `.omnius/context/kg-summary/latest.md`.",
|
|
582473
582735
|
"",
|
|
582474
582736
|
lines.join("\n")
|
|
582475
582737
|
].join("\n"), "utf-8");
|
|
582476
|
-
|
|
582738
|
+
writeFileSync90(join179(kgSummaryDir, "index.json"), JSON.stringify({
|
|
582477
582739
|
schema: "omnius.kg-summary-index.v1",
|
|
582478
582740
|
latest: "latest.md",
|
|
582479
582741
|
latestSessionFile: summaryFilename,
|
|
@@ -583310,7 +583572,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
583310
583572
|
if (!this._workingDirectory)
|
|
583311
583573
|
return;
|
|
583312
583574
|
try {
|
|
583313
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
583575
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = __require("node:fs");
|
|
583314
583576
|
const { join: join179 } = __require("node:path");
|
|
583315
583577
|
const sessionDir2 = this.options.stateDir ? join179(this.omniusStateDir(), "session", this._sessionId) : join179(this._workingDirectory, ".omnius", "session", this._sessionId);
|
|
583316
583578
|
mkdirSync106(sessionDir2, { recursive: true });
|
|
@@ -583325,7 +583587,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
583325
583587
|
memexEntryCount: this._memexArchive.size,
|
|
583326
583588
|
fileRegistrySize: this._fileRegistry.size
|
|
583327
583589
|
};
|
|
583328
|
-
|
|
583590
|
+
writeFileSync90(join179(sessionDir2, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
583329
583591
|
} catch {
|
|
583330
583592
|
}
|
|
583331
583593
|
}
|
|
@@ -583462,7 +583724,7 @@ ${tail}`;
|
|
|
583462
583724
|
const analysis = await this.analyzeImageDataForContext(image.mime, image.base64, image.textWithoutImage.slice(0, 2e3));
|
|
583463
583725
|
const imageNote = analysis.contextBlock ? `${analysis.contextBlock}
|
|
583464
583726
|
|
|
583465
|
-
Use this image analysis. Do not repeat ${toolName} with the same arguments unless the scene has changed.` : `[Embedded image data omitted from model context; ${analysis.errorReason || "vision and OCR returned no text"}.
|
|
583727
|
+
Use this image analysis. Do not repeat ${toolName} with the same arguments unless the scene has changed.` : `[Embedded image data omitted from model context; ${analysis.errorReason || "vision and OCR returned no text"}. If further inspection is needed, call vision first with the saved image path (Moondream caption/query), then use image_read only for metadata/OCR/raw image ingress.]`;
|
|
583466
583728
|
return {
|
|
583467
583729
|
...result,
|
|
583468
583730
|
llmContent: `${image.textWithoutImage.trim()}
|
|
@@ -583498,7 +583760,7 @@ ${imageNote}`.trim()
|
|
|
583498
583760
|
const imageUrl = `data:${mime};base64,${base642}`;
|
|
583499
583761
|
const tmpImgPath = this.writeTempImageForOcr(mime, base642);
|
|
583500
583762
|
const [visionOutcome, ocrOutcome] = await Promise.allSettled([
|
|
583501
|
-
this.describeImageViaVisionSubagent(imageUrl, textContent),
|
|
583763
|
+
tmpImgPath ? this.describeImageViaPrimaryVision(tmpImgPath, imageUrl, textContent) : this.describeImageViaVisionSubagent(imageUrl, textContent),
|
|
583502
583764
|
tmpImgPath ? this.extractImageOcrText(tmpImgPath) : Promise.resolve("")
|
|
583503
583765
|
]);
|
|
583504
583766
|
const visionDesc = visionOutcome.status === "fulfilled" ? visionOutcome.value.trim() : "";
|
|
@@ -583513,6 +583775,26 @@ ${imageNote}`.trim()
|
|
|
583513
583775
|
const errorReason = visionOutcome.status === "rejected" ? String(visionOutcome.reason?.message ?? visionOutcome.reason) : void 0;
|
|
583514
583776
|
return { contextBlock: "", errorReason };
|
|
583515
583777
|
}
|
|
583778
|
+
async describeImageViaPrimaryVision(imagePath, imageUrl, textContent) {
|
|
583779
|
+
try {
|
|
583780
|
+
const vision = new VisionTool(this._workingDirectory || process.cwd());
|
|
583781
|
+
const prompt = textContent ? `User context: ${textContent}
|
|
583782
|
+
|
|
583783
|
+
Describe the image in detail. Identify people, objects, text, UI elements, diagrams, errors, and any task-relevant visual metadata.` : "Describe the image in detail. Identify people, objects, text, UI elements, diagrams, errors, and any task-relevant visual metadata.";
|
|
583784
|
+
const result = await vision.execute({
|
|
583785
|
+
image: imagePath,
|
|
583786
|
+
action: "query",
|
|
583787
|
+
prompt,
|
|
583788
|
+
length: "long"
|
|
583789
|
+
});
|
|
583790
|
+
const output = String(result.llmContent || result.output || "").trim();
|
|
583791
|
+
if (result.success && output.length > 20)
|
|
583792
|
+
return output;
|
|
583793
|
+
throw new Error(result.error || "vision tool returned no description");
|
|
583794
|
+
} catch {
|
|
583795
|
+
return await this.describeImageViaVisionSubagent(imageUrl, textContent);
|
|
583796
|
+
}
|
|
583797
|
+
}
|
|
583516
583798
|
async describeImageViaVisionSubagent(imageUrl, textContent) {
|
|
583517
583799
|
const visionMessages = [
|
|
583518
583800
|
{
|
|
@@ -585985,12 +586267,12 @@ ${result}`
|
|
|
585985
586267
|
let resizedBase64 = null;
|
|
585986
586268
|
try {
|
|
585987
586269
|
const { execSync: execSync63 } = await import("node:child_process");
|
|
585988
|
-
const { writeFileSync:
|
|
586270
|
+
const { writeFileSync: writeFileSync90, readFileSync: readFileSync133, unlinkSync: unlinkSync36 } = await import("node:fs");
|
|
585989
586271
|
const { join: join179 } = await import("node:path");
|
|
585990
586272
|
const { tmpdir: tmpdir24 } = await import("node:os");
|
|
585991
586273
|
const tmpIn = join179(tmpdir24(), `omnius_img_in_${Date.now()}.png`);
|
|
585992
586274
|
const tmpOut = join179(tmpdir24(), `omnius_img_out_${Date.now()}.jpg`);
|
|
585993
|
-
|
|
586275
|
+
writeFileSync90(tmpIn, buffer2);
|
|
585994
586276
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
585995
586277
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
585996
586278
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
@@ -594971,10 +595253,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
594971
595253
|
wordTimestamps: false
|
|
594972
595254
|
});
|
|
594973
595255
|
if (outputDir2) {
|
|
594974
|
-
const { basename:
|
|
595256
|
+
const { basename: basename40 } = await import("node:path");
|
|
594975
595257
|
const transcriptDir = join120(outputDir2, ".omnius", "transcripts");
|
|
594976
595258
|
mkdirSync63(transcriptDir, { recursive: true });
|
|
594977
|
-
const outFile = join120(transcriptDir, `${
|
|
595259
|
+
const outFile = join120(transcriptDir, `${basename40(filePath)}.txt`);
|
|
594978
595260
|
writeFileSync53(outFile, result.text, "utf-8");
|
|
594979
595261
|
}
|
|
594980
595262
|
return {
|
|
@@ -594990,10 +595272,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
594990
595272
|
const fb = await transcribeFileViaWhisper(filePath, this.config.model);
|
|
594991
595273
|
if (fb) {
|
|
594992
595274
|
if (outputDir2) {
|
|
594993
|
-
const { basename:
|
|
595275
|
+
const { basename: basename40 } = await import("node:path");
|
|
594994
595276
|
const transcriptDir = join120(outputDir2, ".omnius", "transcripts");
|
|
594995
595277
|
mkdirSync63(transcriptDir, { recursive: true });
|
|
594996
|
-
const outFile = join120(transcriptDir, `${
|
|
595278
|
+
const outFile = join120(transcriptDir, `${basename40(filePath)}.txt`);
|
|
594997
595279
|
writeFileSync53(outFile, fb.text, "utf-8");
|
|
594998
595280
|
}
|
|
594999
595281
|
return fb;
|
|
@@ -635942,13 +636224,13 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
635942
636224
|
try {
|
|
635943
636225
|
const { randomBytes: randomBytes30 } = await import("node:crypto");
|
|
635944
636226
|
const { homedir: homedir62 } = await import("node:os");
|
|
635945
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
636227
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
635946
636228
|
const { join: join179 } = await import("node:path");
|
|
635947
636229
|
const newKey = randomBytes30(16).toString("hex");
|
|
635948
636230
|
process.env["OMNIUS_API_KEY"] = newKey;
|
|
635949
636231
|
const dir = join179(homedir62(), ".omnius");
|
|
635950
636232
|
mkdirSync106(dir, { recursive: true });
|
|
635951
|
-
|
|
636233
|
+
writeFileSync90(join179(dir, "api.key"), newKey + "\n", "utf8");
|
|
635952
636234
|
renderInfo(`New API key: ${c3.bold(c3.yellow(newKey))}`);
|
|
635953
636235
|
renderInfo(
|
|
635954
636236
|
"Restart the daemon to apply if needed. Use /access any to restart quickly."
|
|
@@ -636219,11 +636501,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636219
636501
|
);
|
|
636220
636502
|
try {
|
|
636221
636503
|
const { homedir: homedir63 } = await import("node:os");
|
|
636222
|
-
const { mkdirSync: mkdirSync107, writeFileSync:
|
|
636504
|
+
const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync91 } = await import("node:fs");
|
|
636223
636505
|
const { join: join180 } = await import("node:path");
|
|
636224
636506
|
const dir = join180(homedir63(), ".omnius");
|
|
636225
636507
|
mkdirSync107(dir, { recursive: true });
|
|
636226
|
-
|
|
636508
|
+
writeFileSync91(join180(dir, "api.key"), apiKey + "\n", "utf8");
|
|
636227
636509
|
} catch {
|
|
636228
636510
|
}
|
|
636229
636511
|
}
|
|
@@ -636235,11 +636517,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636235
636517
|
const port2 = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
636236
636518
|
try {
|
|
636237
636519
|
const { homedir: homedir63 } = await import("node:os");
|
|
636238
|
-
const { mkdirSync: mkdirSync107, writeFileSync:
|
|
636520
|
+
const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync91 } = await import("node:fs");
|
|
636239
636521
|
const { join: join180 } = await import("node:path");
|
|
636240
636522
|
const dir = join180(homedir63(), ".omnius");
|
|
636241
636523
|
mkdirSync107(dir, { recursive: true });
|
|
636242
|
-
|
|
636524
|
+
writeFileSync91(join180(dir, "access"), `${val2}
|
|
636243
636525
|
`, "utf8");
|
|
636244
636526
|
} catch {
|
|
636245
636527
|
}
|
|
@@ -636339,11 +636621,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636339
636621
|
);
|
|
636340
636622
|
try {
|
|
636341
636623
|
const { homedir: homedir63 } = await import("node:os");
|
|
636342
|
-
const { mkdirSync: mkdirSync107, writeFileSync:
|
|
636624
|
+
const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync91 } = await import("node:fs");
|
|
636343
636625
|
const { join: join180 } = await import("node:path");
|
|
636344
636626
|
const dir = join180(homedir63(), ".omnius");
|
|
636345
636627
|
mkdirSync107(dir, { recursive: true });
|
|
636346
|
-
|
|
636628
|
+
writeFileSync91(join180(dir, "api.key"), apiKey + "\n", "utf8");
|
|
636347
636629
|
} catch {
|
|
636348
636630
|
}
|
|
636349
636631
|
}
|
|
@@ -636354,12 +636636,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636354
636636
|
}
|
|
636355
636637
|
const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
636356
636638
|
const { homedir: homedir62 } = await import("node:os");
|
|
636357
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
636639
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
636358
636640
|
const { join: join179 } = await import("node:path");
|
|
636359
636641
|
try {
|
|
636360
636642
|
const dir = join179(homedir62(), ".omnius");
|
|
636361
636643
|
mkdirSync106(dir, { recursive: true });
|
|
636362
|
-
|
|
636644
|
+
writeFileSync90(join179(dir, "access"), `${val}
|
|
636363
636645
|
`, "utf8");
|
|
636364
636646
|
} catch (e2) {
|
|
636365
636647
|
renderWarning(
|
|
@@ -645195,14 +645477,14 @@ async function handleVoiceMenu(ctx3, save3, hasLocal) {
|
|
|
645195
645477
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
645196
645478
|
continue;
|
|
645197
645479
|
}
|
|
645198
|
-
const { basename:
|
|
645480
|
+
const { basename: basename40, join: pathJoin } = await import("node:path");
|
|
645199
645481
|
const {
|
|
645200
645482
|
copyFileSync: copyFileSync8,
|
|
645201
645483
|
mkdirSync: mkdirSync106,
|
|
645202
645484
|
existsSync: exists2
|
|
645203
645485
|
} = await import("node:fs");
|
|
645204
645486
|
const { homedir: homedir62 } = await import("node:os");
|
|
645205
|
-
const modelName =
|
|
645487
|
+
const modelName = basename40(onnxDrop.path, ".onnx").replace(
|
|
645206
645488
|
/[^a-zA-Z0-9_-]/g,
|
|
645207
645489
|
"-"
|
|
645208
645490
|
);
|
|
@@ -645722,7 +646004,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
645722
646004
|
copyFileSync: cpf,
|
|
645723
646005
|
mkdirSync: mkd
|
|
645724
646006
|
} = __require("node:fs");
|
|
645725
|
-
const { basename:
|
|
646007
|
+
const { basename: basename40, join: pjoin } = __require("node:path");
|
|
645726
646008
|
if (!fe(src2)) {
|
|
645727
646009
|
renderError(`File not found: ${src2}`);
|
|
645728
646010
|
helpers.render();
|
|
@@ -645735,7 +646017,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
645735
646017
|
"clone-refs"
|
|
645736
646018
|
);
|
|
645737
646019
|
mkd(refsDir, { recursive: true });
|
|
645738
|
-
const destName =
|
|
646020
|
+
const destName = basename40(src2);
|
|
645739
646021
|
const dest = pjoin(refsDir, destName);
|
|
645740
646022
|
cpf(src2, dest);
|
|
645741
646023
|
renderInfo(`Imported "${destName}" → ${dest}`);
|
|
@@ -646992,13 +647274,13 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
646992
647274
|
sponsors.push(...verified);
|
|
646993
647275
|
if (verified.length > 0) {
|
|
646994
647276
|
try {
|
|
646995
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
647277
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = __require("node:fs");
|
|
646996
647278
|
mkdirSync106(sponsorDir2, { recursive: true });
|
|
646997
647279
|
const cached = verified.map((s2) => ({
|
|
646998
647280
|
...s2,
|
|
646999
647281
|
lastVerified: Date.now()
|
|
647000
647282
|
}));
|
|
647001
|
-
|
|
647283
|
+
writeFileSync90(knownFile, JSON.stringify(cached, null, 2));
|
|
647002
647284
|
} catch {
|
|
647003
647285
|
}
|
|
647004
647286
|
}
|
|
@@ -647202,7 +647484,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647202
647484
|
}
|
|
647203
647485
|
if (models.length > 0) {
|
|
647204
647486
|
try {
|
|
647205
|
-
const { writeFileSync:
|
|
647487
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106 } = await import("node:fs");
|
|
647206
647488
|
const { join: join179, dirname: dirname54 } = await import("node:path");
|
|
647207
647489
|
const cachePath2 = join179(
|
|
647208
647490
|
ctx3.repoRoot || process.cwd(),
|
|
@@ -647211,7 +647493,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647211
647493
|
"peer-models-cache.json"
|
|
647212
647494
|
);
|
|
647213
647495
|
mkdirSync106(dirname54(cachePath2), { recursive: true });
|
|
647214
|
-
|
|
647496
|
+
writeFileSync90(
|
|
647215
647497
|
cachePath2,
|
|
647216
647498
|
JSON.stringify(
|
|
647217
647499
|
{
|
|
@@ -647285,7 +647567,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647285
647567
|
"Live model probe failed; using sponsor directory model advertisement."
|
|
647286
647568
|
);
|
|
647287
647569
|
try {
|
|
647288
|
-
const { writeFileSync:
|
|
647570
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106 } = await import("node:fs");
|
|
647289
647571
|
const { join: join179, dirname: dirname54 } = await import("node:path");
|
|
647290
647572
|
const cachePath2 = join179(
|
|
647291
647573
|
ctx3.repoRoot || process.cwd(),
|
|
@@ -647294,7 +647576,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647294
647576
|
"peer-models-cache.json"
|
|
647295
647577
|
);
|
|
647296
647578
|
mkdirSync106(dirname54(cachePath2), { recursive: true });
|
|
647297
|
-
|
|
647579
|
+
writeFileSync90(
|
|
647298
647580
|
cachePath2,
|
|
647299
647581
|
JSON.stringify(
|
|
647300
647582
|
{
|
|
@@ -649992,13 +650274,13 @@ var init_commands = __esm({
|
|
|
649992
650274
|
try {
|
|
649993
650275
|
const { randomBytes: randomBytes30 } = await import("node:crypto");
|
|
649994
650276
|
const { homedir: homedir62 } = await import("node:os");
|
|
649995
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
650277
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
649996
650278
|
const { join: join179 } = await import("node:path");
|
|
649997
650279
|
const apiKey = randomBytes30(16).toString("hex");
|
|
649998
650280
|
process.env["OMNIUS_API_KEY"] = apiKey;
|
|
649999
650281
|
const dir = join179(homedir62(), ".omnius");
|
|
650000
650282
|
mkdirSync106(dir, { recursive: true });
|
|
650001
|
-
|
|
650283
|
+
writeFileSync90(join179(dir, "api.key"), apiKey + "\n", "utf8");
|
|
650002
650284
|
renderInfo(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
650003
650285
|
renderInfo(
|
|
650004
650286
|
"Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it."
|
|
@@ -650017,11 +650299,11 @@ var init_commands = __esm({
|
|
|
650017
650299
|
const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
650018
650300
|
try {
|
|
650019
650301
|
const { homedir: homedir62 } = await import("node:os");
|
|
650020
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
650302
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
650021
650303
|
const { join: join179 } = await import("node:path");
|
|
650022
650304
|
const dir = join179(homedir62(), ".omnius");
|
|
650023
650305
|
mkdirSync106(dir, { recursive: true });
|
|
650024
|
-
|
|
650306
|
+
writeFileSync90(join179(dir, "access"), `${val}
|
|
650025
650307
|
`, "utf8");
|
|
650026
650308
|
} catch {
|
|
650027
650309
|
}
|
|
@@ -661171,6 +661453,175 @@ var init_soul_observations = __esm({
|
|
|
661171
661453
|
}
|
|
661172
661454
|
});
|
|
661173
661455
|
|
|
661456
|
+
// packages/cli/src/tui/visual-object-association.ts
|
|
661457
|
+
var visual_object_association_exports = {};
|
|
661458
|
+
__export(visual_object_association_exports, {
|
|
661459
|
+
associateVisualObjectFromImage: () => associateVisualObjectFromImage,
|
|
661460
|
+
extractExplicitVisualObjectLabels: () => extractExplicitVisualObjectLabels,
|
|
661461
|
+
formatVisualObjectMemoryContext: () => formatVisualObjectMemoryContext
|
|
661462
|
+
});
|
|
661463
|
+
import { basename as basename35 } from "node:path";
|
|
661464
|
+
function stringValue2(value2) {
|
|
661465
|
+
return typeof value2 === "string" ? value2.trim() : "";
|
|
661466
|
+
}
|
|
661467
|
+
function stringList(value2) {
|
|
661468
|
+
if (Array.isArray(value2)) {
|
|
661469
|
+
return value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
|
|
661470
|
+
}
|
|
661471
|
+
const single = stringValue2(value2);
|
|
661472
|
+
return single ? [single] : [];
|
|
661473
|
+
}
|
|
661474
|
+
function splitLabels(value2) {
|
|
661475
|
+
return value2.split(/[;,]/).map((part) => part.trim()).filter(Boolean).slice(0, 12);
|
|
661476
|
+
}
|
|
661477
|
+
function normalizeLabel(value2) {
|
|
661478
|
+
return value2.replace(/\s+/g, " ").replace(/^["'`]+|["'`]+$/g, "").trim();
|
|
661479
|
+
}
|
|
661480
|
+
function uniqueLabels(values) {
|
|
661481
|
+
const seen = /* @__PURE__ */ new Set();
|
|
661482
|
+
const out = [];
|
|
661483
|
+
for (const raw of values) {
|
|
661484
|
+
const label = normalizeLabel(raw);
|
|
661485
|
+
const key = label.toLowerCase();
|
|
661486
|
+
if (!label || seen.has(key)) continue;
|
|
661487
|
+
seen.add(key);
|
|
661488
|
+
out.push(label);
|
|
661489
|
+
}
|
|
661490
|
+
return out;
|
|
661491
|
+
}
|
|
661492
|
+
function explicitCaptionLabels(caption) {
|
|
661493
|
+
const text2 = stringValue2(caption);
|
|
661494
|
+
if (!text2) return [];
|
|
661495
|
+
const match = text2.match(/^\s*(?:object[_ -]?label|object|label|labels)\s*:\s*(.+)$/i);
|
|
661496
|
+
return match?.[1] ? splitLabels(match[1]) : [];
|
|
661497
|
+
}
|
|
661498
|
+
function identityNames(payload) {
|
|
661499
|
+
const names = /* @__PURE__ */ new Set();
|
|
661500
|
+
const add3 = (value2) => {
|
|
661501
|
+
const name10 = normalizeLabel(String(value2 ?? ""));
|
|
661502
|
+
if (name10) names.add(name10.toLowerCase());
|
|
661503
|
+
};
|
|
661504
|
+
for (const key of ["person", "person_name", "personName", "face_name", "faceName"]) {
|
|
661505
|
+
add3(payload[key]);
|
|
661506
|
+
}
|
|
661507
|
+
for (const person of stringList(payload["people"])) add3(person);
|
|
661508
|
+
const assertions = Array.isArray(payload["identityAssertions"]) ? payload["identityAssertions"] : Array.isArray(payload["identity_assertions"]) ? payload["identity_assertions"] : [];
|
|
661509
|
+
for (const item of assertions) {
|
|
661510
|
+
if (item && typeof item === "object") add3(item["name"]);
|
|
661511
|
+
}
|
|
661512
|
+
return names;
|
|
661513
|
+
}
|
|
661514
|
+
function isRejectedObjectLabel(label, payload) {
|
|
661515
|
+
const key = normalizeLabel(label).toLowerCase();
|
|
661516
|
+
if (!key) return true;
|
|
661517
|
+
if (/^(visual_identity|pending_visual_identity|person|face|speaker)(?:[_:\s-]|$)/i.test(label)) return true;
|
|
661518
|
+
if (identityNames(payload).has(key)) return true;
|
|
661519
|
+
return false;
|
|
661520
|
+
}
|
|
661521
|
+
function extractExplicitVisualObjectLabels(payload) {
|
|
661522
|
+
const media = payload["media"] && typeof payload["media"] === "object" ? payload["media"] : {};
|
|
661523
|
+
const candidates = uniqueLabels([
|
|
661524
|
+
...stringList(payload["object_label"]),
|
|
661525
|
+
...stringList(payload["objectLabel"]),
|
|
661526
|
+
...stringList(payload["object_labels"]),
|
|
661527
|
+
...stringList(payload["objectLabels"]),
|
|
661528
|
+
...stringList(payload["visualObjectLabel"]),
|
|
661529
|
+
...stringList(payload["visual_object_label"]),
|
|
661530
|
+
...stringList(payload["visualObjectLabels"]),
|
|
661531
|
+
...stringList(payload["visual_object_labels"]),
|
|
661532
|
+
...stringList(payload["label"]),
|
|
661533
|
+
...stringList(payload["labels"]),
|
|
661534
|
+
...stringList(media["objectLabel"]),
|
|
661535
|
+
...stringList(media["object_label"]),
|
|
661536
|
+
...stringList(media["objectLabels"]),
|
|
661537
|
+
...stringList(media["object_labels"]),
|
|
661538
|
+
...stringList(media["label"]),
|
|
661539
|
+
...stringList(media["labels"]),
|
|
661540
|
+
...explicitCaptionLabels(payload["caption"]),
|
|
661541
|
+
...explicitCaptionLabels(media["caption"])
|
|
661542
|
+
]).filter((label) => !isRejectedObjectLabel(label, payload));
|
|
661543
|
+
const aliases = uniqueLabels([
|
|
661544
|
+
...stringList(payload["aliases"]),
|
|
661545
|
+
...stringList(payload["object_aliases"]),
|
|
661546
|
+
...stringList(payload["objectAliases"]),
|
|
661547
|
+
...stringList(payload["visualObjectAliases"]),
|
|
661548
|
+
...stringList(payload["visual_object_aliases"]),
|
|
661549
|
+
...stringList(media["aliases"]),
|
|
661550
|
+
...stringList(media["objectAliases"]),
|
|
661551
|
+
...stringList(media["object_aliases"]),
|
|
661552
|
+
...candidates.slice(1)
|
|
661553
|
+
]).filter((label) => !isRejectedObjectLabel(label, payload));
|
|
661554
|
+
return {
|
|
661555
|
+
label: candidates[0],
|
|
661556
|
+
aliases,
|
|
661557
|
+
source: candidates.length > 0 ? "explicit_visual_object_label" : void 0
|
|
661558
|
+
};
|
|
661559
|
+
}
|
|
661560
|
+
function formatVisualObjectMemoryContext(result) {
|
|
661561
|
+
if (!result.taught || !result.label) return "";
|
|
661562
|
+
const lines = [
|
|
661563
|
+
"Visual Object Memory",
|
|
661564
|
+
`- Learned object label: ${result.label}`
|
|
661565
|
+
];
|
|
661566
|
+
if (result.aliases.length > 0) lines.push(`- Aliases: ${result.aliases.join(", ")}`);
|
|
661567
|
+
return lines.join("\n");
|
|
661568
|
+
}
|
|
661569
|
+
async function associateVisualObjectFromImage(options2) {
|
|
661570
|
+
const payload = options2.payload ?? {};
|
|
661571
|
+
const extraction = extractExplicitVisualObjectLabels({
|
|
661572
|
+
...payload,
|
|
661573
|
+
media: options2.media ?? payload["media"]
|
|
661574
|
+
});
|
|
661575
|
+
if (!extraction.label) {
|
|
661576
|
+
return {
|
|
661577
|
+
attempted: false,
|
|
661578
|
+
taught: false,
|
|
661579
|
+
aliases: [],
|
|
661580
|
+
contextBlock: ""
|
|
661581
|
+
};
|
|
661582
|
+
}
|
|
661583
|
+
const visual = options2.visualMemoryTool ?? new VisualMemoryTool();
|
|
661584
|
+
const aliases = uniqueLabels(extraction.aliases.filter((alias) => alias.toLowerCase() !== extraction.label.toLowerCase()));
|
|
661585
|
+
const labels = uniqueLabels([extraction.label, ...aliases]);
|
|
661586
|
+
const teach = await visual.execute({
|
|
661587
|
+
action: "teach",
|
|
661588
|
+
image: options2.imagePath,
|
|
661589
|
+
label: extraction.label,
|
|
661590
|
+
aliases,
|
|
661591
|
+
labels,
|
|
661592
|
+
sourceSurface: options2.sourceSurface,
|
|
661593
|
+
sessionId: options2.sessionId,
|
|
661594
|
+
fileUniqueId: options2.media?.fileUniqueId
|
|
661595
|
+
});
|
|
661596
|
+
if (!teach.success) {
|
|
661597
|
+
return {
|
|
661598
|
+
attempted: true,
|
|
661599
|
+
taught: false,
|
|
661600
|
+
label: extraction.label,
|
|
661601
|
+
aliases,
|
|
661602
|
+
contextBlock: "",
|
|
661603
|
+
output: teach.output,
|
|
661604
|
+
degradedReason: teach.error || teach.output || `visual_memory teach failed for ${basename35(options2.imagePath)}`
|
|
661605
|
+
};
|
|
661606
|
+
}
|
|
661607
|
+
const result = {
|
|
661608
|
+
attempted: true,
|
|
661609
|
+
taught: true,
|
|
661610
|
+
label: extraction.label,
|
|
661611
|
+
aliases,
|
|
661612
|
+
contextBlock: "",
|
|
661613
|
+
output: teach.output
|
|
661614
|
+
};
|
|
661615
|
+
result.contextBlock = formatVisualObjectMemoryContext(result);
|
|
661616
|
+
return result;
|
|
661617
|
+
}
|
|
661618
|
+
var init_visual_object_association = __esm({
|
|
661619
|
+
"packages/cli/src/tui/visual-object-association.ts"() {
|
|
661620
|
+
"use strict";
|
|
661621
|
+
init_dist5();
|
|
661622
|
+
}
|
|
661623
|
+
});
|
|
661624
|
+
|
|
661174
661625
|
// packages/cli/src/tui/telegram-channel-dmn.ts
|
|
661175
661626
|
import {
|
|
661176
661627
|
existsSync as existsSync144,
|
|
@@ -663671,55 +664122,16 @@ function advancedOcr(imagePath) {
|
|
|
663671
664122
|
async function queryVisionModel(modelName, imagePath, prompt = "Describe what you see in this image in detail. Include any text, UI elements, code, diagrams, or visual content.") {
|
|
663672
664123
|
if (!isVisionModel(modelName)) return "";
|
|
663673
664124
|
if (!existsSync145(imagePath)) return "";
|
|
663674
|
-
const imageBuffer = readFileSync118(imagePath);
|
|
663675
|
-
const base64Image = imageBuffer.toString("base64");
|
|
663676
|
-
const broker = getModelBroker();
|
|
663677
|
-
const decision2 = await broker.ensureModelLoadable({
|
|
663678
|
-
name: modelName,
|
|
663679
|
-
domain: "vision",
|
|
663680
|
-
host: "ollama",
|
|
663681
|
-
owner: "vision-ingress",
|
|
663682
|
-
requestedNumCtx: 2048
|
|
663683
|
-
});
|
|
663684
|
-
let effectiveModel = modelName;
|
|
663685
|
-
let numCtx;
|
|
663686
|
-
if (decision2.kind === "reject") {
|
|
663687
|
-
return "";
|
|
663688
|
-
} else if (decision2.kind === "degrade") {
|
|
663689
|
-
effectiveModel = decision2.fallback.name;
|
|
663690
|
-
} else if (decision2.kind === "evict") {
|
|
663691
|
-
for (const target of decision2.evictTargets) {
|
|
663692
|
-
await broker.evict(target.host, target.name, "make-room-for-vision");
|
|
663693
|
-
}
|
|
663694
|
-
numCtx = decision2.effectiveNumCtx;
|
|
663695
|
-
} else if (decision2.kind === "ok") {
|
|
663696
|
-
numCtx = decision2.effectiveNumCtx;
|
|
663697
|
-
} else if (decision2.kind === "wait-for-inflight") {
|
|
663698
|
-
const inner = await decision2.promise;
|
|
663699
|
-
if (inner.kind === "ok") numCtx = inner.effectiveNumCtx;
|
|
663700
|
-
else if (inner.kind === "degrade") effectiveModel = inner.fallback.name;
|
|
663701
|
-
else if (inner.kind === "reject") return "";
|
|
663702
|
-
}
|
|
663703
|
-
if (numCtx === void 0) {
|
|
663704
|
-
const trainCtx = await broker.getNctxTrain(effectiveModel);
|
|
663705
|
-
numCtx = trainCtx && trainCtx > 0 ? Math.min(trainCtx, 4096) : 2048;
|
|
663706
|
-
}
|
|
663707
664125
|
try {
|
|
663708
|
-
const
|
|
663709
|
-
|
|
663710
|
-
|
|
663711
|
-
|
|
663712
|
-
|
|
663713
|
-
|
|
663714
|
-
images: [base64Image],
|
|
663715
|
-
stream: false,
|
|
663716
|
-
options: { temperature: 0.3, num_predict: 1024, num_ctx: numCtx }
|
|
663717
|
-
})
|
|
664126
|
+
const tool = new VisionTool(process.cwd());
|
|
664127
|
+
const result = await tool.execute({
|
|
664128
|
+
image: imagePath,
|
|
664129
|
+
action: "query",
|
|
664130
|
+
prompt,
|
|
664131
|
+
model: modelName
|
|
663718
664132
|
});
|
|
663719
|
-
if (!
|
|
663720
|
-
|
|
663721
|
-
const data = await response.json();
|
|
663722
|
-
return (data.response || "").trim();
|
|
664133
|
+
if (!result.success) return "";
|
|
664134
|
+
return String(result.llmContent || result.output || "").trim();
|
|
663723
664135
|
} catch {
|
|
663724
664136
|
return "";
|
|
663725
664137
|
}
|
|
@@ -663790,13 +664202,13 @@ import {
|
|
|
663790
664202
|
statSync as statSync50,
|
|
663791
664203
|
statfsSync as statfsSync7,
|
|
663792
664204
|
readFileSync as readFileSync119,
|
|
663793
|
-
writeFileSync as
|
|
664205
|
+
writeFileSync as writeFileSync77,
|
|
663794
664206
|
appendFileSync as appendFileSync15
|
|
663795
664207
|
} from "node:fs";
|
|
663796
664208
|
import {
|
|
663797
664209
|
join as join158,
|
|
663798
664210
|
resolve as resolve62,
|
|
663799
|
-
basename as
|
|
664211
|
+
basename as basename36,
|
|
663800
664212
|
relative as relative16,
|
|
663801
664213
|
isAbsolute as isAbsolute11,
|
|
663802
664214
|
extname as extname21
|
|
@@ -666265,6 +666677,7 @@ var init_telegram_bridge = __esm({
|
|
|
666265
666677
|
init_soul_observations();
|
|
666266
666678
|
init_identity_memory_tool();
|
|
666267
666679
|
init_visual_identity_association();
|
|
666680
|
+
init_visual_object_association();
|
|
666268
666681
|
init_telegram_channel_dmn();
|
|
666269
666682
|
init_telegram_reflection_corpus();
|
|
666270
666683
|
init_memory_paths();
|
|
@@ -669265,6 +669678,14 @@ ${mediaContext}` : ""
|
|
|
669265
669678
|
const messageText = isReplyMedia ? msg.replyContext?.text || msg.replyContext?.caption || msg.replyToText || media.caption : msg.text || media.caption;
|
|
669266
669679
|
const sender = isReplyMedia ? this.telegramMemorySenderFromReply(msg) : this.telegramMemorySenderFromMessage(msg);
|
|
669267
669680
|
const modality = media.type === "audio" || media.type === "voice" ? "audio" : telegramMediaIsImage(media) ? "visual" : "text";
|
|
669681
|
+
const objectLabels = extractExplicitVisualObjectLabels({
|
|
669682
|
+
caption: media.caption,
|
|
669683
|
+
media: { caption: media.caption }
|
|
669684
|
+
});
|
|
669685
|
+
const structuredObjectLabels = [
|
|
669686
|
+
objectLabels.label,
|
|
669687
|
+
...objectLabels.aliases
|
|
669688
|
+
].filter((label) => typeof label === "string" && label.trim().length > 0);
|
|
669268
669689
|
const payload = {
|
|
669269
669690
|
sourceSurface: "telegram",
|
|
669270
669691
|
sessionId: this.sessionKeyForMessage(msg),
|
|
@@ -669300,8 +669721,12 @@ ${mediaContext}` : ""
|
|
|
669300
669721
|
sender_id: sender?.id,
|
|
669301
669722
|
username: sender?.username,
|
|
669302
669723
|
display_name: sender?.displayName,
|
|
669303
|
-
labels:
|
|
669724
|
+
labels: structuredObjectLabels
|
|
669304
669725
|
};
|
|
669726
|
+
if (objectLabels.label) {
|
|
669727
|
+
payload.object_label = objectLabels.label;
|
|
669728
|
+
payload.aliases = objectLabels.aliases;
|
|
669729
|
+
}
|
|
669305
669730
|
if (extractedContent) {
|
|
669306
669731
|
if (modality === "audio") payload.transcript = extractedContent;
|
|
669307
669732
|
else payload.extractedContent = extractedContent;
|
|
@@ -670202,7 +670627,7 @@ ${mediaContext}` : ""
|
|
|
670202
670627
|
autoFollowup: false
|
|
670203
670628
|
}
|
|
670204
670629
|
};
|
|
670205
|
-
|
|
670630
|
+
writeFileSync77(
|
|
670206
670631
|
this.telegramConversationPath(sessionKey),
|
|
670207
670632
|
JSON.stringify(payload, null, 2) + "\n",
|
|
670208
670633
|
"utf8"
|
|
@@ -671031,7 +671456,7 @@ ${mediaContext}` : ""
|
|
|
671031
671456
|
}
|
|
671032
671457
|
const matchingEntry = mediaEntries.find((entry) => {
|
|
671033
671458
|
if (resolve62(entry.localPath) === resolve62(raw)) return true;
|
|
671034
|
-
if (
|
|
671459
|
+
if (basename36(entry.localPath) === raw) return true;
|
|
671035
671460
|
if (entry.fileUniqueId === raw || entry.fileId === raw) return true;
|
|
671036
671461
|
if (entry.messageId && String(entry.messageId) === raw) return true;
|
|
671037
671462
|
if (entry.messageId && `message_id:${entry.messageId}` === raw.toLowerCase())
|
|
@@ -671072,7 +671497,7 @@ ${mediaContext}` : ""
|
|
|
671072
671497
|
sourceMessageId,
|
|
671073
671498
|
chatKey,
|
|
671074
671499
|
mediaKind,
|
|
671075
|
-
safeAlias:
|
|
671500
|
+
safeAlias: basename36(result.path)
|
|
671076
671501
|
}
|
|
671077
671502
|
};
|
|
671078
671503
|
}
|
|
@@ -671113,7 +671538,7 @@ ${mediaContext}` : ""
|
|
|
671113
671538
|
}
|
|
671114
671539
|
return entries.find((entry2) => {
|
|
671115
671540
|
if (resolve62(entry2.localPath) === resolve62(ref)) return true;
|
|
671116
|
-
if (
|
|
671541
|
+
if (basename36(entry2.localPath) === ref) return true;
|
|
671117
671542
|
if (entry2.fileUniqueId === ref || entry2.fileId === ref) return true;
|
|
671118
671543
|
if (entry2.messageId && String(entry2.messageId) === ref) return true;
|
|
671119
671544
|
return false;
|
|
@@ -671141,7 +671566,7 @@ ${mediaContext}` : ""
|
|
|
671141
671566
|
caption: entry.caption
|
|
671142
671567
|
},
|
|
671143
671568
|
modality,
|
|
671144
|
-
label: `Telegram message_id ${entry.messageId || "unknown"} ${
|
|
671569
|
+
label: `Telegram message_id ${entry.messageId || "unknown"} ${basename36(entry.localPath)}`,
|
|
671145
671570
|
extractedContent: entry.extractedContent
|
|
671146
671571
|
};
|
|
671147
671572
|
}
|
|
@@ -672307,8 +672732,8 @@ ${cardLines.join("\n")}`
|
|
|
672307
672732
|
const caption = entry.caption ? ` caption=${telegramContextJsonString(entry.caption, 120)}` : "";
|
|
672308
672733
|
const extracted = entry.extractedContent ? `
|
|
672309
672734
|
extracted=${telegramContextJsonString(entry.extractedContent.replace(/\s+/g, " "), 220)}` : "";
|
|
672310
|
-
const alias = entry.messageId ? `message_id:${entry.messageId}` :
|
|
672311
|
-
return `- ${alias}${replyMark}: ${kind}; file ${
|
|
672735
|
+
const alias = entry.messageId ? `message_id:${entry.messageId}` : basename36(entry.localPath);
|
|
672736
|
+
return `- ${alias}${replyMark}: ${kind}; file ${basename36(entry.localPath)}${caption}${extracted}`;
|
|
672312
672737
|
});
|
|
672313
672738
|
sections.push(
|
|
672314
672739
|
[
|
|
@@ -674805,7 +675230,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`
|
|
|
674805
675230
|
throw e2;
|
|
674806
675231
|
}
|
|
674807
675232
|
}
|
|
674808
|
-
|
|
675233
|
+
writeFileSync77(
|
|
674809
675234
|
lockFile,
|
|
674810
675235
|
JSON.stringify(
|
|
674811
675236
|
{
|
|
@@ -679758,7 +680183,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
679758
680183
|
}
|
|
679759
680184
|
writeTelegramToolButtonState(state) {
|
|
679760
680185
|
mkdirSync89(this.telegramToolButtonDir, { recursive: true });
|
|
679761
|
-
|
|
680186
|
+
writeFileSync77(
|
|
679762
680187
|
this.telegramToolButtonPath(state.nonce),
|
|
679763
680188
|
JSON.stringify(state, null, 2) + "\n",
|
|
679764
680189
|
"utf-8"
|
|
@@ -680661,12 +681086,12 @@ Advanced text extraction signal: chars=${advancedSignal.chars}, lines=${advanced
|
|
|
680661
681086
|
};
|
|
680662
681087
|
}
|
|
680663
681088
|
const lines = entries.map((entry, index) => {
|
|
680664
|
-
const pathAlias = entry.messageId ? `message_id:${entry.messageId}` :
|
|
681089
|
+
const pathAlias = entry.messageId ? `message_id:${entry.messageId}` : basename36(entry.localPath);
|
|
680665
681090
|
const parts = [
|
|
680666
681091
|
`${index + 1}. message_id ${entry.messageId || "unknown"}`,
|
|
680667
681092
|
currentMsg?.replyToMessageId === entry.messageId ? "replied-to" : "",
|
|
680668
681093
|
telegramCachedMediaIsImage(entry) ? "image" : telegramCachedMediaIsPdf(entry) ? "pdf" : telegramCachedMediaIsAudio(entry) ? "audio" : telegramCachedMediaIsVideo(entry) ? "video" : entry.mediaType,
|
|
680669
|
-
`file=${
|
|
681094
|
+
`file=${basename36(entry.localPath)}`,
|
|
680670
681095
|
`path_alias=${pathAlias}`,
|
|
680671
681096
|
entry.caption ? `caption=${telegramContextJsonString(entry.caption, 140)}` : ""
|
|
680672
681097
|
].filter(Boolean);
|
|
@@ -680849,8 +681274,8 @@ Advanced text extraction signal: chars=${advancedSignal.chars}, lines=${advanced
|
|
|
680849
681274
|
)) {
|
|
680850
681275
|
return {
|
|
680851
681276
|
success: true,
|
|
680852
|
-
output: `Telegram file already sent in this turn: ${
|
|
680853
|
-
llmContent: `Already sent ${
|
|
681277
|
+
output: `Telegram file already sent in this turn: ${basename36(file.path)} as ${kind} to ${String(target.chatId)}`,
|
|
681278
|
+
llmContent: `Already sent ${basename36(file.path)} to Telegram as ${kind}; do not send it again.`,
|
|
680854
681279
|
durationMs: performance.now() - start2,
|
|
680855
681280
|
mutated: false,
|
|
680856
681281
|
mutatedFiles: []
|
|
@@ -680877,8 +681302,8 @@ Advanced text extraction signal: chars=${advancedSignal.chars}, lines=${advanced
|
|
|
680877
681302
|
);
|
|
680878
681303
|
return {
|
|
680879
681304
|
success: true,
|
|
680880
|
-
output: `Sent Telegram file: ${
|
|
680881
|
-
llmContent: `Sent ${
|
|
681305
|
+
output: `Sent Telegram file: ${basename36(file.path)} as ${kind} to ${String(target.chatId)}${messageId ? ` (message_id ${messageId})` : ""}`,
|
|
681306
|
+
llmContent: `Sent ${basename36(file.path)} to Telegram as ${kind}.`,
|
|
680882
681307
|
durationMs: performance.now() - start2,
|
|
680883
681308
|
mutated: false,
|
|
680884
681309
|
mutatedFiles: []
|
|
@@ -681164,6 +681589,7 @@ ${visionContext}]`;
|
|
|
681164
681589
|
cacheEntry.extractedContent
|
|
681165
681590
|
);
|
|
681166
681591
|
let visualIdentityContext = "";
|
|
681592
|
+
let visualObjectContext = "";
|
|
681167
681593
|
let ingestReachedDaemon = false;
|
|
681168
681594
|
try {
|
|
681169
681595
|
const ingestResponse = await fetch(
|
|
@@ -681181,6 +681607,9 @@ ${visionContext}]`;
|
|
|
681181
681607
|
const block = ingested?.visualIdentity?.contextBlock;
|
|
681182
681608
|
if (typeof block === "string" && block.trim())
|
|
681183
681609
|
visualIdentityContext = block.trim();
|
|
681610
|
+
const objectBlock = ingested?.visualObjectMemory?.contextBlock;
|
|
681611
|
+
if (typeof objectBlock === "string" && objectBlock.trim())
|
|
681612
|
+
visualObjectContext = objectBlock.trim();
|
|
681184
681613
|
}
|
|
681185
681614
|
} catch {
|
|
681186
681615
|
}
|
|
@@ -681202,8 +681631,29 @@ ${visionContext}]`;
|
|
|
681202
681631
|
visualIdentityContext = association.contextBlock;
|
|
681203
681632
|
} catch {
|
|
681204
681633
|
}
|
|
681634
|
+
try {
|
|
681635
|
+
const objectMemory = await associateVisualObjectFromImage({
|
|
681636
|
+
repoRoot: this.repoRoot,
|
|
681637
|
+
imagePath: localPath,
|
|
681638
|
+
sourceSurface: "telegram",
|
|
681639
|
+
scope: ingestPayload["scope"],
|
|
681640
|
+
sender: ingestPayload["sender"],
|
|
681641
|
+
message: ingestPayload["message"],
|
|
681642
|
+
replyTo: ingestPayload["replyTo"],
|
|
681643
|
+
sessionId: typeof ingestPayload["sessionId"] === "string" ? ingestPayload["sessionId"] : this.sessionKeyForMessage(msg),
|
|
681644
|
+
media: ingestPayload["media"],
|
|
681645
|
+
extractedContent: cacheEntry.extractedContent,
|
|
681646
|
+
payload: ingestPayload
|
|
681647
|
+
});
|
|
681648
|
+
if (objectMemory.contextBlock)
|
|
681649
|
+
visualObjectContext = objectMemory.contextBlock;
|
|
681650
|
+
} catch {
|
|
681651
|
+
}
|
|
681205
681652
|
}
|
|
681206
|
-
description = appendMediaContextBlock(
|
|
681653
|
+
description = appendMediaContextBlock(
|
|
681654
|
+
description,
|
|
681655
|
+
[visualIdentityContext, visualObjectContext].filter(Boolean).join("\n\n")
|
|
681656
|
+
);
|
|
681207
681657
|
} else if (isImageMedia) {
|
|
681208
681658
|
description = `[${sourceLabel}image received: path_alias=${mediaAlias}${safeCaption}. Full visual comprehension pending; use image='${source === "reply" ? "reply" : "latest"}' or image='${mediaAlias}' with telegram_image_analyze detail='full'.]`;
|
|
681209
681659
|
cacheEntry.analysisComplete = false;
|
|
@@ -681512,7 +681962,7 @@ ${text2}`.trim()
|
|
|
681512
681962
|
throw new Error(`File does not exist: ${media.value}`);
|
|
681513
681963
|
const buffer2 = readFileSync119(media.value);
|
|
681514
681964
|
const boundary = `----omnius-media-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
681515
|
-
const filename =
|
|
681965
|
+
const filename = basename36(media.value);
|
|
681516
681966
|
const contentType = mimeForPath(media.value, media.kind);
|
|
681517
681967
|
const parts = [];
|
|
681518
681968
|
const addField = (name10, value2) => {
|
|
@@ -681750,7 +682200,7 @@ Content-Type: ${contentType}\r
|
|
|
681750
682200
|
audioAsVoice: false
|
|
681751
682201
|
},
|
|
681752
682202
|
{
|
|
681753
|
-
caption: `Vision action loop screenshot: ${
|
|
682203
|
+
caption: `Vision action loop screenshot: ${basename36(abs)}`
|
|
681754
682204
|
}
|
|
681755
682205
|
).catch(() => null);
|
|
681756
682206
|
}
|
|
@@ -681830,7 +682280,7 @@ Content-Type: ${contentType}\r
|
|
|
681830
682280
|
continue;
|
|
681831
682281
|
}
|
|
681832
682282
|
const buffer2 = readFileSync119(pathOrFileId);
|
|
681833
|
-
const filename =
|
|
682283
|
+
const filename = basename36(pathOrFileId);
|
|
681834
682284
|
parts.push(Buffer.from(`--${boundary}\r
|
|
681835
682285
|
`));
|
|
681836
682286
|
parts.push(
|
|
@@ -683607,9 +684057,9 @@ __export(projects_exports, {
|
|
|
683607
684057
|
setCurrentProject: () => setCurrentProject,
|
|
683608
684058
|
unregisterProject: () => unregisterProject
|
|
683609
684059
|
});
|
|
683610
|
-
import { readFileSync as readFileSync120, writeFileSync as
|
|
684060
|
+
import { readFileSync as readFileSync120, writeFileSync as writeFileSync78, mkdirSync as mkdirSync90, existsSync as existsSync147, statSync as statSync51, renameSync as renameSync12 } from "node:fs";
|
|
683611
684061
|
import { homedir as homedir52 } from "node:os";
|
|
683612
|
-
import { basename as
|
|
684062
|
+
import { basename as basename37, join as join159, resolve as resolve63 } from "node:path";
|
|
683613
684063
|
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
683614
684064
|
function readAll2() {
|
|
683615
684065
|
try {
|
|
@@ -683625,7 +684075,7 @@ function readAll2() {
|
|
|
683625
684075
|
function writeAll(file) {
|
|
683626
684076
|
mkdirSync90(OMNIUS_DIR3, { recursive: true });
|
|
683627
684077
|
const tmp = `${PROJECTS_FILE}.${randomUUID19().slice(0, 8)}.tmp`;
|
|
683628
|
-
|
|
684078
|
+
writeFileSync78(tmp, JSON.stringify(file, null, 2), "utf8");
|
|
683629
684079
|
renameSync12(tmp, PROJECTS_FILE);
|
|
683630
684080
|
}
|
|
683631
684081
|
function listProjects() {
|
|
@@ -683657,7 +684107,7 @@ function registerProject(root, pid) {
|
|
|
683657
684107
|
} else {
|
|
683658
684108
|
entry = {
|
|
683659
684109
|
root: canonical,
|
|
683660
|
-
name:
|
|
684110
|
+
name: basename37(canonical) || canonical,
|
|
683661
684111
|
firstSeen: now2,
|
|
683662
684112
|
lastSeen: now2,
|
|
683663
684113
|
pid: pid ?? null,
|
|
@@ -683708,7 +684158,7 @@ function setCurrentProject(root) {
|
|
|
683708
684158
|
currentRoot = canonical;
|
|
683709
684159
|
try {
|
|
683710
684160
|
mkdirSync90(OMNIUS_DIR3, { recursive: true });
|
|
683711
|
-
|
|
684161
|
+
writeFileSync78(CURRENT_FILE, `${canonical}
|
|
683712
684162
|
`, "utf8");
|
|
683713
684163
|
} catch {
|
|
683714
684164
|
}
|
|
@@ -684605,7 +685055,7 @@ var init_access_policy = __esm({
|
|
|
684605
685055
|
|
|
684606
685056
|
// packages/cli/src/api/project-preferences.ts
|
|
684607
685057
|
import { createHash as createHash42 } from "node:crypto";
|
|
684608
|
-
import { existsSync as existsSync148, mkdirSync as mkdirSync91, readFileSync as readFileSync121, renameSync as renameSync13, writeFileSync as
|
|
685058
|
+
import { existsSync as existsSync148, mkdirSync as mkdirSync91, readFileSync as readFileSync121, renameSync as renameSync13, writeFileSync as writeFileSync79, unlinkSync as unlinkSync34 } from "node:fs";
|
|
684609
685059
|
import { homedir as homedir53 } from "node:os";
|
|
684610
685060
|
import { join as join160, resolve as resolve64 } from "node:path";
|
|
684611
685061
|
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
@@ -684628,7 +685078,7 @@ function ensureDir(root) {
|
|
|
684628
685078
|
const sentinel = rootSentinelPath(root);
|
|
684629
685079
|
try {
|
|
684630
685080
|
if (!existsSync148(sentinel)) {
|
|
684631
|
-
|
|
685081
|
+
writeFileSync79(sentinel, `${resolve64(root)}
|
|
684632
685082
|
`, "utf8");
|
|
684633
685083
|
}
|
|
684634
685084
|
} catch {
|
|
@@ -684657,12 +685107,12 @@ function writeProjectPreferences(root, partial) {
|
|
|
684657
685107
|
};
|
|
684658
685108
|
const file = prefsPath(root);
|
|
684659
685109
|
const tmp = `${file}.${randomUUID20().slice(0, 8)}.tmp`;
|
|
684660
|
-
|
|
685110
|
+
writeFileSync79(tmp, JSON.stringify(merged, null, 2), "utf8");
|
|
684661
685111
|
try {
|
|
684662
685112
|
renameSync13(tmp, file);
|
|
684663
685113
|
} catch (err) {
|
|
684664
685114
|
try {
|
|
684665
|
-
|
|
685115
|
+
writeFileSync79(file, JSON.stringify(merged, null, 2), "utf8");
|
|
684666
685116
|
} catch {
|
|
684667
685117
|
}
|
|
684668
685118
|
try {
|
|
@@ -685067,7 +685517,7 @@ data: ${JSON.stringify(ev)}
|
|
|
685067
685517
|
|
|
685068
685518
|
// packages/cli/src/api/routes-media.ts
|
|
685069
685519
|
import { existsSync as existsSync151, mkdirSync as mkdirSync94, statSync as statSync53, copyFileSync as copyFileSync7, createReadStream } from "node:fs";
|
|
685070
|
-
import { basename as
|
|
685520
|
+
import { basename as basename38, join as join162, resolve as pathResolve2 } from "node:path";
|
|
685071
685521
|
function mediaWorkDir() {
|
|
685072
685522
|
return join162(omniusHomeDir(), "media", "_work");
|
|
685073
685523
|
}
|
|
@@ -685089,7 +685539,7 @@ function extractGeneratedPath(output) {
|
|
|
685089
685539
|
function publishToGallery(srcPath, kind) {
|
|
685090
685540
|
ensureGlobalMediaDirs();
|
|
685091
685541
|
const dir = globalMediaDir(kind);
|
|
685092
|
-
const name10 =
|
|
685542
|
+
const name10 = basename38(srcPath);
|
|
685093
685543
|
const dest = join162(dir, name10);
|
|
685094
685544
|
try {
|
|
685095
685545
|
if (pathResolve2(srcPath) !== pathResolve2(dest)) {
|
|
@@ -685290,7 +685740,7 @@ async function handleAvAnalyze(ctx3) {
|
|
|
685290
685740
|
adapterStatus[role] = a2 && !a2.meta.isMock ? "live" : "mock";
|
|
685291
685741
|
if (adapterStatus[role] === "live") anyLive = true;
|
|
685292
685742
|
}
|
|
685293
|
-
const episodeId = `rest-${
|
|
685743
|
+
const episodeId = `rest-${basename38(filePath)}-${Date.now().toString(36)}`;
|
|
685294
685744
|
const ingest = await ingestMedia(episodeId, `file://${filePath}`);
|
|
685295
685745
|
const store2 = await analyzeEpisode({ episodeId, mediaUri: `file://${filePath}`, durationSec: ingest.source.durationSec, registry: registry4, windows: ingest.shots, roles: AV_ROLES });
|
|
685296
685746
|
const world = store2.snapshot();
|
|
@@ -685460,7 +685910,7 @@ function handleFile(ctx3) {
|
|
|
685460
685910
|
return true;
|
|
685461
685911
|
}
|
|
685462
685912
|
const dir = globalMediaDir(kind);
|
|
685463
|
-
const full = pathResolve2(dir,
|
|
685913
|
+
const full = pathResolve2(dir, basename38(name10));
|
|
685464
685914
|
if (!full.startsWith(pathResolve2(dir)) || !existsSync151(full)) {
|
|
685465
685915
|
sendProblem(ctx3.res, problemDetails({
|
|
685466
685916
|
type: P.notFound,
|
|
@@ -685705,7 +686155,7 @@ var init_direct_tool_registry = __esm({
|
|
|
685705
686155
|
});
|
|
685706
686156
|
|
|
685707
686157
|
// packages/cli/src/api/external-tool-registry.ts
|
|
685708
|
-
import { existsSync as existsSync152, mkdirSync as mkdirSync95, readFileSync as readFileSync123, writeFileSync as
|
|
686158
|
+
import { existsSync as existsSync152, mkdirSync as mkdirSync95, readFileSync as readFileSync123, writeFileSync as writeFileSync80, renameSync as renameSync14 } from "node:fs";
|
|
685709
686159
|
import { join as join163 } from "node:path";
|
|
685710
686160
|
function externalToolStorePath(workingDir) {
|
|
685711
686161
|
return join163(workingDir, ".omnius", "external-tools.json");
|
|
@@ -685728,7 +686178,7 @@ function persist3(workingDir, tools) {
|
|
|
685728
686178
|
mkdirSync95(join163(workingDir, ".omnius"), { recursive: true });
|
|
685729
686179
|
const file = { version: STORE_VERSION, tools };
|
|
685730
686180
|
const tmp = `${path12}.tmp`;
|
|
685731
|
-
|
|
686181
|
+
writeFileSync80(tmp, JSON.stringify(file, null, 2), { mode: 384 });
|
|
685732
686182
|
renameSync14(tmp, path12);
|
|
685733
686183
|
}
|
|
685734
686184
|
function validateManifest2(input, existing) {
|
|
@@ -686840,7 +687290,7 @@ __export(runtime_keys_exports, {
|
|
|
686840
687290
|
mintKey: () => mintKey,
|
|
686841
687291
|
revokeByPrefix: () => revokeByPrefix
|
|
686842
687292
|
});
|
|
686843
|
-
import { existsSync as existsSync154, readFileSync as readFileSync125, writeFileSync as
|
|
687293
|
+
import { existsSync as existsSync154, readFileSync as readFileSync125, writeFileSync as writeFileSync81, mkdirSync as mkdirSync96, chmodSync as chmodSync4 } from "node:fs";
|
|
686844
687294
|
import { join as join165 } from "node:path";
|
|
686845
687295
|
import { homedir as homedir55 } from "node:os";
|
|
686846
687296
|
import { randomBytes as randomBytes27 } from "node:crypto";
|
|
@@ -686861,7 +687311,7 @@ function loadAll() {
|
|
|
686861
687311
|
}
|
|
686862
687312
|
function persistAll(records) {
|
|
686863
687313
|
ensureDir2();
|
|
686864
|
-
|
|
687314
|
+
writeFileSync81(KEYS_FILE, JSON.stringify(records, null, 2), "utf-8");
|
|
686865
687315
|
try {
|
|
686866
687316
|
chmodSync4(KEYS_FILE, 384);
|
|
686867
687317
|
} catch {
|
|
@@ -687095,7 +687545,7 @@ __export(graphical_sudo_exports, {
|
|
|
687095
687545
|
runGraphicalSudo: () => runGraphicalSudo
|
|
687096
687546
|
});
|
|
687097
687547
|
import { spawn as spawn31 } from "node:child_process";
|
|
687098
|
-
import { existsSync as existsSync156, mkdirSync as mkdirSync97, writeFileSync as
|
|
687548
|
+
import { existsSync as existsSync156, mkdirSync as mkdirSync97, writeFileSync as writeFileSync82, chmodSync as chmodSync5 } from "node:fs";
|
|
687099
687549
|
import { join as join167 } from "node:path";
|
|
687100
687550
|
import { tmpdir as tmpdir22 } from "node:os";
|
|
687101
687551
|
function detectSudoHelper() {
|
|
@@ -687131,7 +687581,7 @@ exec zenity --password --title="Omnius needs sudo" --text="${description.replace
|
|
|
687131
687581
|
exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
|
|
687132
687582
|
`;
|
|
687133
687583
|
}
|
|
687134
|
-
|
|
687584
|
+
writeFileSync82(shim, body, "utf-8");
|
|
687135
687585
|
chmodSync5(shim, 493);
|
|
687136
687586
|
return shim;
|
|
687137
687587
|
}
|
|
@@ -702167,7 +702617,7 @@ var init_auth_oidc = __esm({
|
|
|
702167
702617
|
});
|
|
702168
702618
|
|
|
702169
702619
|
// packages/cli/src/api/usage-tracker.ts
|
|
702170
|
-
import { mkdirSync as mkdirSync99, readFileSync as readFileSync128, writeFileSync as
|
|
702620
|
+
import { mkdirSync as mkdirSync99, readFileSync as readFileSync128, writeFileSync as writeFileSync83, existsSync as existsSync158 } from "node:fs";
|
|
702171
702621
|
import { join as join169 } from "node:path";
|
|
702172
702622
|
function initUsageTracker(omniusDir) {
|
|
702173
702623
|
const dir = join169(omniusDir, "usage");
|
|
@@ -702211,7 +702661,7 @@ function flush2() {
|
|
|
702211
702661
|
if (!initialized2 || !dirty) return;
|
|
702212
702662
|
try {
|
|
702213
702663
|
store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
|
|
702214
|
-
|
|
702664
|
+
writeFileSync83(usageFile, JSON.stringify(store, null, 2), "utf-8");
|
|
702215
702665
|
dirty = false;
|
|
702216
702666
|
} catch {
|
|
702217
702667
|
}
|
|
@@ -702386,7 +702836,7 @@ var init_chat_followup = __esm({
|
|
|
702386
702836
|
|
|
702387
702837
|
// packages/cli/src/docker.ts
|
|
702388
702838
|
import { execSync as execSync59, spawn as spawn32 } from "node:child_process";
|
|
702389
|
-
import { existsSync as existsSync159, mkdirSync as mkdirSync100, writeFileSync as
|
|
702839
|
+
import { existsSync as existsSync159, mkdirSync as mkdirSync100, writeFileSync as writeFileSync84 } from "node:fs";
|
|
702390
702840
|
import { join as join170, resolve as resolve65, dirname as dirname50 } from "node:path";
|
|
702391
702841
|
import { homedir as homedir58 } from "node:os";
|
|
702392
702842
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
@@ -702611,8 +703061,8 @@ chown -R node:node /workspace /home/node/.omnius 2>/dev/null || true
|
|
|
702611
703061
|
if [ "$1" = "omnius" ]; then shift; exec su - node -c "cd /workspace && omnius $*"; fi
|
|
702612
703062
|
exec "$@"
|
|
702613
703063
|
`;
|
|
702614
|
-
|
|
702615
|
-
|
|
703064
|
+
writeFileSync84(join170(dir, "Dockerfile"), dockerfile);
|
|
703065
|
+
writeFileSync84(join170(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
702616
703066
|
}
|
|
702617
703067
|
function hasNvidiaGpu() {
|
|
702618
703068
|
try {
|
|
@@ -702685,7 +703135,7 @@ __export(embedding_workers_exports, {
|
|
|
702685
703135
|
startEmbeddingWorkers: () => startEmbeddingWorkers,
|
|
702686
703136
|
stopEmbeddingWorkers: () => stopEmbeddingWorkers
|
|
702687
703137
|
});
|
|
702688
|
-
import { basename as
|
|
703138
|
+
import { basename as basename39, join as join171 } from "node:path";
|
|
702689
703139
|
function startEmbeddingWorkers(opts) {
|
|
702690
703140
|
if (_running) return;
|
|
702691
703141
|
_running = true;
|
|
@@ -702751,7 +703201,7 @@ async function runEmbeddingTask(modality, episodeId, taskId, opts) {
|
|
|
702751
703201
|
try {
|
|
702752
703202
|
if (!_aligner) {
|
|
702753
703203
|
const stateRoot = process.env.OMNIUS_DIR || process.cwd();
|
|
702754
|
-
const omniusDir =
|
|
703204
|
+
const omniusDir = basename39(stateRoot) === ".omnius" ? stateRoot : join171(stateRoot, ".omnius");
|
|
702755
703205
|
const memDir = join171(omniusDir, "memory");
|
|
702756
703206
|
_aligner = new EmbeddingAligner(
|
|
702757
703207
|
`${modality}-${emb.length}`,
|
|
@@ -702873,7 +703323,7 @@ import { spawn as spawn33, execSync as execSync60 } from "node:child_process";
|
|
|
702873
703323
|
import {
|
|
702874
703324
|
createReadStream as createReadStream2,
|
|
702875
703325
|
mkdirSync as mkdirSync101,
|
|
702876
|
-
writeFileSync as
|
|
703326
|
+
writeFileSync as writeFileSync85,
|
|
702877
703327
|
readFileSync as readFileSync129,
|
|
702878
703328
|
readdirSync as readdirSync56,
|
|
702879
703329
|
existsSync as existsSync160,
|
|
@@ -704534,11 +704984,11 @@ function atomicJobWrite(dir, id, job) {
|
|
|
704534
704984
|
const finalPath = join172(dir, `${id}.json`);
|
|
704535
704985
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
704536
704986
|
try {
|
|
704537
|
-
|
|
704987
|
+
writeFileSync85(tmpPath, JSON.stringify(job, null, 2), "utf-8");
|
|
704538
704988
|
renameSync15(tmpPath, finalPath);
|
|
704539
704989
|
} catch {
|
|
704540
704990
|
try {
|
|
704541
|
-
|
|
704991
|
+
writeFileSync85(finalPath, JSON.stringify(job, null, 2), "utf-8");
|
|
704542
704992
|
} catch {
|
|
704543
704993
|
}
|
|
704544
704994
|
try {
|
|
@@ -706370,7 +706820,7 @@ function writeUpdateState(state) {
|
|
|
706370
706820
|
mkdirSync101(dir, { recursive: true });
|
|
706371
706821
|
const finalPath = updateStateFile();
|
|
706372
706822
|
const tmpPath = `${finalPath}.tmp.${process.pid}`;
|
|
706373
|
-
|
|
706823
|
+
writeFileSync85(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
706374
706824
|
renameSync15(tmpPath, finalPath);
|
|
706375
706825
|
} catch {
|
|
706376
706826
|
}
|
|
@@ -708720,13 +709170,13 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
|
|
|
708720
709170
|
return;
|
|
708721
709171
|
}
|
|
708722
709172
|
const { tmpdir: tmpdir24 } = await import("node:os");
|
|
708723
|
-
const { writeFileSync:
|
|
709173
|
+
const { writeFileSync: writeFileSync90, unlinkSync: unlinkSync36 } = await import("node:fs");
|
|
708724
709174
|
const { join: pjoin } = await import("node:path");
|
|
708725
709175
|
const tmpPath = pjoin(
|
|
708726
709176
|
tmpdir24(),
|
|
708727
709177
|
`omnius-clone-upload-${Date.now()}-${safeName3}`
|
|
708728
709178
|
);
|
|
708729
|
-
|
|
709179
|
+
writeFileSync90(tmpPath, buf);
|
|
708730
709180
|
try {
|
|
708731
709181
|
const ve = getVoiceEngine();
|
|
708732
709182
|
const msg = await ve.setCloneVoice(tmpPath);
|
|
@@ -709450,7 +709900,7 @@ data: ${JSON.stringify(data)}
|
|
|
709450
709900
|
}
|
|
709451
709901
|
for (const f2 of seenFiles) {
|
|
709452
709902
|
try {
|
|
709453
|
-
|
|
709903
|
+
writeFileSync85(f2, JSON.stringify({ tasks: [] }, null, 2));
|
|
709454
709904
|
deleted++;
|
|
709455
709905
|
} catch {
|
|
709456
709906
|
}
|
|
@@ -711249,11 +711699,11 @@ function setScheduledEnabled(id, enabled2) {
|
|
|
711249
711699
|
arr[target.index].enabled = enabled2;
|
|
711250
711700
|
if (Array.isArray(json?.tasks)) {
|
|
711251
711701
|
json.tasks = arr;
|
|
711252
|
-
|
|
711702
|
+
writeFileSync85(target.file, JSON.stringify(json, null, 2));
|
|
711253
711703
|
} else if (Array.isArray(json)) {
|
|
711254
|
-
|
|
711704
|
+
writeFileSync85(target.file, JSON.stringify(arr, null, 2));
|
|
711255
711705
|
} else {
|
|
711256
|
-
|
|
711706
|
+
writeFileSync85(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
711257
711707
|
}
|
|
711258
711708
|
if (!enabled2) {
|
|
711259
711709
|
try {
|
|
@@ -711283,11 +711733,11 @@ function deleteScheduledById(id) {
|
|
|
711283
711733
|
arr.splice(target.index, 1);
|
|
711284
711734
|
if (Array.isArray(json?.tasks)) {
|
|
711285
711735
|
json.tasks = arr;
|
|
711286
|
-
|
|
711736
|
+
writeFileSync85(target.file, JSON.stringify(json, null, 2));
|
|
711287
711737
|
} else if (Array.isArray(json)) {
|
|
711288
|
-
|
|
711738
|
+
writeFileSync85(target.file, JSON.stringify(arr, null, 2));
|
|
711289
711739
|
} else {
|
|
711290
|
-
|
|
711740
|
+
writeFileSync85(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
711291
711741
|
}
|
|
711292
711742
|
const candidates = [];
|
|
711293
711743
|
if (id) candidates.push(id);
|
|
@@ -711521,7 +711971,7 @@ function reconcileScheduledTasks(apply) {
|
|
|
711521
711971
|
mkdirSync101(join172(wdir, ".omnius", "scheduled", "logs"), {
|
|
711522
711972
|
recursive: true
|
|
711523
711973
|
});
|
|
711524
|
-
|
|
711974
|
+
writeFileSync85(file, JSON.stringify(toWrite, null, 2));
|
|
711525
711975
|
adopted.push({ file, index: arr.length - 1 });
|
|
711526
711976
|
}
|
|
711527
711977
|
} else {
|
|
@@ -711699,8 +712149,8 @@ WantedBy=timers.target
|
|
|
711699
712149
|
`;
|
|
711700
712150
|
if (!dryRun) {
|
|
711701
712151
|
mkdirSync101(unitDir, { recursive: true });
|
|
711702
|
-
|
|
711703
|
-
|
|
712152
|
+
writeFileSync85(svc, svcText);
|
|
712153
|
+
writeFileSync85(tim, timText);
|
|
711704
712154
|
try {
|
|
711705
712155
|
const { execSync: es } = require4("node:child_process");
|
|
711706
712156
|
es("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
@@ -712084,7 +712534,7 @@ function startApiServer(options2 = {}) {
|
|
|
712084
712534
|
try {
|
|
712085
712535
|
const dir = join172(homedir59(), ".omnius");
|
|
712086
712536
|
mkdirSync101(dir, { recursive: true });
|
|
712087
|
-
|
|
712537
|
+
writeFileSync85(
|
|
712088
712538
|
join172(dir, "access"),
|
|
712089
712539
|
`${runtimeAccessMode}
|
|
712090
712540
|
`,
|
|
@@ -712497,7 +712947,7 @@ function startApiServer(options2 = {}) {
|
|
|
712497
712947
|
}
|
|
712498
712948
|
try {
|
|
712499
712949
|
const {
|
|
712500
|
-
writeFileSync:
|
|
712950
|
+
writeFileSync: writeFileSync90,
|
|
712501
712951
|
mkdirSync: mkdirSync106,
|
|
712502
712952
|
existsSync: _exists,
|
|
712503
712953
|
readFileSync: _rfs
|
|
@@ -712536,7 +712986,7 @@ function startApiServer(options2 = {}) {
|
|
|
712536
712986
|
for (const dir of dirSet) {
|
|
712537
712987
|
try {
|
|
712538
712988
|
if (!_exists(dir)) mkdirSync106(dir, { recursive: true });
|
|
712539
|
-
|
|
712989
|
+
writeFileSync90(_join(dir, "api-port.json"), apiHint);
|
|
712540
712990
|
written++;
|
|
712541
712991
|
} catch {
|
|
712542
712992
|
}
|
|
@@ -712905,7 +713355,7 @@ async function handleChatAttachmentUpload(req3, res) {
|
|
|
712905
713355
|
dir,
|
|
712906
713356
|
`${Date.now()}-${randomUUID21().slice(0, 8)}-${safeName3}`
|
|
712907
713357
|
);
|
|
712908
|
-
|
|
713358
|
+
writeFileSync85(localPath, Buffer.from(base642, "base64"));
|
|
712909
713359
|
const mimeType = typeof b.mimeType === "string" ? b.mimeType : typeof b.mime_type === "string" ? b.mime_type : "";
|
|
712910
713360
|
const isImage = mimeType.toLowerCase().startsWith("image/") || /\.(png|jpe?g|gif|webp|bmp|tiff?)$/i.test(safeName3);
|
|
712911
713361
|
const sessionId = typeof b.sessionId === "string" ? b.sessionId : typeof b.session_id === "string" ? b.session_id : void 0;
|
|
@@ -712962,6 +713412,7 @@ async function handleChatAttachmentUpload(req3, res) {
|
|
|
712962
713412
|
graph.close();
|
|
712963
713413
|
}
|
|
712964
713414
|
let visualIdentity = void 0;
|
|
713415
|
+
let visualObjectMemory = void 0;
|
|
712965
713416
|
let contextBlock = [
|
|
712966
713417
|
`GUI attachment saved: ${safeName3}`,
|
|
712967
713418
|
`path: ${localPath}`,
|
|
@@ -713000,6 +713451,40 @@ ${association.contextBlock}`;
|
|
|
713000
713451
|
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713001
713452
|
};
|
|
713002
713453
|
}
|
|
713454
|
+
try {
|
|
713455
|
+
const { associateVisualObjectFromImage: associateVisualObjectFromImage2 } = await Promise.resolve().then(() => (init_visual_object_association(), visual_object_association_exports));
|
|
713456
|
+
const objectMemory = await associateVisualObjectFromImage2({
|
|
713457
|
+
repoRoot: process.cwd(),
|
|
713458
|
+
imagePath: localPath,
|
|
713459
|
+
sourceSurface: "gui",
|
|
713460
|
+
scope,
|
|
713461
|
+
sender,
|
|
713462
|
+
message: message2,
|
|
713463
|
+
sessionId,
|
|
713464
|
+
media,
|
|
713465
|
+
payload: b
|
|
713466
|
+
});
|
|
713467
|
+
visualObjectMemory = {
|
|
713468
|
+
attempted: objectMemory.attempted,
|
|
713469
|
+
taught: objectMemory.taught,
|
|
713470
|
+
label: objectMemory.label,
|
|
713471
|
+
aliases: objectMemory.aliases,
|
|
713472
|
+
contextBlock: objectMemory.contextBlock,
|
|
713473
|
+
degradedReason: objectMemory.degradedReason
|
|
713474
|
+
};
|
|
713475
|
+
if (objectMemory.contextBlock)
|
|
713476
|
+
contextBlock += `
|
|
713477
|
+
|
|
713478
|
+
${objectMemory.contextBlock}`;
|
|
713479
|
+
} catch (err) {
|
|
713480
|
+
visualObjectMemory = {
|
|
713481
|
+
attempted: true,
|
|
713482
|
+
taught: false,
|
|
713483
|
+
aliases: [],
|
|
713484
|
+
contextBlock: "",
|
|
713485
|
+
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713486
|
+
};
|
|
713487
|
+
}
|
|
713003
713488
|
}
|
|
713004
713489
|
jsonResponse(res, 200, {
|
|
713005
713490
|
id: ingestId,
|
|
@@ -713008,7 +713493,8 @@ ${association.contextBlock}`;
|
|
|
713008
713493
|
mimeType,
|
|
713009
713494
|
modality,
|
|
713010
713495
|
contextBlock,
|
|
713011
|
-
visualIdentity
|
|
713496
|
+
visualIdentity,
|
|
713497
|
+
visualObjectMemory
|
|
713012
713498
|
});
|
|
713013
713499
|
} catch (err) {
|
|
713014
713500
|
jsonResponse(res, 400, {
|
|
@@ -713141,6 +713627,7 @@ async function handleMemoryIngest2(req3, res, ollamaUrl) {
|
|
|
713141
713627
|
embeddings
|
|
713142
713628
|
});
|
|
713143
713629
|
let visualIdentity = void 0;
|
|
713630
|
+
let visualObjectMemory = void 0;
|
|
713144
713631
|
if (modality === "visual" && mediaPath) {
|
|
713145
713632
|
try {
|
|
713146
713633
|
const { associateVisualIdentityFromImage: associateVisualIdentityFromImage2 } = await Promise.resolve().then(() => (init_visual_identity_association(), visual_identity_association_exports));
|
|
@@ -713174,8 +713661,40 @@ async function handleMemoryIngest2(req3, res, ollamaUrl) {
|
|
|
713174
713661
|
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713175
713662
|
};
|
|
713176
713663
|
}
|
|
713664
|
+
try {
|
|
713665
|
+
const { associateVisualObjectFromImage: associateVisualObjectFromImage2 } = await Promise.resolve().then(() => (init_visual_object_association(), visual_object_association_exports));
|
|
713666
|
+
const objectMemory = await associateVisualObjectFromImage2({
|
|
713667
|
+
repoRoot: process.cwd(),
|
|
713668
|
+
imagePath: mediaPath,
|
|
713669
|
+
sourceSurface,
|
|
713670
|
+
scope,
|
|
713671
|
+
sender,
|
|
713672
|
+
message: message2,
|
|
713673
|
+
replyTo,
|
|
713674
|
+
sessionId,
|
|
713675
|
+
media,
|
|
713676
|
+
extractedContent: b.extracted_content || b.extractedContent,
|
|
713677
|
+
payload: b
|
|
713678
|
+
});
|
|
713679
|
+
visualObjectMemory = {
|
|
713680
|
+
attempted: objectMemory.attempted,
|
|
713681
|
+
taught: objectMemory.taught,
|
|
713682
|
+
label: objectMemory.label,
|
|
713683
|
+
aliases: objectMemory.aliases,
|
|
713684
|
+
contextBlock: objectMemory.contextBlock,
|
|
713685
|
+
degradedReason: objectMemory.degradedReason
|
|
713686
|
+
};
|
|
713687
|
+
} catch (err) {
|
|
713688
|
+
visualObjectMemory = {
|
|
713689
|
+
attempted: true,
|
|
713690
|
+
taught: false,
|
|
713691
|
+
aliases: [],
|
|
713692
|
+
contextBlock: "",
|
|
713693
|
+
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713694
|
+
};
|
|
713695
|
+
}
|
|
713177
713696
|
}
|
|
713178
|
-
jsonResponse(res, 200, { id: result.episodeId, ...result, visualIdentity });
|
|
713697
|
+
jsonResponse(res, 200, { id: result.episodeId, ...result, visualIdentity, visualObjectMemory });
|
|
713179
713698
|
} catch (err) {
|
|
713180
713699
|
jsonResponse(res, 400, {
|
|
713181
713700
|
error: "bad_request",
|
|
@@ -713391,7 +713910,7 @@ __export(clipboard_media_exports, {
|
|
|
713391
713910
|
pasteClipboardImageToFile: () => pasteClipboardImageToFile
|
|
713392
713911
|
});
|
|
713393
713912
|
import { execFileSync as execFileSync11, execSync as execSync61 } from "node:child_process";
|
|
713394
|
-
import { mkdirSync as mkdirSync102, readFileSync as readFileSync130, rmSync as rmSync13, writeFileSync as
|
|
713913
|
+
import { mkdirSync as mkdirSync102, readFileSync as readFileSync130, rmSync as rmSync13, writeFileSync as writeFileSync86 } from "node:fs";
|
|
713395
713914
|
import { join as join173 } from "node:path";
|
|
713396
713915
|
function pasteClipboardImageToFile(repoRoot) {
|
|
713397
713916
|
const image = readClipboardImage();
|
|
@@ -713399,7 +713918,7 @@ function pasteClipboardImageToFile(repoRoot) {
|
|
|
713399
713918
|
const dir = join173(repoRoot, ".omnius", "clipboard");
|
|
713400
713919
|
mkdirSync102(dir, { recursive: true });
|
|
713401
713920
|
const path12 = join173(dir, `clipboard-${Date.now()}${image.ext}`);
|
|
713402
|
-
|
|
713921
|
+
writeFileSync86(path12, image.buffer);
|
|
713403
713922
|
return { path: path12, buffer: image.buffer, mime: image.mime };
|
|
713404
713923
|
}
|
|
713405
713924
|
function readClipboardImage() {
|
|
@@ -713468,7 +713987,7 @@ import { createRequire as createRequire9 } from "node:module";
|
|
|
713468
713987
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
713469
713988
|
import {
|
|
713470
713989
|
readFileSync as readFileSync131,
|
|
713471
|
-
writeFileSync as
|
|
713990
|
+
writeFileSync as writeFileSync87,
|
|
713472
713991
|
appendFileSync as appendFileSync17,
|
|
713473
713992
|
rmSync as rmSync14,
|
|
713474
713993
|
readdirSync as readdirSync57,
|
|
@@ -714595,7 +715114,7 @@ function createFanoutExploreTool(config, repoRoot, ctxWindowSize) {
|
|
|
714595
715114
|
);
|
|
714596
715115
|
if (debug) {
|
|
714597
715116
|
try {
|
|
714598
|
-
|
|
715117
|
+
writeFileSync87(
|
|
714599
715118
|
join174(repoRoot, ".omnius", "fanout-debug.json"),
|
|
714600
715119
|
JSON.stringify({ objective, regions, rawReturns, digests }, null, 2)
|
|
714601
715120
|
);
|
|
@@ -715381,7 +715900,7 @@ ${skillPack}`;
|
|
|
715381
715900
|
You have vision capabilities. Choose the RIGHT tool for each situation:
|
|
715382
715901
|
|
|
715383
715902
|
FOR IMAGE FILES (photos, screenshots, diagrams):
|
|
715384
|
-
image_read(
|
|
715903
|
+
image_read(path="path") — Read image metadata/base64/OCR; use vision(image="path") for semantic Moondream analysis
|
|
715385
715904
|
vision(image="path", action="caption") — Describe image contents via Moondream
|
|
715386
715905
|
vision(image="path", action="query", prompt="question") — Ask questions about an image
|
|
715387
715906
|
vision(image="path", action="detect", prompt="object") — Find objects (bounding boxes)
|
|
@@ -718910,7 +719429,7 @@ This is an independent background session started from /background.`
|
|
|
718910
719429
|
if (Math.random() < 0.02) {
|
|
718911
719430
|
const all2 = readFileSync131(HISTORY_FILE, "utf8").trim().split("\n");
|
|
718912
719431
|
if (all2.length > MAX_HISTORY_LINES) {
|
|
718913
|
-
|
|
719432
|
+
writeFileSync87(
|
|
718914
719433
|
HISTORY_FILE,
|
|
718915
719434
|
all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n",
|
|
718916
719435
|
"utf8"
|
|
@@ -719851,7 +720370,7 @@ Log: ${nexusLogPath}`
|
|
|
719851
720370
|
sessionTitle = title.trim() || null;
|
|
719852
720371
|
try {
|
|
719853
720372
|
mkdirSync103(join174(repoRoot, ".omnius"), { recursive: true });
|
|
719854
|
-
|
|
720373
|
+
writeFileSync87(
|
|
719855
720374
|
join174(repoRoot, ".omnius", "session-title"),
|
|
719856
720375
|
`${sessionTitle ?? ""}
|
|
719857
720376
|
`,
|
|
@@ -719945,7 +720464,7 @@ Log: ${nexusLogPath}`
|
|
|
719945
720464
|
queuePrompt(
|
|
719946
720465
|
imageContext ? `${imageContext}
|
|
719947
720466
|
|
|
719948
|
-
The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analysis, and ASCII preview above to understand and respond to the image content.` : `The user pasted a clipboard image saved at ${relPath}.
|
|
720467
|
+
The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analysis, and ASCII preview above to understand and respond to the image content.` : `The user pasted a clipboard image saved at ${relPath}. Use vision(image="${relPath}") for semantic Moondream analysis, and image_read(path="${relPath}") only if metadata/OCR/raw ingress is needed.`,
|
|
719949
720468
|
"clipboard"
|
|
719950
720469
|
);
|
|
719951
720470
|
return {
|
|
@@ -722575,7 +723094,7 @@ ${result.text}`;
|
|
|
722575
723094
|
|
|
722576
723095
|
${imageContext}
|
|
722577
723096
|
|
|
722578
|
-
|
|
723097
|
+
Use vision(image="${cleanPath}") for additional semantic detail, and image_read(path="${cleanPath}") only if metadata/OCR/raw ingress is needed.` : `The user has provided an image file: ${cleanPath}. Use vision(image="${cleanPath}") for semantic Moondream analysis. Use image_read(path="${cleanPath}") only if metadata/OCR/raw ingress is needed.`;
|
|
722579
723098
|
}
|
|
722580
723099
|
if (isMedia && fullInput === input && (voiceEngine.isLuxtts || voiceEngine.isMisotts)) {
|
|
722581
723100
|
const cloneExts = [".wav", ".mp3", ".ogg", ".flac", ".m4a"];
|
|
@@ -723303,7 +723822,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723303
723822
|
);
|
|
723304
723823
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
723305
723824
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
723306
|
-
|
|
723825
|
+
writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
|
|
723307
723826
|
} catch (ikErr) {
|
|
723308
723827
|
}
|
|
723309
723828
|
try {
|
|
@@ -723336,7 +723855,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723336
723855
|
});
|
|
723337
723856
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
723338
723857
|
mkdirSync103(archeDir, { recursive: true });
|
|
723339
|
-
|
|
723858
|
+
writeFileSync87(archeFile, JSON.stringify(variants, null, 2));
|
|
723340
723859
|
} catch {
|
|
723341
723860
|
}
|
|
723342
723861
|
}
|
|
@@ -723367,7 +723886,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723367
723886
|
updated = true;
|
|
723368
723887
|
}
|
|
723369
723888
|
if (updated) {
|
|
723370
|
-
|
|
723889
|
+
writeFileSync87(metaFile2, JSON.stringify(store2, null, 2));
|
|
723371
723890
|
}
|
|
723372
723891
|
}
|
|
723373
723892
|
} catch {
|
|
@@ -723476,7 +723995,7 @@ Rules:
|
|
|
723476
723995
|
});
|
|
723477
723996
|
if (store2.length > 100) store2 = store2.slice(-100);
|
|
723478
723997
|
mkdirSync103(metaDir, { recursive: true });
|
|
723479
|
-
|
|
723998
|
+
writeFileSync87(storeFile, JSON.stringify(store2, null, 2));
|
|
723480
723999
|
}
|
|
723481
724000
|
}
|
|
723482
724001
|
} catch {
|
|
@@ -723540,7 +724059,7 @@ Rules:
|
|
|
723540
724059
|
);
|
|
723541
724060
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
723542
724061
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
723543
|
-
|
|
724062
|
+
writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
|
|
723544
724063
|
}
|
|
723545
724064
|
const metaFile2 = join174(
|
|
723546
724065
|
repoRoot,
|
|
@@ -723568,7 +724087,7 @@ Rules:
|
|
|
723568
724087
|
(item.scores.confidence || 0.5) - 0.02
|
|
723569
724088
|
);
|
|
723570
724089
|
}
|
|
723571
|
-
|
|
724090
|
+
writeFileSync87(metaFile2, JSON.stringify(store2, null, 2));
|
|
723572
724091
|
}
|
|
723573
724092
|
try {
|
|
723574
724093
|
const archeDir = join174(repoRoot, ".omnius", "arche");
|
|
@@ -723591,7 +724110,7 @@ Rules:
|
|
|
723591
724110
|
});
|
|
723592
724111
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
723593
724112
|
mkdirSync103(archeDir, { recursive: true });
|
|
723594
|
-
|
|
724113
|
+
writeFileSync87(archeFile, JSON.stringify(variants, null, 2));
|
|
723595
724114
|
} catch {
|
|
723596
724115
|
}
|
|
723597
724116
|
} catch {
|
|
@@ -723704,7 +724223,7 @@ import { resolve as resolve68 } from "node:path";
|
|
|
723704
724223
|
import { spawn as spawn34 } from "node:child_process";
|
|
723705
724224
|
import {
|
|
723706
724225
|
mkdirSync as mkdirSync104,
|
|
723707
|
-
writeFileSync as
|
|
724226
|
+
writeFileSync as writeFileSync88,
|
|
723708
724227
|
readFileSync as readFileSync132,
|
|
723709
724228
|
readdirSync as readdirSync58,
|
|
723710
724229
|
existsSync as existsSync162
|
|
@@ -723844,7 +724363,7 @@ async function runBackground(task, config, opts) {
|
|
|
723844
724363
|
}
|
|
723845
724364
|
});
|
|
723846
724365
|
job.pid = child.pid ?? 0;
|
|
723847
|
-
|
|
724366
|
+
writeFileSync88(join175(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
723848
724367
|
let output = "";
|
|
723849
724368
|
child.stdout?.on("data", (chunk) => {
|
|
723850
724369
|
output += chunk.toString();
|
|
@@ -723860,7 +724379,7 @@ async function runBackground(task, config, opts) {
|
|
|
723860
724379
|
job.summary = result.summary;
|
|
723861
724380
|
job.durationMs = result.durationMs;
|
|
723862
724381
|
job.error = result.error;
|
|
723863
|
-
|
|
724382
|
+
writeFileSync88(join175(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
723864
724383
|
} catch {
|
|
723865
724384
|
}
|
|
723866
724385
|
});
|
|
@@ -724499,7 +725018,7 @@ __export(eval_exports, {
|
|
|
724499
725018
|
evalCommand: () => evalCommand
|
|
724500
725019
|
});
|
|
724501
725020
|
import { tmpdir as tmpdir23 } from "node:os";
|
|
724502
|
-
import { mkdirSync as mkdirSync105, writeFileSync as
|
|
725021
|
+
import { mkdirSync as mkdirSync105, writeFileSync as writeFileSync89 } from "node:fs";
|
|
724503
725022
|
import { join as join177 } from "node:path";
|
|
724504
725023
|
async function evalCommand(opts, config) {
|
|
724505
725024
|
const suiteName = opts.suite ?? "basic";
|
|
@@ -724631,7 +725150,7 @@ async function evalCommand(opts, config) {
|
|
|
724631
725150
|
function createTempEvalRepo() {
|
|
724632
725151
|
const dir = join177(tmpdir23(), `omnius-eval-${Date.now()}`);
|
|
724633
725152
|
mkdirSync105(dir, { recursive: true });
|
|
724634
|
-
|
|
725153
|
+
writeFileSync89(
|
|
724635
725154
|
join177(dir, "package.json"),
|
|
724636
725155
|
JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
|
|
724637
725156
|
"utf8"
|
|
@@ -724868,8 +725387,16 @@ function routeCommand(command) {
|
|
|
724868
725387
|
}
|
|
724869
725388
|
function parseCliArgs(argv) {
|
|
724870
725389
|
const args = argv.slice(2);
|
|
725390
|
+
const parseInput = [...args];
|
|
725391
|
+
const selfTestFlagIndex = parseInput.indexOf("--self-test");
|
|
725392
|
+
if (selfTestFlagIndex >= 0) {
|
|
725393
|
+
const next = parseInput[selfTestFlagIndex + 1];
|
|
725394
|
+
if (!next || next.startsWith("-")) {
|
|
725395
|
+
parseInput.splice(selfTestFlagIndex, 1, "--self-test=crossmodal");
|
|
725396
|
+
}
|
|
725397
|
+
}
|
|
724871
725398
|
const { values, positionals } = nodeParseArgs2({
|
|
724872
|
-
args,
|
|
725399
|
+
args: parseInput,
|
|
724873
725400
|
options: {
|
|
724874
725401
|
"dry-run": { type: "boolean" },
|
|
724875
725402
|
verbose: { type: "boolean", short: "v" },
|
|
@@ -724886,6 +725413,7 @@ function parseCliArgs(argv) {
|
|
|
724886
725413
|
live: { type: "boolean" },
|
|
724887
725414
|
json: { type: "boolean", short: "j" },
|
|
724888
725415
|
background: { type: "boolean" },
|
|
725416
|
+
"self-test": { type: "string" },
|
|
724889
725417
|
help: { type: "boolean", short: "h" },
|
|
724890
725418
|
version: { type: "boolean", short: "V" }
|
|
724891
725419
|
},
|
|
@@ -724908,6 +725436,7 @@ function parseCliArgs(argv) {
|
|
|
724908
725436
|
local: values.local === true,
|
|
724909
725437
|
json: values.json === true,
|
|
724910
725438
|
background: values.background === true,
|
|
725439
|
+
selfTest: typeof values["self-test"] === "string" ? values["self-test"] : void 0,
|
|
724911
725440
|
help: values.help === true,
|
|
724912
725441
|
version: values.version === true
|
|
724913
725442
|
};
|
|
@@ -725013,6 +725542,23 @@ Examples:
|
|
|
725013
725542
|
`.trim();
|
|
725014
725543
|
process.stdout.write(text2 + "\n");
|
|
725015
725544
|
}
|
|
725545
|
+
async function runSelfTest(mode) {
|
|
725546
|
+
if (mode !== "crossmodal") {
|
|
725547
|
+
throw new Error(`Unknown self-test mode: ${mode}`);
|
|
725548
|
+
}
|
|
725549
|
+
process.stdout.write("Running crossmodal smoke tests...\n");
|
|
725550
|
+
const { spawn: spawn35 } = await import("node:child_process");
|
|
725551
|
+
const run2 = (file) => new Promise((resolve71, reject) => {
|
|
725552
|
+
const p2 = spawn35(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
|
|
725553
|
+
p2.stdout.on("data", (d2) => process.stdout.write(d2));
|
|
725554
|
+
p2.stderr.on("data", (d2) => process.stdout.write(d2));
|
|
725555
|
+
onChildExit(p2, (code8) => code8 === 0 ? resolve71() : reject(new Error(`${file} exited ${code8}`)));
|
|
725556
|
+
});
|
|
725557
|
+
const base3 = process.cwd();
|
|
725558
|
+
await run2(`${base3}/eval/test-crossmodal.mjs`);
|
|
725559
|
+
await run2(`${base3}/eval/test-memory-search.mjs`);
|
|
725560
|
+
process.stdout.write("Self-test complete.\n");
|
|
725561
|
+
}
|
|
725016
725562
|
async function main() {
|
|
725017
725563
|
const version4 = getVersion5();
|
|
725018
725564
|
const parsed = parseCliArgs(process.argv);
|
|
@@ -725026,6 +725572,10 @@ async function main() {
|
|
|
725026
725572
|
printHelp2(version4);
|
|
725027
725573
|
return;
|
|
725028
725574
|
}
|
|
725575
|
+
if (parsed.selfTest) {
|
|
725576
|
+
await runSelfTest(parsed.selfTest);
|
|
725577
|
+
return;
|
|
725578
|
+
}
|
|
725029
725579
|
if (!parsed.json) {
|
|
725030
725580
|
const updateInfo = await checkForUpdate(version4);
|
|
725031
725581
|
if (updateInfo) {
|
|
@@ -725044,27 +725594,6 @@ async function main() {
|
|
|
725044
725594
|
});
|
|
725045
725595
|
try {
|
|
725046
725596
|
switch (parsed.command) {
|
|
725047
|
-
case void 0: {
|
|
725048
|
-
if (process.argv.includes("--self-test")) {
|
|
725049
|
-
const mode = process.argv[process.argv.indexOf("--self-test") + 1] || "crossmodal";
|
|
725050
|
-
if (mode === "crossmodal") {
|
|
725051
|
-
process.stdout.write("Running crossmodal smoke tests...\n");
|
|
725052
|
-
const { spawn: spawn35 } = await import("node:child_process");
|
|
725053
|
-
const run2 = (file) => new Promise((resolve71, reject) => {
|
|
725054
|
-
const p2 = spawn35(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
|
|
725055
|
-
p2.stdout.on("data", (d2) => process.stdout.write(d2));
|
|
725056
|
-
p2.stderr.on("data", (d2) => process.stdout.write(d2));
|
|
725057
|
-
onChildExit(p2, (code8) => code8 === 0 ? resolve71() : reject(new Error(`${file} exited ${code8}`)));
|
|
725058
|
-
});
|
|
725059
|
-
const base3 = process.cwd();
|
|
725060
|
-
await run2(`${base3}/eval/test-crossmodal.mjs`);
|
|
725061
|
-
await run2(`${base3}/eval/test-memory-search.mjs`);
|
|
725062
|
-
process.stdout.write("Self-test complete.\n");
|
|
725063
|
-
return;
|
|
725064
|
-
}
|
|
725065
|
-
}
|
|
725066
|
-
break;
|
|
725067
|
-
}
|
|
725068
725597
|
case "run": {
|
|
725069
725598
|
const { runCommand: runCommand3 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
725070
725599
|
await runCommand3(
|