omnius 1.0.368 → 1.0.370
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 +1330 -322
- 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");
|
|
@@ -295142,7 +295152,13 @@ var init_todo_write = __esm({
|
|
|
295142
295152
|
- completed: fully done (tests pass, code works, goal met)
|
|
295143
295153
|
- blocked: stuck on a dependency (include blocker text)
|
|
295144
295154
|
|
|
295145
|
-
|
|
295155
|
+
## Nested decomposition
|
|
295156
|
+
- Use stable ids plus parentId to create subtasks under a parent objective.
|
|
295157
|
+
- Work on leaf subtasks; a parent is completed only after every child is completed with evidence.
|
|
295158
|
+
- When evidence changes the plan, rewrite the tree: add new child todos, block invalidated children with root cause, and keep the parent in_progress/blocked until the child set is truthful.
|
|
295159
|
+
- If a tool fails for a child, do not mark that child completed. Reconfigure it: re-read/observe current state, choose a different target/tool, or leave it blocked.
|
|
295160
|
+
|
|
295161
|
+
Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark completed if tests are failing or implementation is partial. The user watches this list in the chat UI in real time. Canonical call shape: todo_write({"todos":[{"id":"p1","content":"Implement feature","status":"in_progress"},{"id":"c1","parentId":"p1","content":"Inspect files","status":"in_progress"},{"id":"c2","parentId":"p1","content":"Make changes","status":"pending"},{"id":"c3","parentId":"p1","content":"Verify results","status":"pending"}]})`;
|
|
295146
295162
|
parameters = {
|
|
295147
295163
|
type: "object",
|
|
295148
295164
|
required: ["todos"],
|
|
@@ -295160,7 +295176,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
295160
295176
|
type: "string",
|
|
295161
295177
|
enum: ["pending", "in_progress", "completed", "blocked"]
|
|
295162
295178
|
},
|
|
295163
|
-
parentId: { type: "string", description: "Parent todo id for sub-tasks" },
|
|
295179
|
+
parentId: { type: "string", description: "Parent todo id for nested sub-tasks. Parents summarize objectives; children carry concrete implementation/verification work. Never complete a parent until every child is completed with evidence." },
|
|
295164
295180
|
blocker: { type: "string", description: "Reason this is blocked (status=blocked only)" },
|
|
295165
295181
|
verifyCommand: {
|
|
295166
295182
|
type: "string",
|
|
@@ -295277,6 +295293,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
295277
295293
|
const reminder = "Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Mark the current task in_progress and the next task pending. Proceed with the current task.";
|
|
295278
295294
|
const payload = {
|
|
295279
295295
|
reminder,
|
|
295296
|
+
decompositionContract: "Use parentId for sub-todos. Keep parents in_progress/blocked until all children are completed with objective evidence. When tool evidence invalidates a child, rewrite that child as blocked or split it into new children instead of overclaiming completion.",
|
|
295280
295297
|
oldTodos: result.oldTodos,
|
|
295281
295298
|
newTodos: result.newTodos,
|
|
295282
295299
|
verificationNudgeNeeded
|
|
@@ -295285,9 +295302,10 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
295285
295302
|
payload["inputRepair"] = Array.from(new Set(repairNotes));
|
|
295286
295303
|
payload["canonicalShape"] = {
|
|
295287
295304
|
todos: [
|
|
295288
|
-
{ content: "
|
|
295289
|
-
{ content: "
|
|
295290
|
-
{ content: "
|
|
295305
|
+
{ id: "p1", content: "Implement the requested change", status: "in_progress" },
|
|
295306
|
+
{ id: "c1", parentId: "p1", content: "Inspect files", status: "in_progress" },
|
|
295307
|
+
{ id: "c2", parentId: "p1", content: "Make changes", status: "pending" },
|
|
295308
|
+
{ id: "c3", parentId: "p1", content: "Verify results", status: "pending" }
|
|
295291
295309
|
]
|
|
295292
295310
|
};
|
|
295293
295311
|
}
|
|
@@ -321828,9 +321846,9 @@ ${lanes.join("\n")}
|
|
|
321828
321846
|
function isJsonEqual(a2, b) {
|
|
321829
321847
|
return a2 === b || typeof a2 === "object" && a2 !== null && typeof b === "object" && b !== null && equalOwnProperties(a2, b, isJsonEqual);
|
|
321830
321848
|
}
|
|
321831
|
-
function parsePseudoBigInt(
|
|
321849
|
+
function parsePseudoBigInt(stringValue3) {
|
|
321832
321850
|
let log2Base;
|
|
321833
|
-
switch (
|
|
321851
|
+
switch (stringValue3.charCodeAt(1)) {
|
|
321834
321852
|
// "x" in "0x123"
|
|
321835
321853
|
case 98:
|
|
321836
321854
|
case 66:
|
|
@@ -321845,19 +321863,19 @@ ${lanes.join("\n")}
|
|
|
321845
321863
|
log2Base = 4;
|
|
321846
321864
|
break;
|
|
321847
321865
|
default:
|
|
321848
|
-
const nIndex =
|
|
321866
|
+
const nIndex = stringValue3.length - 1;
|
|
321849
321867
|
let nonZeroStart = 0;
|
|
321850
|
-
while (
|
|
321868
|
+
while (stringValue3.charCodeAt(nonZeroStart) === 48) {
|
|
321851
321869
|
nonZeroStart++;
|
|
321852
321870
|
}
|
|
321853
|
-
return
|
|
321871
|
+
return stringValue3.slice(nonZeroStart, nIndex) || "0";
|
|
321854
321872
|
}
|
|
321855
|
-
const startIndex = 2, endIndex =
|
|
321873
|
+
const startIndex = 2, endIndex = stringValue3.length - 1;
|
|
321856
321874
|
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
|
321857
321875
|
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
|
321858
321876
|
for (let i2 = endIndex - 1, bitOffset = 0; i2 >= startIndex; i2--, bitOffset += log2Base) {
|
|
321859
321877
|
const segment = bitOffset >>> 4;
|
|
321860
|
-
const digitChar =
|
|
321878
|
+
const digitChar = stringValue3.charCodeAt(i2);
|
|
321861
321879
|
const digit = digitChar <= 57 ? digitChar - 48 : 10 + digitChar - (digitChar <= 70 ? 65 : 97);
|
|
321862
321880
|
const shiftedDigit = digit << (bitOffset & 15);
|
|
321863
321881
|
segments[segment] |= shiftedDigit;
|
|
@@ -435385,9 +435403,9 @@ ${lanes.join("\n")}
|
|
|
435385
435403
|
/*ignoreCase*/
|
|
435386
435404
|
false
|
|
435387
435405
|
)) {
|
|
435388
|
-
const
|
|
435389
|
-
if (
|
|
435390
|
-
const name10 = removeSuffix(removePrefix(
|
|
435406
|
+
const basename40 = getBaseFileName(a2.fileName);
|
|
435407
|
+
if (basename40 === "lib.d.ts" || basename40 === "lib.es6.d.ts") return 0;
|
|
435408
|
+
const name10 = removeSuffix(removePrefix(basename40, "lib."), ".d.ts");
|
|
435391
435409
|
const index = libs.indexOf(name10);
|
|
435392
435410
|
if (index !== -1) return index + 1;
|
|
435393
435411
|
}
|
|
@@ -499313,8 +499331,8 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
499313
499331
|
}
|
|
499314
499332
|
};
|
|
499315
499333
|
for (const file of files) {
|
|
499316
|
-
const
|
|
499317
|
-
if (
|
|
499334
|
+
const basename40 = getBaseFileName(file);
|
|
499335
|
+
if (basename40 === "package.json" || basename40 === "bower.json") {
|
|
499318
499336
|
createProjectWatcher(
|
|
499319
499337
|
file,
|
|
499320
499338
|
"FileWatcher"
|
|
@@ -502998,8 +503016,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
502998
503016
|
var _a;
|
|
502999
503017
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
503000
503018
|
if (!fileOrDirectoryPath) return;
|
|
503001
|
-
const
|
|
503002
|
-
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (
|
|
503019
|
+
const basename40 = getBaseFileName(fileOrDirectoryPath);
|
|
503020
|
+
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename40 === "package.json" || basename40 === "node_modules")) {
|
|
503003
503021
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
503004
503022
|
var _a2;
|
|
503005
503023
|
(_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
|
|
@@ -511902,7 +511920,7 @@ var require_path_browserify = __commonJS({
|
|
|
511902
511920
|
if (hasRoot && end === 1) return "//";
|
|
511903
511921
|
return path12.slice(0, end);
|
|
511904
511922
|
},
|
|
511905
|
-
basename: function
|
|
511923
|
+
basename: function basename40(path12, ext) {
|
|
511906
511924
|
if (ext !== void 0 && typeof ext !== "string") throw new TypeError('"ext" argument must be a string');
|
|
511907
511925
|
assertPath(path12);
|
|
511908
511926
|
var start2 = 0;
|
|
@@ -546577,6 +546595,32 @@ ${content.slice(0, 500)}`,
|
|
|
546577
546595
|
}
|
|
546578
546596
|
});
|
|
546579
546597
|
|
|
546598
|
+
// packages/execution/dist/tools/clip-feature-python.js
|
|
546599
|
+
var CLIP_FEATURE_HELPERS_PY;
|
|
546600
|
+
var init_clip_feature_python = __esm({
|
|
546601
|
+
"packages/execution/dist/tools/clip-feature-python.js"() {
|
|
546602
|
+
"use strict";
|
|
546603
|
+
CLIP_FEATURE_HELPERS_PY = `
|
|
546604
|
+
def _omnius_feature_tensor(features):
|
|
546605
|
+
if hasattr(features, "image_embeds"):
|
|
546606
|
+
return features.image_embeds
|
|
546607
|
+
if hasattr(features, "text_embeds"):
|
|
546608
|
+
return features.text_embeds
|
|
546609
|
+
if hasattr(features, "pooler_output"):
|
|
546610
|
+
return features.pooler_output
|
|
546611
|
+
if hasattr(features, "last_hidden_state"):
|
|
546612
|
+
return features.last_hidden_state[:, 0]
|
|
546613
|
+
if isinstance(features, (tuple, list)):
|
|
546614
|
+
return features[0]
|
|
546615
|
+
return features
|
|
546616
|
+
|
|
546617
|
+
def _omnius_normalized_features(features):
|
|
546618
|
+
tensor = _omnius_feature_tensor(features)
|
|
546619
|
+
return tensor / tensor.norm(dim=-1, keepdim=True)
|
|
546620
|
+
`;
|
|
546621
|
+
}
|
|
546622
|
+
});
|
|
546623
|
+
|
|
546580
546624
|
// packages/execution/dist/tools/visual-memory.js
|
|
546581
546625
|
import { execSync as execSync39 } from "node:child_process";
|
|
546582
546626
|
import { existsSync as existsSync66, mkdirSync as mkdirSync39, writeFileSync as writeFileSync31, readFileSync as readFileSync48 } from "node:fs";
|
|
@@ -546587,33 +546631,123 @@ function visualMemoryPythonEnv(extra = {}) {
|
|
|
546587
546631
|
applyMediaCudaDeviceFilterToEnv(env2, "vision");
|
|
546588
546632
|
return env2;
|
|
546589
546633
|
}
|
|
546590
|
-
|
|
546634
|
+
function stringArg2(args, ...keys) {
|
|
546635
|
+
for (const key of keys) {
|
|
546636
|
+
const value2 = args[key];
|
|
546637
|
+
if (typeof value2 === "string" && value2.trim())
|
|
546638
|
+
return value2.trim();
|
|
546639
|
+
}
|
|
546640
|
+
return "";
|
|
546641
|
+
}
|
|
546642
|
+
function stringListArg(value2) {
|
|
546643
|
+
if (Array.isArray(value2)) {
|
|
546644
|
+
return value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
|
|
546645
|
+
}
|
|
546646
|
+
if (typeof value2 === "string" && value2.trim())
|
|
546647
|
+
return [value2.trim()];
|
|
546648
|
+
return [];
|
|
546649
|
+
}
|
|
546650
|
+
function imagePathArg(args) {
|
|
546651
|
+
return stringArg2(args, "image", "path", "file", "media");
|
|
546652
|
+
}
|
|
546653
|
+
function associationLabelArg(args) {
|
|
546654
|
+
return stringArg2(args, "name", "label", "title", "object", "person") || stringListArg(args["labels"])[0] || stringListArg(args["aliases"])[0] || "";
|
|
546655
|
+
}
|
|
546656
|
+
function pyLiteral(value2) {
|
|
546657
|
+
return JSON.stringify(value2);
|
|
546658
|
+
}
|
|
546659
|
+
function normalizeVisualMemoryAction(args) {
|
|
546660
|
+
const raw = stringArg2(args, "action").toLowerCase();
|
|
546661
|
+
if (!raw) {
|
|
546662
|
+
if (imagePathArg(args) && associationLabelArg(args))
|
|
546663
|
+
return "teach";
|
|
546664
|
+
if (imagePathArg(args))
|
|
546665
|
+
return "recognize";
|
|
546666
|
+
return "";
|
|
546667
|
+
}
|
|
546668
|
+
if (raw === "learn" || raw === "remember" || raw === "associate")
|
|
546669
|
+
return "teach";
|
|
546670
|
+
if (raw === "score" || raw === "classify")
|
|
546671
|
+
return "describe";
|
|
546672
|
+
return raw;
|
|
546673
|
+
}
|
|
546674
|
+
function summarizeProcessFailure(stdout, stderr) {
|
|
546675
|
+
const normalize2 = (text2) => text2.replace(/\r/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
546676
|
+
const stderrLines = normalize2(stderr);
|
|
546677
|
+
const stdoutLines = normalize2(stdout);
|
|
546678
|
+
const tagged = [
|
|
546679
|
+
...stderrLines.map((line) => `stderr: ${line}`),
|
|
546680
|
+
...stdoutLines.map((line) => `stdout: ${line}`)
|
|
546681
|
+
];
|
|
546682
|
+
if (tagged.length === 0)
|
|
546683
|
+
return "Vision ML script failed";
|
|
546684
|
+
const exceptionRe = /(?:^|\s)(?:[A-Za-z_][\w.]*Error|[A-Za-z_][\w.]*Exception|AssertionError|KeyboardInterrupt|SystemExit):\s+.+$/;
|
|
546685
|
+
const tracebackIdx = tagged.findIndex((line) => /Traceback \(most recent call last\):/.test(line));
|
|
546686
|
+
const exceptionLine = [...stderrLines, ...stdoutLines].slice().reverse().find((line) => exceptionRe.test(line) && !/\bwarning:/i.test(line));
|
|
546687
|
+
const parts = [];
|
|
546688
|
+
if (exceptionLine) {
|
|
546689
|
+
parts.push(`Root cause: ${exceptionLine}`);
|
|
546690
|
+
}
|
|
546691
|
+
if (tracebackIdx >= 0) {
|
|
546692
|
+
parts.push("Traceback:");
|
|
546693
|
+
parts.push(...tagged.slice(tracebackIdx).slice(0, 18));
|
|
546694
|
+
}
|
|
546695
|
+
const tail = tagged.slice(-24);
|
|
546696
|
+
for (const line of tail) {
|
|
546697
|
+
if (!parts.includes(line))
|
|
546698
|
+
parts.push(line);
|
|
546699
|
+
}
|
|
546700
|
+
return parts.join("\n").slice(0, 2200);
|
|
546701
|
+
}
|
|
546702
|
+
var VMEM_DIR, VENV_DIR2, VENV_PY, VENV_PIP2, VISUAL_MEMORY_ACTIONS, VisualMemoryTool;
|
|
546591
546703
|
var init_visual_memory = __esm({
|
|
546592
546704
|
"packages/execution/dist/tools/visual-memory.js"() {
|
|
546593
546705
|
"use strict";
|
|
546594
546706
|
init_cuda_device_filter();
|
|
546707
|
+
init_clip_feature_python();
|
|
546595
546708
|
VMEM_DIR = join80(homedir20(), ".omnius", "visual-memory");
|
|
546596
546709
|
VENV_DIR2 = join80(homedir20(), ".omnius", "vision-ml-venv");
|
|
546597
546710
|
VENV_PY = join80(VENV_DIR2, "bin", "python3");
|
|
546598
546711
|
VENV_PIP2 = join80(VENV_DIR2, "bin", "pip");
|
|
546712
|
+
VISUAL_MEMORY_ACTIONS = /* @__PURE__ */ new Set(["detect", "enroll", "identify", "teach", "recognize", "describe", "list", "forget"]);
|
|
546599
546713
|
VisualMemoryTool = class {
|
|
546600
546714
|
name = "visual_memory";
|
|
546601
|
-
description = "Persistent visual memory —
|
|
546715
|
+
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
546716
|
parameters = {
|
|
546603
546717
|
type: "object",
|
|
546604
546718
|
properties: {
|
|
546605
546719
|
action: {
|
|
546606
546720
|
type: "string",
|
|
546607
|
-
enum: ["detect", "enroll", "identify", "teach", "recognize", "list", "forget"],
|
|
546608
|
-
description: "Action: detect/enroll/identify faces, teach/recognize objects, list/forget memory"
|
|
546721
|
+
enum: ["detect", "enroll", "identify", "teach", "recognize", "describe", "list", "forget"],
|
|
546722
|
+
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
546723
|
},
|
|
546610
546724
|
image: {
|
|
546611
546725
|
type: "string",
|
|
546612
|
-
description: "Path to image file (JPEG/PNG). Required for detect/enroll/identify/teach/recognize."
|
|
546726
|
+
description: "Path to image file (JPEG/PNG). Required for detect/enroll/identify/teach/recognize/describe."
|
|
546727
|
+
},
|
|
546728
|
+
path: {
|
|
546729
|
+
type: "string",
|
|
546730
|
+
description: "Alias for image path."
|
|
546731
|
+
},
|
|
546732
|
+
file: {
|
|
546733
|
+
type: "string",
|
|
546734
|
+
description: "Alias for image path."
|
|
546735
|
+
},
|
|
546736
|
+
media: {
|
|
546737
|
+
type: "string",
|
|
546738
|
+
description: "Alias for image path."
|
|
546613
546739
|
},
|
|
546614
546740
|
name: {
|
|
546615
546741
|
type: "string",
|
|
546616
|
-
description: "Person name (for 'enroll') or object label (for 'teach').
|
|
546742
|
+
description: "Person name (for 'enroll') or object label (for 'teach')."
|
|
546743
|
+
},
|
|
546744
|
+
label: {
|
|
546745
|
+
type: "string",
|
|
546746
|
+
description: "Alias for name when teaching an object or enrolling a person from an associated label."
|
|
546747
|
+
},
|
|
546748
|
+
title: {
|
|
546749
|
+
type: "string",
|
|
546750
|
+
description: "Alias for name/label when a manifest or metadata title identifies the visual subject."
|
|
546617
546751
|
},
|
|
546618
546752
|
id: {
|
|
546619
546753
|
type: "string",
|
|
@@ -546630,15 +546764,23 @@ var init_visual_memory = __esm({
|
|
|
546630
546764
|
},
|
|
546631
546765
|
labels: {
|
|
546632
546766
|
type: "array",
|
|
546633
|
-
description: "
|
|
546767
|
+
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.",
|
|
546768
|
+
items: { type: "string" }
|
|
546769
|
+
},
|
|
546770
|
+
aliases: {
|
|
546771
|
+
type: "array",
|
|
546772
|
+
description: "Additional label aliases. aliases[0] is accepted as the primary label when name/label/labels are omitted.",
|
|
546634
546773
|
items: { type: "string" }
|
|
546635
546774
|
}
|
|
546636
546775
|
},
|
|
546637
|
-
required: [
|
|
546776
|
+
required: []
|
|
546638
546777
|
};
|
|
546639
546778
|
async execute(args) {
|
|
546640
|
-
const action = args
|
|
546779
|
+
const action = normalizeVisualMemoryAction(args);
|
|
546641
546780
|
const start2 = performance.now();
|
|
546781
|
+
if (!VISUAL_MEMORY_ACTIONS.has(action)) {
|
|
546782
|
+
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 };
|
|
546783
|
+
}
|
|
546642
546784
|
if (!await this.ensureVenv()) {
|
|
546643
546785
|
return { success: false, output: "", error: "Could not set up vision ML environment. Needs Python 3.10+.", durationMs: performance.now() - start2 };
|
|
546644
546786
|
}
|
|
@@ -546656,6 +546798,11 @@ var init_visual_memory = __esm({
|
|
|
546656
546798
|
return await this.teachObject(args, start2);
|
|
546657
546799
|
case "recognize":
|
|
546658
546800
|
return await this.recognizeObjects(args, start2);
|
|
546801
|
+
case "describe":
|
|
546802
|
+
return await this.recognizeObjects({
|
|
546803
|
+
...args,
|
|
546804
|
+
threshold: typeof args["threshold"] === "number" ? args["threshold"] : -1
|
|
546805
|
+
}, start2);
|
|
546659
546806
|
case "list":
|
|
546660
546807
|
return await this.listMemory(start2);
|
|
546661
546808
|
case "forget":
|
|
@@ -546671,7 +546818,7 @@ var init_visual_memory = __esm({
|
|
|
546671
546818
|
// Face Detection
|
|
546672
546819
|
// =========================================================================
|
|
546673
546820
|
async detectFaces(args, start2) {
|
|
546674
|
-
const image = args
|
|
546821
|
+
const image = imagePathArg(args);
|
|
546675
546822
|
if (!image || !existsSync66(image)) {
|
|
546676
546823
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546677
546824
|
}
|
|
@@ -546684,7 +546831,7 @@ app = FaceAnalysis(name='buffalo_s', providers=['CUDAExecutionProvider', 'CPUExe
|
|
|
546684
546831
|
app.prepare(ctx_id=0, det_size=(640, 640))
|
|
546685
546832
|
|
|
546686
546833
|
import cv2
|
|
546687
|
-
img = cv2.imread(
|
|
546834
|
+
img = cv2.imread(${pyLiteral(image)})
|
|
546688
546835
|
if img is None:
|
|
546689
546836
|
print(json.dumps({"success": False, "error": "Could not read image"}))
|
|
546690
546837
|
sys.exit(0)
|
|
@@ -546716,8 +546863,8 @@ ${JSON.stringify(result.faces, null, 2)}`, durationMs: performance.now() - start
|
|
|
546716
546863
|
// Face Enrollment
|
|
546717
546864
|
// =========================================================================
|
|
546718
546865
|
async enrollFace(args, start2) {
|
|
546719
|
-
const image = args
|
|
546720
|
-
const name10 = args
|
|
546866
|
+
const image = imagePathArg(args);
|
|
546867
|
+
const name10 = associationLabelArg(args);
|
|
546721
546868
|
if (!image || !existsSync66(image))
|
|
546722
546869
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546723
546870
|
if (!name10)
|
|
@@ -546730,7 +546877,7 @@ app = FaceAnalysis(name='buffalo_s', providers=['CUDAExecutionProvider', 'CPUExe
|
|
|
546730
546877
|
app.prepare(ctx_id=0, det_size=(640, 640))
|
|
546731
546878
|
|
|
546732
546879
|
import cv2
|
|
546733
|
-
img = cv2.imread(
|
|
546880
|
+
img = cv2.imread(${pyLiteral(image)})
|
|
546734
546881
|
if img is None:
|
|
546735
546882
|
print(json.dumps({"success": False, "error": "Could not read image"}))
|
|
546736
546883
|
sys.exit(0)
|
|
@@ -546751,9 +546898,9 @@ if os.path.exists(db_path):
|
|
|
546751
546898
|
with open(db_path) as f:
|
|
546752
546899
|
db = json.load(f)
|
|
546753
546900
|
|
|
546754
|
-
person_id =
|
|
546901
|
+
person_id = ${pyLiteral(name10)}.lower().replace(" ", "_").replace("'", "")
|
|
546755
546902
|
if person_id not in db:
|
|
546756
|
-
db[person_id] = {"name":
|
|
546903
|
+
db[person_id] = {"name": ${pyLiteral(name10)}, "embeddings": [], "created_at": time.time()}
|
|
546757
546904
|
|
|
546758
546905
|
db[person_id]["embeddings"].append(embedding)
|
|
546759
546906
|
db[person_id]["updated_at"] = time.time()
|
|
@@ -546765,7 +546912,7 @@ with open(db_path, "w") as f:
|
|
|
546765
546912
|
print(json.dumps({
|
|
546766
546913
|
"success": True,
|
|
546767
546914
|
"person_id": person_id,
|
|
546768
|
-
"name":
|
|
546915
|
+
"name": ${pyLiteral(name10)},
|
|
546769
546916
|
"samples": sample_count,
|
|
546770
546917
|
"total_people": len(db),
|
|
546771
546918
|
"confidence": float(face.det_score),
|
|
@@ -546786,7 +546933,7 @@ print(json.dumps({
|
|
|
546786
546933
|
// Face Identification
|
|
546787
546934
|
// =========================================================================
|
|
546788
546935
|
async identifyFaces(args, start2) {
|
|
546789
|
-
const image = args
|
|
546936
|
+
const image = imagePathArg(args);
|
|
546790
546937
|
if (!image || !existsSync66(image))
|
|
546791
546938
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546792
546939
|
const threshold = args["threshold"] || 0.5;
|
|
@@ -546799,7 +546946,7 @@ app = FaceAnalysis(name='buffalo_s', providers=['CUDAExecutionProvider', 'CPUExe
|
|
|
546799
546946
|
app.prepare(ctx_id=0, det_size=(640, 640))
|
|
546800
546947
|
|
|
546801
546948
|
import cv2
|
|
546802
|
-
img = cv2.imread(
|
|
546949
|
+
img = cv2.imread(${pyLiteral(image)})
|
|
546803
546950
|
if img is None:
|
|
546804
546951
|
print(json.dumps({"success": False, "error": "Could not read image"}))
|
|
546805
546952
|
sys.exit(0)
|
|
@@ -546883,37 +547030,51 @@ ${lines.join("\n")}`,
|
|
|
546883
547030
|
// Object Teaching (CLIP/SigLIP)
|
|
546884
547031
|
// =========================================================================
|
|
546885
547032
|
async teachObject(args, start2) {
|
|
546886
|
-
const image = args
|
|
546887
|
-
const label = args
|
|
547033
|
+
const image = imagePathArg(args);
|
|
547034
|
+
const label = associationLabelArg(args);
|
|
546888
547035
|
if (!image || !existsSync66(image))
|
|
546889
547036
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546890
547037
|
if (!label)
|
|
546891
547038
|
return { success: false, output: "", error: "Provide a label for the object.", durationMs: performance.now() - start2 };
|
|
547039
|
+
const aliases = [...new Set([
|
|
547040
|
+
label,
|
|
547041
|
+
...stringListArg(args["labels"]),
|
|
547042
|
+
...stringListArg(args["aliases"])
|
|
547043
|
+
].map((item) => item.trim()).filter(Boolean))];
|
|
546892
547044
|
const result = await this.runVisionPython(`
|
|
546893
|
-
import json, sys, os, time
|
|
547045
|
+
import json, sys, os, time, hashlib
|
|
546894
547046
|
import torch
|
|
546895
547047
|
from PIL import Image
|
|
546896
547048
|
from transformers import CLIPProcessor, CLIPModel
|
|
546897
547049
|
|
|
547050
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547051
|
+
|
|
547052
|
+
image_path = ${pyLiteral(image)}
|
|
547053
|
+
label = ${pyLiteral(label)}
|
|
547054
|
+
aliases = ${JSON.stringify(aliases)}
|
|
547055
|
+
with open(image_path, "rb") as f:
|
|
547056
|
+
image_hash = hashlib.sha256(f.read()).hexdigest()
|
|
547057
|
+
|
|
546898
547058
|
# Use CLIP ViT-B/32 — good balance of speed and quality
|
|
546899
547059
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
546900
547060
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
546901
547061
|
|
|
546902
|
-
img = Image.open(
|
|
547062
|
+
img = Image.open(image_path).convert("RGB")
|
|
546903
547063
|
inputs = processor(images=img, return_tensors="pt")
|
|
546904
547064
|
with torch.no_grad():
|
|
546905
|
-
image_features = model.get_image_features(**inputs)
|
|
546906
|
-
image_features = image_features / image_features.norm(dim=-1, keepdim=True)
|
|
547065
|
+
image_features = _omnius_normalized_features(model.get_image_features(**inputs))
|
|
546907
547066
|
|
|
546908
547067
|
embedding = image_features[0].cpu().numpy().tolist()
|
|
546909
547068
|
|
|
546910
|
-
# Also embed the text label for cross-modal retrieval
|
|
546911
|
-
text_inputs = processor(text=
|
|
547069
|
+
# Also embed the text label and aliases for cross-modal retrieval
|
|
547070
|
+
text_inputs = processor(text=aliases, return_tensors="pt", padding=True)
|
|
546912
547071
|
with torch.no_grad():
|
|
546913
|
-
text_features = model.get_text_features(**text_inputs)
|
|
546914
|
-
text_features = text_features / text_features.norm(dim=-1, keepdim=True)
|
|
547072
|
+
text_features = _omnius_normalized_features(model.get_text_features(**text_inputs))
|
|
546915
547073
|
|
|
546916
|
-
|
|
547074
|
+
text_embeddings = {}
|
|
547075
|
+
for i, alias in enumerate(aliases):
|
|
547076
|
+
text_embeddings[alias] = text_features[i].cpu().numpy().tolist()
|
|
547077
|
+
text_embedding = text_embeddings[aliases[0]]
|
|
546917
547078
|
|
|
546918
547079
|
# Store in object database
|
|
546919
547080
|
db_path = "${VMEM_DIR}/objects.json"
|
|
@@ -546922,12 +547083,19 @@ if os.path.exists(db_path):
|
|
|
546922
547083
|
with open(db_path) as f:
|
|
546923
547084
|
db = json.load(f)
|
|
546924
547085
|
|
|
546925
|
-
obj_id =
|
|
547086
|
+
obj_id = label.lower().replace(" ", "_").replace("'", "")
|
|
546926
547087
|
if obj_id not in db:
|
|
546927
|
-
db[obj_id] = {"label":
|
|
547088
|
+
db[obj_id] = {"label": label, "aliases": [], "image_embeddings": [], "image_hashes": [], "text_embeddings": {}, "text_embedding": text_embedding, "created_at": time.time()}
|
|
546928
547089
|
|
|
546929
|
-
db[obj_id]
|
|
547090
|
+
existing_hashes = set(db[obj_id].get("image_hashes", []))
|
|
547091
|
+
duplicate_sample = image_hash in existing_hashes
|
|
547092
|
+
if not duplicate_sample:
|
|
547093
|
+
db[obj_id].setdefault("image_embeddings", []).append(embedding)
|
|
547094
|
+
db[obj_id].setdefault("image_hashes", []).append(image_hash)
|
|
546930
547095
|
db[obj_id]["text_embedding"] = text_embedding # update with latest
|
|
547096
|
+
db[obj_id].setdefault("text_embeddings", {}).update(text_embeddings)
|
|
547097
|
+
merged_aliases = list(dict.fromkeys([db[obj_id].get("label", label)] + db[obj_id].get("aliases", []) + aliases))
|
|
547098
|
+
db[obj_id]["aliases"] = merged_aliases
|
|
546931
547099
|
db[obj_id]["updated_at"] = time.time()
|
|
546932
547100
|
sample_count = len(db[obj_id]["image_embeddings"])
|
|
546933
547101
|
|
|
@@ -546937,10 +547105,12 @@ with open(db_path, "w") as f:
|
|
|
546937
547105
|
print(json.dumps({
|
|
546938
547106
|
"success": True,
|
|
546939
547107
|
"object_id": obj_id,
|
|
546940
|
-
"label":
|
|
547108
|
+
"label": label,
|
|
547109
|
+
"aliases": merged_aliases,
|
|
546941
547110
|
"samples": sample_count,
|
|
546942
547111
|
"total_objects": len(db),
|
|
546943
547112
|
"embedding_dim": len(embedding),
|
|
547113
|
+
"duplicate_sample": duplicate_sample,
|
|
546944
547114
|
}))
|
|
546945
547115
|
`, 12e4);
|
|
546946
547116
|
if (!result.success)
|
|
@@ -546949,7 +547119,9 @@ print(json.dumps({
|
|
|
546949
547119
|
success: true,
|
|
546950
547120
|
output: `Taught object "${result.label}" (ID: ${result.object_id})
|
|
546951
547121
|
Samples: ${result.samples}
|
|
546952
|
-
|
|
547122
|
+
Aliases: ${(result.aliases || []).join(", ") || result.label}
|
|
547123
|
+
` + (result.duplicate_sample ? ` Duplicate sample skipped for same image hash
|
|
547124
|
+
` : "") + ` Embedding: ${result.embedding_dim}d CLIP vector
|
|
546953
547125
|
Total objects in memory: ${result.total_objects}`,
|
|
546954
547126
|
durationMs: performance.now() - start2
|
|
546955
547127
|
};
|
|
@@ -546958,11 +547130,11 @@ print(json.dumps({
|
|
|
546958
547130
|
// Object Recognition
|
|
546959
547131
|
// =========================================================================
|
|
546960
547132
|
async recognizeObjects(args, start2) {
|
|
546961
|
-
const image = args
|
|
547133
|
+
const image = imagePathArg(args);
|
|
546962
547134
|
if (!image || !existsSync66(image))
|
|
546963
547135
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
546964
|
-
const threshold = args["threshold"]
|
|
546965
|
-
const extraLabels = args["labels"]
|
|
547136
|
+
const threshold = typeof args["threshold"] === "number" ? args["threshold"] : 0.3;
|
|
547137
|
+
const extraLabels = stringListArg(args["labels"]);
|
|
546966
547138
|
const wantsJson = args["format"] === "json" || args["json"] === true;
|
|
546967
547139
|
const result = await this.runVisionPython(`
|
|
546968
547140
|
import json, sys, os, numpy as np
|
|
@@ -546970,16 +547142,17 @@ import torch
|
|
|
546970
547142
|
from PIL import Image
|
|
546971
547143
|
from transformers import CLIPProcessor, CLIPModel
|
|
546972
547144
|
|
|
547145
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547146
|
+
|
|
546973
547147
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
546974
547148
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
546975
547149
|
|
|
546976
|
-
img = Image.open(
|
|
547150
|
+
img = Image.open(${pyLiteral(image)}).convert("RGB")
|
|
546977
547151
|
|
|
546978
547152
|
# Get image embedding
|
|
546979
547153
|
inputs = processor(images=img, return_tensors="pt")
|
|
546980
547154
|
with torch.no_grad():
|
|
546981
|
-
image_features = model.get_image_features(**inputs)
|
|
546982
|
-
image_features = image_features / image_features.norm(dim=-1, keepdim=True)
|
|
547155
|
+
image_features = _omnius_normalized_features(model.get_image_features(**inputs))
|
|
546983
547156
|
|
|
546984
547157
|
query = image_features[0].cpu().numpy()
|
|
546985
547158
|
|
|
@@ -546994,13 +547167,30 @@ if os.path.exists(db_path):
|
|
|
546994
547167
|
matches = []
|
|
546995
547168
|
for obj_id, data in db.items():
|
|
546996
547169
|
best_sim = -1
|
|
546997
|
-
for emb in data
|
|
547170
|
+
for emb in data.get("image_embeddings", []):
|
|
546998
547171
|
sim = float(np.dot(query, np.array(emb, dtype=np.float32)))
|
|
546999
547172
|
if sim > best_sim:
|
|
547000
547173
|
best_sim = sim
|
|
547001
547174
|
|
|
547002
|
-
# Also score against text label
|
|
547003
|
-
text_sim =
|
|
547175
|
+
# Also score against all stored text label/alias embeddings
|
|
547176
|
+
text_sim = -1
|
|
547177
|
+
best_text_label = data.get("label", obj_id)
|
|
547178
|
+
text_embeddings = data.get("text_embeddings")
|
|
547179
|
+
if isinstance(text_embeddings, dict) and text_embeddings:
|
|
547180
|
+
iterable = text_embeddings.items()
|
|
547181
|
+
elif data.get("text_embedding") is not None:
|
|
547182
|
+
iterable = [(data.get("label", obj_id), data["text_embedding"])]
|
|
547183
|
+
else:
|
|
547184
|
+
iterable = []
|
|
547185
|
+
for alias, emb in iterable:
|
|
547186
|
+
sim = float(np.dot(query, np.array(emb, dtype=np.float32)))
|
|
547187
|
+
if sim > text_sim:
|
|
547188
|
+
text_sim = sim
|
|
547189
|
+
best_text_label = alias
|
|
547190
|
+
if text_sim < 0:
|
|
547191
|
+
text_sim = 0
|
|
547192
|
+
if best_sim < 0:
|
|
547193
|
+
best_sim = 0
|
|
547004
547194
|
|
|
547005
547195
|
# Blend: 60% image similarity, 40% text similarity
|
|
547006
547196
|
blended = 0.6 * best_sim + 0.4 * text_sim
|
|
@@ -547008,6 +547198,8 @@ for obj_id, data in db.items():
|
|
|
547008
547198
|
matches.append({
|
|
547009
547199
|
"object_id": obj_id,
|
|
547010
547200
|
"label": data["label"],
|
|
547201
|
+
"matched_alias": best_text_label,
|
|
547202
|
+
"aliases": data.get("aliases", []),
|
|
547011
547203
|
"image_similarity": round(best_sim, 3),
|
|
547012
547204
|
"text_similarity": round(text_sim, 3),
|
|
547013
547205
|
"blended_score": round(blended, 3),
|
|
@@ -547022,8 +547214,7 @@ extra_labels = ${JSON.stringify(extraLabels)}
|
|
|
547022
547214
|
if extra_labels:
|
|
547023
547215
|
text_inputs = processor(text=extra_labels, return_tensors="pt", padding=True)
|
|
547024
547216
|
with torch.no_grad():
|
|
547025
|
-
text_features = model.get_text_features(**text_inputs)
|
|
547026
|
-
text_features = text_features / text_features.norm(dim=-1, keepdim=True)
|
|
547217
|
+
text_features = _omnius_normalized_features(model.get_text_features(**text_inputs))
|
|
547027
547218
|
|
|
547028
547219
|
for i, label in enumerate(extra_labels):
|
|
547029
547220
|
sim = float(np.dot(query, text_features[i].cpu().numpy()))
|
|
@@ -547089,7 +547280,7 @@ ${objects.join("\n") || " (none taught)"}`,
|
|
|
547089
547280
|
};
|
|
547090
547281
|
}
|
|
547091
547282
|
async forgetEntry(args, start2) {
|
|
547092
|
-
const id = (args
|
|
547283
|
+
const id = stringArg2(args, "id", "name", "label").toLowerCase().replace(/\s/g, "_");
|
|
547093
547284
|
if (!id)
|
|
547094
547285
|
return { success: false, output: "", error: "Provide the ID or name of the person/object to forget.", durationMs: performance.now() - start2 };
|
|
547095
547286
|
let removed = false;
|
|
@@ -547165,7 +547356,7 @@ ${objects.join("\n") || " (none taught)"}`,
|
|
|
547165
547356
|
}
|
|
547166
547357
|
}
|
|
547167
547358
|
}
|
|
547168
|
-
throw new Error(
|
|
547359
|
+
throw new Error(summarizeProcessFailure(stdout, stderr));
|
|
547169
547360
|
}
|
|
547170
547361
|
}
|
|
547171
547362
|
};
|
|
@@ -547182,6 +547373,7 @@ var MM_DIR, MM_INDEX, MultimodalMemoryTool;
|
|
|
547182
547373
|
var init_multimodal_memory = __esm({
|
|
547183
547374
|
"packages/execution/dist/tools/multimodal-memory.js"() {
|
|
547184
547375
|
"use strict";
|
|
547376
|
+
init_clip_feature_python();
|
|
547185
547377
|
MM_DIR = join81(homedir21(), ".omnius", "multimodal-episodes");
|
|
547186
547378
|
MM_INDEX = join81(MM_DIR, "index.json");
|
|
547187
547379
|
MultimodalMemoryTool = class {
|
|
@@ -547275,13 +547467,13 @@ var init_multimodal_memory = __esm({
|
|
|
547275
547467
|
import json, torch
|
|
547276
547468
|
from PIL import Image
|
|
547277
547469
|
from transformers import CLIPProcessor, CLIPModel
|
|
547470
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547278
547471
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
547279
547472
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
547280
547473
|
img = Image.open("${imagePath}").convert("RGB")
|
|
547281
547474
|
inputs = processor(images=img, return_tensors="pt")
|
|
547282
547475
|
with torch.no_grad():
|
|
547283
|
-
features = model.get_image_features(**inputs)
|
|
547284
|
-
features = features / features.norm(dim=-1, keepdim=True)
|
|
547476
|
+
features = _omnius_normalized_features(model.get_image_features(**inputs))
|
|
547285
547477
|
print(json.dumps(features[0].cpu().numpy().tolist()))
|
|
547286
547478
|
`;
|
|
547287
547479
|
const scriptFile = join81(tmpdir17(), `mm-clip-${Date.now()}.py`);
|
|
@@ -547501,12 +547693,12 @@ Recall later: multimodal_memory action=recall query="${personName}"`,
|
|
|
547501
547693
|
const clipTextScript = `
|
|
547502
547694
|
import json, torch
|
|
547503
547695
|
from transformers import CLIPProcessor, CLIPModel
|
|
547696
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547504
547697
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
547505
547698
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
547506
547699
|
inputs = processor(text=["${query.replace(/"/g, '\\"').replace(/\n/g, " ")}"], return_tensors="pt", padding=True)
|
|
547507
547700
|
with torch.no_grad():
|
|
547508
|
-
features = model.get_text_features(**inputs)
|
|
547509
|
-
features = features / features.norm(dim=-1, keepdim=True)
|
|
547701
|
+
features = _omnius_normalized_features(model.get_text_features(**inputs))
|
|
547510
547702
|
print(json.dumps(features[0].cpu().numpy().tolist()))
|
|
547511
547703
|
`;
|
|
547512
547704
|
const scriptFile = join81(tmpdir17(), `mm-clipq-${Date.now()}.py`);
|
|
@@ -558355,6 +558547,15 @@ function nowIso2(now2 = /* @__PURE__ */ new Date()) {
|
|
|
558355
558547
|
function cleanText(value2, max = 600) {
|
|
558356
558548
|
return String(value2 ?? "").replace(/\s+/g, " ").trim().slice(0, max);
|
|
558357
558549
|
}
|
|
558550
|
+
function normalizeEvidencePath(value2) {
|
|
558551
|
+
return String(value2 ?? "").trim().replace(/^file:\/\//i, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "");
|
|
558552
|
+
}
|
|
558553
|
+
function cleanTargetPaths(paths) {
|
|
558554
|
+
if (!Array.isArray(paths))
|
|
558555
|
+
return [];
|
|
558556
|
+
const cleaned = paths.map(normalizeEvidencePath).filter((path12) => path12.length > 0).slice(0, 20);
|
|
558557
|
+
return [...new Set(cleaned)];
|
|
558558
|
+
}
|
|
558358
558559
|
function convertPipesToUnicode(text2) {
|
|
558359
558560
|
return text2.replace(/\|/g, "│");
|
|
558360
558561
|
}
|
|
@@ -558430,6 +558631,7 @@ function deriveClaimsFromProposedText(input) {
|
|
|
558430
558631
|
});
|
|
558431
558632
|
}
|
|
558432
558633
|
function recordCompletionEvidence(ledger, evidence) {
|
|
558634
|
+
const targetPaths = cleanTargetPaths(evidence.targetPaths);
|
|
558433
558635
|
const entry = {
|
|
558434
558636
|
id: evidence.id ?? nextId2("ev", ledger.evidence.length),
|
|
558435
558637
|
kind: evidence.kind,
|
|
@@ -558437,7 +558639,8 @@ function recordCompletionEvidence(ledger, evidence) {
|
|
|
558437
558639
|
summary: cleanText(evidence.summary, 1200),
|
|
558438
558640
|
toolName: evidence.toolName,
|
|
558439
558641
|
success: evidence.success,
|
|
558440
|
-
rawRef: evidence.rawRef
|
|
558642
|
+
rawRef: evidence.rawRef,
|
|
558643
|
+
...targetPaths.length > 0 ? { targetPaths } : {}
|
|
558441
558644
|
};
|
|
558442
558645
|
return {
|
|
558443
558646
|
...ledger,
|
|
@@ -558457,7 +558660,8 @@ function recordToolEvidence(ledger, input) {
|
|
|
558457
558660
|
toolName: input.name,
|
|
558458
558661
|
success: input.success,
|
|
558459
558662
|
summary,
|
|
558460
|
-
rawRef: input.rawRef
|
|
558663
|
+
rawRef: input.rawRef,
|
|
558664
|
+
targetPaths: input.targetPaths
|
|
558461
558665
|
});
|
|
558462
558666
|
}
|
|
558463
558667
|
function addCompletionClaims(ledger, claims) {
|
|
@@ -558596,6 +558800,55 @@ function isMutationEvidence(entry) {
|
|
|
558596
558800
|
return true;
|
|
558597
558801
|
return entry.success === true && /^(file_write|file_edit|file_patch|batch_edit)$/.test(entry.toolName ?? "");
|
|
558598
558802
|
}
|
|
558803
|
+
function evidenceTargetPaths(entry) {
|
|
558804
|
+
const explicit = cleanTargetPaths(entry.targetPaths);
|
|
558805
|
+
if (explicit.length > 0)
|
|
558806
|
+
return explicit;
|
|
558807
|
+
const paths = [];
|
|
558808
|
+
if (entry.rawRef?.startsWith("file://")) {
|
|
558809
|
+
paths.push(entry.rawRef.slice("file://".length));
|
|
558810
|
+
}
|
|
558811
|
+
const fileChange = entry.summary.match(/\bfile change:\s*([^\s,;]+)/i);
|
|
558812
|
+
if (fileChange?.[1])
|
|
558813
|
+
paths.push(fileChange[1]);
|
|
558814
|
+
const quotedPathRe = /"(?:path|file_path|file|filename|filepath|filePath)"\s*:\s*"([^"]+)"/g;
|
|
558815
|
+
for (const match of entry.summary.matchAll(quotedPathRe)) {
|
|
558816
|
+
if (match[1])
|
|
558817
|
+
paths.push(match[1]);
|
|
558818
|
+
}
|
|
558819
|
+
const loosePathRe = /\b(?:path|file_path|file|filename|filepath|filePath)=([^,\s}\]]+)/g;
|
|
558820
|
+
for (const match of entry.summary.matchAll(loosePathRe)) {
|
|
558821
|
+
if (match[1])
|
|
558822
|
+
paths.push(match[1].replace(/^["']|["']$/g, ""));
|
|
558823
|
+
}
|
|
558824
|
+
return cleanTargetPaths(paths);
|
|
558825
|
+
}
|
|
558826
|
+
function pathsEquivalent(a2, b) {
|
|
558827
|
+
const left = normalizeEvidencePath(a2);
|
|
558828
|
+
const right = normalizeEvidencePath(b);
|
|
558829
|
+
if (!left || !right)
|
|
558830
|
+
return false;
|
|
558831
|
+
return left === right || left.endsWith(`/${right}`) || right.endsWith(`/${left}`);
|
|
558832
|
+
}
|
|
558833
|
+
function isVerificationNeutralPath(path12) {
|
|
558834
|
+
const normalized = normalizeEvidencePath(path12).toLowerCase();
|
|
558835
|
+
const base3 = normalized.split("/").pop() ?? normalized;
|
|
558836
|
+
if (/\.(md|mdx|markdown|txt|rst|adoc)$/.test(base3))
|
|
558837
|
+
return true;
|
|
558838
|
+
if (/^(readme|changelog|changes|license|licence|notice|implementation_notes)(?:\.[^.]+)?$/.test(base3))
|
|
558839
|
+
return true;
|
|
558840
|
+
if (normalized.includes("/docs/") || normalized.startsWith("docs/"))
|
|
558841
|
+
return true;
|
|
558842
|
+
return false;
|
|
558843
|
+
}
|
|
558844
|
+
function isVerificationInvalidatingMutation(entry) {
|
|
558845
|
+
if (!isMutationEvidence(entry))
|
|
558846
|
+
return false;
|
|
558847
|
+
const paths = evidenceTargetPaths(entry);
|
|
558848
|
+
if (paths.length === 0)
|
|
558849
|
+
return true;
|
|
558850
|
+
return paths.some((path12) => !isVerificationNeutralPath(path12));
|
|
558851
|
+
}
|
|
558599
558852
|
function isSuccessfulVerificationEvidence(entry) {
|
|
558600
558853
|
if (entry.success !== true)
|
|
558601
558854
|
return false;
|
|
@@ -558627,14 +558880,72 @@ function isStaleEditEvidence(entry) {
|
|
|
558627
558880
|
const text2 = entry.summary.toLowerCase();
|
|
558628
558881
|
return /stale edit loop blocked|old[_ -]?string|old text|expected[_ -]?hash|context mismatch|no occurrences|could not find/.test(text2);
|
|
558629
558882
|
}
|
|
558883
|
+
function staleEditResolvedByLaterMutation(evidence, failedEntry, failedIndex) {
|
|
558884
|
+
const failedPaths = evidenceTargetPaths(failedEntry);
|
|
558885
|
+
if (failedPaths.length === 0)
|
|
558886
|
+
return false;
|
|
558887
|
+
for (const later of evidence.slice(failedIndex + 1)) {
|
|
558888
|
+
if (!isMutationEvidence(later) || later.success !== true)
|
|
558889
|
+
continue;
|
|
558890
|
+
const laterPaths = evidenceTargetPaths(later);
|
|
558891
|
+
if (laterPaths.some((laterPath) => failedPaths.some((failedPath) => pathsEquivalent(laterPath, failedPath)))) {
|
|
558892
|
+
return true;
|
|
558893
|
+
}
|
|
558894
|
+
}
|
|
558895
|
+
return false;
|
|
558896
|
+
}
|
|
558897
|
+
function extractClaimedAllTestsPassedCount(text2) {
|
|
558898
|
+
const match = text2.match(/\ball\s+(\d{1,6})\s+tests?\s+(?:pass|passed|passing)\b/i);
|
|
558899
|
+
return match?.[1] ? Number(match[1]) : null;
|
|
558900
|
+
}
|
|
558901
|
+
function extractObservedSuccessfulTestCount(text2) {
|
|
558902
|
+
const normalized = text2.replace(/\s+/g, " ");
|
|
558903
|
+
const testsPassed = normalized.match(/\btests?\s+(\d{1,6})\s+passed\b/i);
|
|
558904
|
+
if (testsPassed?.[1])
|
|
558905
|
+
return Number(testsPassed[1]);
|
|
558906
|
+
const testsLine = normalized.match(/\btests?\s*:?\s*(\d{1,6})\b/i);
|
|
558907
|
+
const passLine = normalized.match(/\bpass(?:ed)?\s*:?\s*(\d{1,6})\b/i);
|
|
558908
|
+
if (testsLine?.[1])
|
|
558909
|
+
return Number(testsLine[1]);
|
|
558910
|
+
if (passLine?.[1])
|
|
558911
|
+
return Number(passLine[1]);
|
|
558912
|
+
const passedTests = normalized.match(/\b(\d{1,6})\s+tests?\s+passed\b/i);
|
|
558913
|
+
if (passedTests?.[1])
|
|
558914
|
+
return Number(passedTests[1]);
|
|
558915
|
+
return null;
|
|
558916
|
+
}
|
|
558917
|
+
function latestObservedSuccessfulTestCount(evidence) {
|
|
558918
|
+
for (let index = evidence.length - 1; index >= 0; index--) {
|
|
558919
|
+
const entry = evidence[index];
|
|
558920
|
+
if (entry.success !== true || verificationFamily(entry) !== "test")
|
|
558921
|
+
continue;
|
|
558922
|
+
const count = extractObservedSuccessfulTestCount(entry.summary);
|
|
558923
|
+
if (count !== null && Number.isFinite(count))
|
|
558924
|
+
return count;
|
|
558925
|
+
}
|
|
558926
|
+
return null;
|
|
558927
|
+
}
|
|
558928
|
+
function appendTestCountOverclaims(ledger, unresolved) {
|
|
558929
|
+
const observed = latestObservedSuccessfulTestCount(ledger.evidence);
|
|
558930
|
+
if (observed === null)
|
|
558931
|
+
return unresolved;
|
|
558932
|
+
let next = unresolved;
|
|
558933
|
+
for (const claim of ledger.proposedClaims) {
|
|
558934
|
+
const claimed = extractClaimedAllTestsPassedCount(claim.text);
|
|
558935
|
+
if (claimed === null || claimed === observed)
|
|
558936
|
+
continue;
|
|
558937
|
+
next = appendUnresolved(next, `Completion claim overstates verification: claimed all ${claimed} tests pass, but latest successful test evidence reported ${observed}.`, claim.id);
|
|
558938
|
+
}
|
|
558939
|
+
return next;
|
|
558940
|
+
}
|
|
558630
558941
|
function finalizeCompletionLedgerTruth(ledger) {
|
|
558631
558942
|
let unresolved = [...ledger.unresolved];
|
|
558632
|
-
let
|
|
558943
|
+
let lastVerificationInvalidatingMutation = -1;
|
|
558633
558944
|
let lastVerification = -1;
|
|
558634
558945
|
const lastSuccessfulVerificationByFamily = /* @__PURE__ */ new Map();
|
|
558635
558946
|
ledger.evidence.forEach((entry, index) => {
|
|
558636
|
-
if (
|
|
558637
|
-
|
|
558947
|
+
if (isVerificationInvalidatingMutation(entry))
|
|
558948
|
+
lastVerificationInvalidatingMutation = index;
|
|
558638
558949
|
if (isSuccessfulVerificationEvidence(entry)) {
|
|
558639
558950
|
lastVerification = index;
|
|
558640
558951
|
const family = verificationFamily(entry);
|
|
@@ -558650,13 +558961,14 @@ function finalizeCompletionLedgerTruth(ledger) {
|
|
|
558650
558961
|
unresolved = appendUnresolved(unresolved, `Verification failed or did not prove success: ${entry.summary}`, entry.id);
|
|
558651
558962
|
}
|
|
558652
558963
|
}
|
|
558653
|
-
if (isStaleEditEvidence(entry)) {
|
|
558964
|
+
if (isStaleEditEvidence(entry) && !staleEditResolvedByLaterMutation(ledger.evidence, entry, index)) {
|
|
558654
558965
|
unresolved = appendUnresolved(unresolved, `Stale edit failure remains unresolved: ${entry.summary}`, entry.id);
|
|
558655
558966
|
}
|
|
558656
558967
|
});
|
|
558657
|
-
if (lastVerification >= 0 &&
|
|
558968
|
+
if (lastVerification >= 0 && lastVerificationInvalidatingMutation > lastVerification) {
|
|
558658
558969
|
unresolved = appendUnresolved(unresolved, "File changes occurred after the last successful verification; final verification is stale.", "verification_freshness");
|
|
558659
558970
|
}
|
|
558971
|
+
unresolved = appendTestCountOverclaims(ledger, unresolved);
|
|
558660
558972
|
const status = ledger.status === "blocked" || ledger.status === "request_changes" ? ledger.status : unresolved.length > 0 ? "incomplete_verification" : ledger.status;
|
|
558661
558973
|
return {
|
|
558662
558974
|
...ledger,
|
|
@@ -564299,12 +564611,12 @@ var init_reflectionBuffer = __esm({
|
|
|
564299
564611
|
if (!this.persistPath)
|
|
564300
564612
|
return;
|
|
564301
564613
|
try {
|
|
564302
|
-
const { writeFileSync:
|
|
564614
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106, existsSync: existsSync164 } = __require("node:fs");
|
|
564303
564615
|
const { join: join179 } = __require("node:path");
|
|
564304
564616
|
const dir = join179(this.persistPath, "..");
|
|
564305
564617
|
if (!existsSync164(dir))
|
|
564306
564618
|
mkdirSync106(dir, { recursive: true });
|
|
564307
|
-
|
|
564619
|
+
writeFileSync90(this.persistPath, JSON.stringify(this.state, null, 2));
|
|
564308
564620
|
} catch {
|
|
564309
564621
|
}
|
|
564310
564622
|
}
|
|
@@ -566961,7 +567273,6 @@ function normalizeFailurePatterns(patterns) {
|
|
|
566961
567273
|
});
|
|
566962
567274
|
}
|
|
566963
567275
|
function buildFailureModeHandoff(input) {
|
|
566964
|
-
const patterns = normalizeFailurePatterns(input.errorPatterns).slice(0, input.maxPatterns ?? 10);
|
|
566965
567276
|
const toolCalls = input.toolCallLog ?? [];
|
|
566966
567277
|
const maxRecentCalls = input.maxRecentCalls ?? 8;
|
|
566967
567278
|
const recentCalls = maxRecentCalls > 0 ? toolCalls.slice(-maxRecentCalls) : [];
|
|
@@ -566973,6 +567284,7 @@ function buildFailureModeHandoff(input) {
|
|
|
566973
567284
|
const currentStep = cleanInline(input.taskState?.currentStep, 180);
|
|
566974
567285
|
const nextAction = cleanInline(input.taskState?.nextAction, 180);
|
|
566975
567286
|
const goal = cleanInline(input.taskGoal || input.taskState?.goal || input.taskState?.originalGoal || "", 260);
|
|
567287
|
+
const patterns = normalizeFailurePatterns(input.errorPatterns).slice(0, input.maxPatterns ?? 10);
|
|
566976
567288
|
if (patterns.length === 0 && recentCalls.length === 0 && modified.length === 0 && failedApproaches.length === 0 && !goal) {
|
|
566977
567289
|
return null;
|
|
566978
567290
|
}
|
|
@@ -567915,12 +568227,12 @@ var init_adversaryStream = __esm({
|
|
|
567915
568227
|
if (!this.persistPath)
|
|
567916
568228
|
return;
|
|
567917
568229
|
try {
|
|
567918
|
-
const { writeFileSync:
|
|
568230
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106, existsSync: existsSync164 } = __require("node:fs");
|
|
567919
568231
|
const { dirname: dirname54 } = __require("node:path");
|
|
567920
568232
|
const dir = dirname54(this.persistPath);
|
|
567921
568233
|
if (!existsSync164(dir))
|
|
567922
568234
|
mkdirSync106(dir, { recursive: true });
|
|
567923
|
-
|
|
568235
|
+
writeFileSync90(this.persistPath, JSON.stringify({ ledger: this.ledger }, null, 2));
|
|
567924
568236
|
} catch {
|
|
567925
568237
|
}
|
|
567926
568238
|
}
|
|
@@ -567942,6 +568254,10 @@ function resolutionSystemPrompt() {
|
|
|
567942
568254
|
" - exit code 0 on an unrelated command does not resolve the request.",
|
|
567943
568255
|
" - Doing PART of the request, or adjacent work, is NOT resolution.",
|
|
567944
568256
|
" - If the request had multiple parts, EVERY part must be addressed.",
|
|
568257
|
+
" - If the original request explicitly allows a degraded fallback such as",
|
|
568258
|
+
" documenting/reporting a tool failure, that fallback can resolve the task",
|
|
568259
|
+
" only when the failure is clearly disclosed and the requested fallback",
|
|
568260
|
+
" artifact/report/verifier is evidenced.",
|
|
567945
568261
|
"",
|
|
567946
568262
|
"Respond with ONLY a JSON object, no prose, no code fences:",
|
|
567947
568263
|
'{"resolved": true|false,',
|
|
@@ -567953,6 +568269,25 @@ function resolutionSystemPrompt() {
|
|
|
567953
568269
|
"original request. When in doubt, resolved=false and name what is missing."
|
|
567954
568270
|
].join("\n");
|
|
567955
568271
|
}
|
|
568272
|
+
function detectExplicitDegradedCompletion(i2) {
|
|
568273
|
+
const original = i2.originalGoal.toLowerCase();
|
|
568274
|
+
const summary = i2.proposedSummary.toLowerCase();
|
|
568275
|
+
const evidence = `${i2.actionsDigest}
|
|
568276
|
+
${i2.evidenceDigest}`.toLowerCase();
|
|
568277
|
+
const permitsFallback = /\bif\b[\s\S]{0,160}\b(?:fails?|failed|failure|blocked|unavailable|cannot|can't|unable)\b[\s\S]{0,180}\b(?:document|report|note|record|summari[sz]e|explain)\b/.test(original) || /\b(?:document|report|note|record|summari[sz]e|explain)\b[\s\S]{0,180}\b(?:fails?|failed|failure|blocked|unavailable|cannot|can't|unable)\b/.test(original) || /\b(?:fallback|degraded|best effort|best-effort|honestly document|document honestly)\b/.test(original);
|
|
568278
|
+
if (!permitsFallback)
|
|
568279
|
+
return null;
|
|
568280
|
+
const disclosesFailure = /\b(?:fail(?:ed|ure)?|blocked|unable|could not|couldn't|cannot|can't|degraded|partial|not available|unavailable)\b/.test(summary);
|
|
568281
|
+
if (!disclosesFailure)
|
|
568282
|
+
return null;
|
|
568283
|
+
const hasFallbackEvidence = /\b(?:passed|success|succeeded|verified|wrote|created|saved|report|artifact|file changed|files changed|last test outcome: passed|exit code 0)\b/.test(evidence) || /\b(?:verifier|verification|report)\b/.test(summary);
|
|
568284
|
+
if (!hasFallbackEvidence)
|
|
568285
|
+
return null;
|
|
568286
|
+
return {
|
|
568287
|
+
accepted: true,
|
|
568288
|
+
reason: "original request explicitly allowed a degraded/failure-report fallback and the completion disclosed the failure with fallback evidence"
|
|
568289
|
+
};
|
|
568290
|
+
}
|
|
567956
568291
|
function buildResolutionPrompt(i2) {
|
|
567957
568292
|
return [
|
|
567958
568293
|
"ORIGINAL REQUEST (what the user actually asked for):",
|
|
@@ -568003,6 +568338,134 @@ var init_completion_resolution_verifier = __esm({
|
|
|
568003
568338
|
}
|
|
568004
568339
|
});
|
|
568005
568340
|
|
|
568341
|
+
// packages/orchestrator/dist/todoTruth.js
|
|
568342
|
+
function normalizeText2(value2) {
|
|
568343
|
+
return value2.toLowerCase().replace(/[_-]+/g, " ").replace(/[^a-z0-9./ ]+/g, " ").replace(/\s+/g, " ").trim();
|
|
568344
|
+
}
|
|
568345
|
+
function extractArg(argsKey, key) {
|
|
568346
|
+
if (!argsKey)
|
|
568347
|
+
return "";
|
|
568348
|
+
const re = new RegExp(`(?:^|,)${key}=([^,]+)`);
|
|
568349
|
+
return argsKey.match(re)?.[1]?.trim() ?? "";
|
|
568350
|
+
}
|
|
568351
|
+
function toolAliases(toolName) {
|
|
568352
|
+
const normalized = normalizeText2(toolName);
|
|
568353
|
+
const spaceAlias = normalizeText2(toolName.replace(/_/g, " "));
|
|
568354
|
+
const compactAlias = toolName.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
568355
|
+
return [...new Set([normalized, spaceAlias, compactAlias].filter(Boolean))];
|
|
568356
|
+
}
|
|
568357
|
+
function todoMentionsFailedCall(todo, call) {
|
|
568358
|
+
if (NON_WORK_TOOLS.has(call.name))
|
|
568359
|
+
return false;
|
|
568360
|
+
const content = normalizeText2(todo.content);
|
|
568361
|
+
const compactContent2 = todo.content.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
568362
|
+
const mentionsTool = toolAliases(call.name).some((alias) => {
|
|
568363
|
+
if (alias.length <= 2)
|
|
568364
|
+
return false;
|
|
568365
|
+
if (/^[a-z0-9]+$/.test(alias) && alias === call.name.toLowerCase().replace(/[^a-z0-9]+/g, "")) {
|
|
568366
|
+
return compactContent2.includes(alias);
|
|
568367
|
+
}
|
|
568368
|
+
return content.includes(alias);
|
|
568369
|
+
});
|
|
568370
|
+
if (!mentionsTool)
|
|
568371
|
+
return false;
|
|
568372
|
+
const action = normalizeText2(extractArg(call.argsKey, "action"));
|
|
568373
|
+
if (!action)
|
|
568374
|
+
return true;
|
|
568375
|
+
return content.includes(action) || action.length <= 2;
|
|
568376
|
+
}
|
|
568377
|
+
function evidenceLine(call) {
|
|
568378
|
+
const preview = String(call.outputPreview ?? "").split("\n").map((line) => line.trim()).find(Boolean);
|
|
568379
|
+
const action = extractArg(call.argsKey, "action");
|
|
568380
|
+
const detail = preview || "tool returned failure";
|
|
568381
|
+
return `${call.name}${action ? ` ${action}` : ""}: ${detail}`.slice(0, 260);
|
|
568382
|
+
}
|
|
568383
|
+
function hasLaterSuccessForSameFamily(calls, failedIndex) {
|
|
568384
|
+
const failed = calls[failedIndex];
|
|
568385
|
+
if (!failed)
|
|
568386
|
+
return false;
|
|
568387
|
+
const failedAction = normalizeText2(extractArg(failed.argsKey, "action"));
|
|
568388
|
+
for (let i2 = failedIndex + 1; i2 < calls.length; i2++) {
|
|
568389
|
+
const next = calls[i2];
|
|
568390
|
+
if (!next || next.success !== true || next.name !== failed.name)
|
|
568391
|
+
continue;
|
|
568392
|
+
const nextAction = normalizeText2(extractArg(next.argsKey, "action"));
|
|
568393
|
+
if (!failedAction || !nextAction || failedAction === nextAction)
|
|
568394
|
+
return true;
|
|
568395
|
+
}
|
|
568396
|
+
return false;
|
|
568397
|
+
}
|
|
568398
|
+
function firstUnresolvedChild(todo, childrenByParent) {
|
|
568399
|
+
const id = todo.id;
|
|
568400
|
+
if (!id)
|
|
568401
|
+
return null;
|
|
568402
|
+
const children2 = childrenByParent.get(id) ?? [];
|
|
568403
|
+
return children2.find((child) => child.status === "blocked") ?? children2.find((child) => child.status === "in_progress") ?? children2.find((child) => child.status === "pending") ?? null;
|
|
568404
|
+
}
|
|
568405
|
+
function reconcileCompletedTodosWithEvidence(input) {
|
|
568406
|
+
const nextTodos = input.todos.map((todo) => ({ ...todo }));
|
|
568407
|
+
const downgrades = [];
|
|
568408
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
568409
|
+
for (const todo of nextTodos) {
|
|
568410
|
+
if (!todo.parentId)
|
|
568411
|
+
continue;
|
|
568412
|
+
const arr = childrenByParent.get(todo.parentId) ?? [];
|
|
568413
|
+
arr.push(todo);
|
|
568414
|
+
childrenByParent.set(todo.parentId, arr);
|
|
568415
|
+
}
|
|
568416
|
+
for (const todo of nextTodos) {
|
|
568417
|
+
if (todo.status !== "completed")
|
|
568418
|
+
continue;
|
|
568419
|
+
const unresolvedChild = firstUnresolvedChild(todo, childrenByParent);
|
|
568420
|
+
if (unresolvedChild) {
|
|
568421
|
+
const childStatus = unresolvedChild.status;
|
|
568422
|
+
const targetStatus = childStatus === "blocked" ? "blocked" : "in_progress";
|
|
568423
|
+
const blocker2 = childStatus === "blocked" ? `Child todo blocked: ${unresolvedChild.content}${unresolvedChild.blocker ? ` (${unresolvedChild.blocker})` : ""}` : `Child todo not complete: [${childStatus}] ${unresolvedChild.content}`;
|
|
568424
|
+
downgrades.push({
|
|
568425
|
+
id: todo.id,
|
|
568426
|
+
content: todo.content,
|
|
568427
|
+
from: "completed",
|
|
568428
|
+
to: targetStatus,
|
|
568429
|
+
blocker: blocker2,
|
|
568430
|
+
evidence: blocker2
|
|
568431
|
+
});
|
|
568432
|
+
todo.status = targetStatus;
|
|
568433
|
+
todo.blocker = blocker2;
|
|
568434
|
+
continue;
|
|
568435
|
+
}
|
|
568436
|
+
const startTurn = todo.id && input.todoStartTurnById?.has(todo.id) ? input.todoStartTurnById.get(todo.id) : 0;
|
|
568437
|
+
const relevantCalls = input.toolCallLog.filter((call) => (call.turn ?? 0) >= startTurn);
|
|
568438
|
+
const failedIndex = relevantCalls.findIndex((call) => call.success === false && todoMentionsFailedCall(todo, call) && !hasLaterSuccessForSameFamily(relevantCalls, relevantCalls.indexOf(call)));
|
|
568439
|
+
if (failedIndex < 0)
|
|
568440
|
+
continue;
|
|
568441
|
+
const failed = relevantCalls[failedIndex];
|
|
568442
|
+
const evidence = evidenceLine(failed);
|
|
568443
|
+
const blocker = `Completion claim contradicted by failed ${failed.name} evidence. Reconfigure this subtask: verify whether the goal is already satisfied, choose a different target/tool, or leave the todo blocked with the root cause.`;
|
|
568444
|
+
downgrades.push({
|
|
568445
|
+
id: todo.id,
|
|
568446
|
+
content: todo.content,
|
|
568447
|
+
from: "completed",
|
|
568448
|
+
to: "blocked",
|
|
568449
|
+
blocker,
|
|
568450
|
+
evidence
|
|
568451
|
+
});
|
|
568452
|
+
todo.status = "blocked";
|
|
568453
|
+
todo.blocker = `${blocker} Evidence: ${evidence}`;
|
|
568454
|
+
}
|
|
568455
|
+
return {
|
|
568456
|
+
todos: nextTodos,
|
|
568457
|
+
changed: downgrades.length > 0,
|
|
568458
|
+
downgrades
|
|
568459
|
+
};
|
|
568460
|
+
}
|
|
568461
|
+
var NON_WORK_TOOLS;
|
|
568462
|
+
var init_todoTruth = __esm({
|
|
568463
|
+
"packages/orchestrator/dist/todoTruth.js"() {
|
|
568464
|
+
"use strict";
|
|
568465
|
+
NON_WORK_TOOLS = /* @__PURE__ */ new Set(["todo_write", "todo_read", "task_complete"]);
|
|
568466
|
+
}
|
|
568467
|
+
});
|
|
568468
|
+
|
|
568006
568469
|
// packages/orchestrator/dist/evidenceBranch.js
|
|
568007
568470
|
function buildStructuralPreview2(lines, path12, query) {
|
|
568008
568471
|
const n2 = lines.length;
|
|
@@ -570209,6 +570672,7 @@ var init_agenticRunner = __esm({
|
|
|
570209
570672
|
init_evidenceLedger();
|
|
570210
570673
|
init_adversaryStream();
|
|
570211
570674
|
init_completion_resolution_verifier();
|
|
570675
|
+
init_todoTruth();
|
|
570212
570676
|
init_evidenceBranch();
|
|
570213
570677
|
init_resolution_memory();
|
|
570214
570678
|
init_contextEngine();
|
|
@@ -570384,6 +570848,7 @@ var init_agenticRunner = __esm({
|
|
|
570384
570848
|
// Research: Kumaran et al. (2016) — complementary learning systems
|
|
570385
570849
|
// Fast learning from errors → immediate behavioral change
|
|
570386
570850
|
_errorPatterns = /* @__PURE__ */ new Map();
|
|
570851
|
+
_taskRelevantErrorPatterns = /* @__PURE__ */ new Map();
|
|
570387
570852
|
_errorGuidanceInjected = /* @__PURE__ */ new Set();
|
|
570388
570853
|
// prevent duplicate injection per turn
|
|
570389
570854
|
// REG-26 (Patch C): Reflexion-style structured failure memory. Indexed by
|
|
@@ -570961,6 +571426,145 @@ ${parts.join("\n")}
|
|
|
570961
571426
|
writesUserTaskArtifacts() {
|
|
570962
571427
|
return this.options.artifactMode === "user-task" && !this.options.subAgent;
|
|
570963
571428
|
}
|
|
571429
|
+
_backendModelLabel(backend = this.backend) {
|
|
571430
|
+
const b = backend;
|
|
571431
|
+
const direct = b["model"] ?? b["resolvedModel"] ?? b["modelName"];
|
|
571432
|
+
if (typeof direct === "string" && direct.trim())
|
|
571433
|
+
return direct.trim();
|
|
571434
|
+
const nested = b["config"];
|
|
571435
|
+
if (nested && typeof nested === "object") {
|
|
571436
|
+
const model = nested["model"];
|
|
571437
|
+
if (typeof model === "string" && model.trim())
|
|
571438
|
+
return model.trim();
|
|
571439
|
+
}
|
|
571440
|
+
return "unknown";
|
|
571441
|
+
}
|
|
571442
|
+
_emitModelResolutionTelemetry(purpose, turn) {
|
|
571443
|
+
try {
|
|
571444
|
+
const backendName = this.backend.constructor?.name ?? "unknown";
|
|
571445
|
+
const resolved = this._backendModelLabel(this.backend);
|
|
571446
|
+
this.emit({
|
|
571447
|
+
type: "status",
|
|
571448
|
+
content: `Model resolution: purpose=${purpose} resolved=${resolved} backend=${backendName}`,
|
|
571449
|
+
turn,
|
|
571450
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
571451
|
+
});
|
|
571452
|
+
} catch {
|
|
571453
|
+
}
|
|
571454
|
+
}
|
|
571455
|
+
_cosineSimilarity(a2, b) {
|
|
571456
|
+
if (!a2 || !b || a2.length !== b.length || a2.length === 0)
|
|
571457
|
+
return 0;
|
|
571458
|
+
let dot = 0;
|
|
571459
|
+
let na = 0;
|
|
571460
|
+
let nb = 0;
|
|
571461
|
+
for (let i2 = 0; i2 < a2.length; i2++) {
|
|
571462
|
+
const av = a2[i2] ?? 0;
|
|
571463
|
+
const bv = b[i2] ?? 0;
|
|
571464
|
+
dot += av * bv;
|
|
571465
|
+
na += av * av;
|
|
571466
|
+
nb += bv * bv;
|
|
571467
|
+
}
|
|
571468
|
+
const denom = Math.sqrt(na) * Math.sqrt(nb);
|
|
571469
|
+
return denom > 0 ? dot / denom : 0;
|
|
571470
|
+
}
|
|
571471
|
+
_embeddingBaseUrl() {
|
|
571472
|
+
const raw = this.backend["baseUrl"] || "http://localhost:11434";
|
|
571473
|
+
return raw.replace(/\/v1\/?$/, "");
|
|
571474
|
+
}
|
|
571475
|
+
_failurePatternText(pattern) {
|
|
571476
|
+
return [
|
|
571477
|
+
`signature: ${pattern.signature}`,
|
|
571478
|
+
pattern.tool ? `tool: ${pattern.tool}` : "",
|
|
571479
|
+
pattern.errorType ? `errorType: ${pattern.errorType}` : "",
|
|
571480
|
+
pattern.guidance ? `guidance: ${pattern.guidance}` : ""
|
|
571481
|
+
].filter(Boolean).join("\n");
|
|
571482
|
+
}
|
|
571483
|
+
async _inferRelevantFailurePatternSignatures(taskGoal, candidates, maxPatterns) {
|
|
571484
|
+
if (candidates.length === 0)
|
|
571485
|
+
return /* @__PURE__ */ new Set();
|
|
571486
|
+
try {
|
|
571487
|
+
this._emitModelResolutionTelemetry("failure_pattern_relevance");
|
|
571488
|
+
const backend = this._auxInferenceBackend();
|
|
571489
|
+
const resp = await backend.chatCompletion({
|
|
571490
|
+
messages: [
|
|
571491
|
+
{
|
|
571492
|
+
role: "system",
|
|
571493
|
+
content: "You select prior failure patterns that are semantically relevant to the active task. Return only JSON."
|
|
571494
|
+
},
|
|
571495
|
+
{
|
|
571496
|
+
role: "user",
|
|
571497
|
+
content: JSON.stringify({
|
|
571498
|
+
taskGoal,
|
|
571499
|
+
max: maxPatterns,
|
|
571500
|
+
candidates: candidates.slice(0, 30).map((pattern) => ({
|
|
571501
|
+
signature: pattern.signature,
|
|
571502
|
+
tool: pattern.tool,
|
|
571503
|
+
errorType: pattern.errorType,
|
|
571504
|
+
guidance: pattern.guidance
|
|
571505
|
+
})),
|
|
571506
|
+
outputSchema: { relevant: ["signature"] }
|
|
571507
|
+
})
|
|
571508
|
+
}
|
|
571509
|
+
],
|
|
571510
|
+
tools: [],
|
|
571511
|
+
temperature: 0,
|
|
571512
|
+
maxTokens: 500,
|
|
571513
|
+
timeoutMs: 2e4
|
|
571514
|
+
});
|
|
571515
|
+
const raw = resp.choices?.[0]?.message?.content ?? "";
|
|
571516
|
+
const start2 = raw.indexOf("{");
|
|
571517
|
+
const end = raw.lastIndexOf("}");
|
|
571518
|
+
if (start2 < 0 || end <= start2)
|
|
571519
|
+
return /* @__PURE__ */ new Set();
|
|
571520
|
+
const parsed = JSON.parse(raw.slice(start2, end + 1));
|
|
571521
|
+
return new Set((parsed.relevant ?? []).map((item) => String(item)).filter((signature) => candidates.some((pattern) => pattern.signature === signature)).slice(0, maxPatterns));
|
|
571522
|
+
} catch {
|
|
571523
|
+
return /* @__PURE__ */ new Set();
|
|
571524
|
+
}
|
|
571525
|
+
}
|
|
571526
|
+
async _selectTaskRelevantErrorPatterns(taskGoal, maxPatterns) {
|
|
571527
|
+
const candidates = normalizeFailurePatterns(this._errorPatterns).slice(0, 40);
|
|
571528
|
+
if (!taskGoal.trim() || candidates.length === 0)
|
|
571529
|
+
return /* @__PURE__ */ new Map();
|
|
571530
|
+
const selected = /* @__PURE__ */ new Map();
|
|
571531
|
+
let selectedBy = "none";
|
|
571532
|
+
try {
|
|
571533
|
+
const embeddings = await generateEmbeddingBatch([taskGoal, ...candidates.map((pattern) => this._failurePatternText(pattern))], { baseUrl: this._embeddingBaseUrl(), timeoutMs: 12e3 });
|
|
571534
|
+
const query = embeddings[0]?.vector;
|
|
571535
|
+
const minScore = Number.parseFloat(process.env["OMNIUS_FAILURE_PATTERN_SIM_MIN"] ?? "0.58");
|
|
571536
|
+
if (query) {
|
|
571537
|
+
const scored = candidates.map((pattern, index) => ({
|
|
571538
|
+
pattern,
|
|
571539
|
+
score: embeddings[index + 1]?.vector ? this._cosineSimilarity(query, embeddings[index + 1].vector) : 0
|
|
571540
|
+
})).filter((item) => item.score >= minScore).sort((a2, b) => b.score - a2.score).slice(0, maxPatterns);
|
|
571541
|
+
for (const item of scored) {
|
|
571542
|
+
const raw = this._errorPatterns.get(item.pattern.signature);
|
|
571543
|
+
if (raw)
|
|
571544
|
+
selected.set(item.pattern.signature, raw);
|
|
571545
|
+
}
|
|
571546
|
+
if (selected.size > 0)
|
|
571547
|
+
selectedBy = "vector";
|
|
571548
|
+
}
|
|
571549
|
+
} catch {
|
|
571550
|
+
}
|
|
571551
|
+
if (selected.size === 0) {
|
|
571552
|
+
const relevant = await this._inferRelevantFailurePatternSignatures(taskGoal, candidates, maxPatterns);
|
|
571553
|
+
for (const signature of relevant) {
|
|
571554
|
+
const raw = this._errorPatterns.get(signature);
|
|
571555
|
+
if (raw)
|
|
571556
|
+
selected.set(signature, raw);
|
|
571557
|
+
}
|
|
571558
|
+
if (selected.size > 0)
|
|
571559
|
+
selectedBy = "inference";
|
|
571560
|
+
}
|
|
571561
|
+
this.emit({
|
|
571562
|
+
type: "status",
|
|
571563
|
+
content: `Failure handoff semantic selection: ${selected.size}/${candidates.length} persisted pattern(s) selected by ${selectedBy}`,
|
|
571564
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
571565
|
+
});
|
|
571566
|
+
return selected;
|
|
571567
|
+
}
|
|
570964
571568
|
_persistCompletionContract(contract) {
|
|
570965
571569
|
if (!this.writesUserTaskArtifacts())
|
|
570966
571570
|
return;
|
|
@@ -571961,12 +572565,14 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
571961
572565
|
if (!this._completionLedger || input.toolName === "task_complete")
|
|
571962
572566
|
return;
|
|
571963
572567
|
const realFileMutation = input.realFileMutation ?? this._isRealProjectMutation(input.toolName, input.result);
|
|
571964
|
-
const
|
|
572568
|
+
const attemptedTargetPaths = this._extractToolTargetPaths(input.toolName, input.args, input.result);
|
|
572569
|
+
const realMutationPaths = input.realMutationPaths ?? (realFileMutation ? attemptedTargetPaths : []);
|
|
571965
572570
|
this._completionLedger = recordToolEvidence(this._completionLedger, {
|
|
571966
572571
|
name: input.toolName,
|
|
571967
572572
|
success: input.result.success,
|
|
571968
572573
|
outputPreview: (input.outputPreview ?? this._toolEvidencePreview(input.result)).toString().slice(0, 500),
|
|
571969
|
-
argsKey: input.argsKey.slice(0, 300)
|
|
572574
|
+
argsKey: input.argsKey.slice(0, 300),
|
|
572575
|
+
targetPaths: attemptedTargetPaths
|
|
571970
572576
|
});
|
|
571971
572577
|
if (realFileMutation && realMutationPaths.length > 0) {
|
|
571972
572578
|
for (const filePath of realMutationPaths) {
|
|
@@ -571975,7 +572581,8 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
571975
572581
|
toolName: input.toolName,
|
|
571976
572582
|
success: true,
|
|
571977
572583
|
summary: `file change: ${filePath}`,
|
|
571978
|
-
rawRef: `file://${filePath}
|
|
572584
|
+
rawRef: `file://${filePath}`,
|
|
572585
|
+
targetPaths: [filePath]
|
|
571979
572586
|
});
|
|
571980
572587
|
}
|
|
571981
572588
|
}
|
|
@@ -572323,7 +572930,7 @@ ${context2 ?? ""}`;
|
|
|
572323
572930
|
`Task affect: uncertainty=${affect.uncertainty.toFixed(2)} frustration=${affect.frustration.toFixed(2)} confidence=${affect.confidence.toFixed(2)} momentum=${affect.momentum.toFixed(2)}`
|
|
572324
572931
|
].join("\n");
|
|
572325
572932
|
}
|
|
572326
|
-
_buildPreflightTaskMemoryRecall(taskGoal) {
|
|
572933
|
+
async _buildPreflightTaskMemoryRecall(taskGoal) {
|
|
572327
572934
|
if (process.env["OMNIUS_DISABLE_PREFLIGHT_MEMORY_RECALL"] === "1")
|
|
572328
572935
|
return "";
|
|
572329
572936
|
if (this.options.stateDir || this.options.subAgent)
|
|
@@ -572332,17 +572939,31 @@ ${context2 ?? ""}`;
|
|
|
572332
572939
|
return "";
|
|
572333
572940
|
try {
|
|
572334
572941
|
const query = taskGoal.slice(0, 1e3);
|
|
572335
|
-
const
|
|
572336
|
-
|
|
572942
|
+
const embedding = await generateEmbedding(query, {
|
|
572943
|
+
baseUrl: this._embeddingBaseUrl(),
|
|
572944
|
+
timeoutMs: 1e4
|
|
572945
|
+
});
|
|
572946
|
+
if (!embedding?.vector)
|
|
572947
|
+
return "";
|
|
572948
|
+
const results = this._episodeStore.search({ query, limit: 12 }, {
|
|
572949
|
+
queryEmbedding: embedding.vector,
|
|
572950
|
+
lexicalWeight: 0,
|
|
572951
|
+
embeddingWeight: 1
|
|
572952
|
+
});
|
|
572953
|
+
const minScore = Number.parseFloat(process.env["OMNIUS_PREFLIGHT_MEMORY_SIM_MIN"] ?? "0.58");
|
|
572954
|
+
const useful = results.map((entry) => ({
|
|
572955
|
+
entry,
|
|
572956
|
+
score: entry.embedding ? this._cosineSimilarity(embedding.vector, entry.embedding) : 0
|
|
572957
|
+
})).filter(({ entry, score }) => typeof entry.content === "string" && entry.content.trim().length >= 30 && score >= minScore).sort((a2, b) => b.score - a2.score).slice(0, 3);
|
|
572337
572958
|
if (useful.length === 0)
|
|
572338
572959
|
return "";
|
|
572339
|
-
const lines = useful.map((entry, index) => {
|
|
572340
|
-
const tool = typeof entry.
|
|
572341
|
-
return `${index + 1}. ${entry.content.replace(/\s+/g, " ").slice(0, 260)}${tool}`;
|
|
572960
|
+
const lines = useful.map(({ entry, score }, index) => {
|
|
572961
|
+
const tool = typeof entry.toolName === "string" && entry.toolName ? ` tool=${entry.toolName}` : "";
|
|
572962
|
+
return `${index + 1}. sim=${score.toFixed(3)} ${entry.content.replace(/\s+/g, " ").slice(0, 260)}${tool}`;
|
|
572342
572963
|
});
|
|
572343
572964
|
return [
|
|
572344
572965
|
`[PREFLIGHT MEMORY RECALL]`,
|
|
572345
|
-
`Retrieved
|
|
572966
|
+
`Retrieved vector-similar prior episodes before the first action. Use these as hypotheses, not truth; verify against current files/UI.`,
|
|
572346
572967
|
...lines,
|
|
572347
572968
|
`If the current task resembles one of these, prefer the remembered working verification path and avoid the remembered failure pattern.`
|
|
572348
572969
|
].join("\n");
|
|
@@ -572455,9 +573076,26 @@ ${shellLines.join("\n")}` : "Commands run: none"
|
|
|
572455
573076
|
const failCount = toolCallLog.filter((e2) => e2.success === false).length;
|
|
572456
573077
|
evidenceParts.push(`Failed tool calls this run: ${failCount}`);
|
|
572457
573078
|
const evidenceDigest = evidenceParts.join("\n");
|
|
573079
|
+
const degraded = detectExplicitDegradedCompletion({
|
|
573080
|
+
originalGoal,
|
|
573081
|
+
actionsDigest,
|
|
573082
|
+
evidenceDigest,
|
|
573083
|
+
proposedSummary
|
|
573084
|
+
});
|
|
573085
|
+
if (degraded) {
|
|
573086
|
+
this._resolutionGateRejections = 0;
|
|
573087
|
+
this.emit({
|
|
573088
|
+
type: "status",
|
|
573089
|
+
content: `Resolution gate accepted explicit degraded completion: ${degraded.reason}`,
|
|
573090
|
+
turn,
|
|
573091
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
573092
|
+
});
|
|
573093
|
+
return { proceed: true };
|
|
573094
|
+
}
|
|
572458
573095
|
let verdict = null;
|
|
572459
573096
|
try {
|
|
572460
573097
|
const backend = this._auxInferenceBackend();
|
|
573098
|
+
this._emitModelResolutionTelemetry("completion_resolution", turn);
|
|
572461
573099
|
for (let attempt = 0; attempt < 2 && !verdict; attempt++) {
|
|
572462
573100
|
const resp = await backend.chatCompletion({
|
|
572463
573101
|
messages: [
|
|
@@ -575393,7 +576031,8 @@ Rewrite it now for ${ctx3.model}.`;
|
|
|
575393
576031
|
run_in_background: ["background", "background_run", "async"],
|
|
575394
576032
|
max_turns: ["maxTurns", "turns"],
|
|
575395
576033
|
timeout_ms: ["timeoutMs", "timeout"],
|
|
575396
|
-
path: ["file", "filepath", "file_path", "filename"],
|
|
576034
|
+
path: ["file", "image", "media", "filepath", "file_path", "filename"],
|
|
576035
|
+
image: ["path", "file", "media", "filepath", "file_path", "filename"],
|
|
575397
576036
|
command: ["cmd", "shell_command"],
|
|
575398
576037
|
query: ["prompt", "task", "message", "input", "text"]
|
|
575399
576038
|
};
|
|
@@ -575889,6 +576528,7 @@ Respond with your assessment, then take action.`;
|
|
|
575889
576528
|
this.pendingUserMessages.length = 0;
|
|
575890
576529
|
const persistentTaskGoal = cleanForStorage(actualUserGoal || "") || cleanedTask;
|
|
575891
576530
|
const userGoal = persistentTaskGoal.slice(0, 500);
|
|
576531
|
+
this._taskRelevantErrorPatterns = process.env["OMNIUS_DISABLE_FAILURE_HANDOFF"] === "1" ? /* @__PURE__ */ new Map() : await this._selectTaskRelevantErrorPatterns(persistentTaskGoal, 10);
|
|
575892
576532
|
this._taskState = {
|
|
575893
576533
|
goal: userGoal,
|
|
575894
576534
|
originalGoal: userGoal,
|
|
@@ -575933,6 +576573,7 @@ Respond with your assessment, then take action.`;
|
|
|
575933
576573
|
contextWindowSize: this.options.contextWindowSize ?? 0,
|
|
575934
576574
|
verbose: false
|
|
575935
576575
|
});
|
|
576576
|
+
this._emitModelResolutionTelemetry("main");
|
|
575936
576577
|
this._hookManager.runSessionHook("session_start", this._sessionId);
|
|
575937
576578
|
if (this.writesUserTaskArtifacts()) {
|
|
575938
576579
|
this._initializeCompletionContract(task, context2, actualUserGoal);
|
|
@@ -576163,7 +576804,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
576163
576804
|
...missionCompletionContract ? [{ role: "system", content: missionCompletionContract }] : [],
|
|
576164
576805
|
{ role: "user", content: userContent }
|
|
576165
576806
|
];
|
|
576166
|
-
const preflightMemoryRecall = this._buildPreflightTaskMemoryRecall(persistentTaskGoal);
|
|
576807
|
+
const preflightMemoryRecall = await this._buildPreflightTaskMemoryRecall(persistentTaskGoal);
|
|
576167
576808
|
if (preflightMemoryRecall) {
|
|
576168
576809
|
messages2.splice(messages2.length - 1, 0, {
|
|
576169
576810
|
role: "system",
|
|
@@ -576283,7 +576924,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
576283
576924
|
try {
|
|
576284
576925
|
const failureHandoff = buildFailureModeHandoff({
|
|
576285
576926
|
taskGoal: persistentTaskGoal,
|
|
576286
|
-
errorPatterns: this.
|
|
576927
|
+
errorPatterns: this._taskRelevantErrorPatterns,
|
|
576287
576928
|
toolCallLog,
|
|
576288
576929
|
taskState: this._taskState,
|
|
576289
576930
|
maxPatterns: 10,
|
|
@@ -579760,13 +580401,15 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
579760
580401
|
default:
|
|
579761
580402
|
guidance = `This tool failed previously with a similar error. Review the error message carefully and adjust your approach before retrying.`;
|
|
579762
580403
|
}
|
|
579763
|
-
|
|
580404
|
+
const learnedPattern = {
|
|
579764
580405
|
count,
|
|
579765
580406
|
guidance,
|
|
579766
580407
|
lastSeen: Date.now(),
|
|
579767
580408
|
tool: tc.name,
|
|
579768
580409
|
errorType
|
|
579769
|
-
}
|
|
580410
|
+
};
|
|
580411
|
+
this._errorPatterns.set(sig, learnedPattern);
|
|
580412
|
+
this._taskRelevantErrorPatterns.set(sig, learnedPattern);
|
|
579770
580413
|
if (this._failureStore) {
|
|
579771
580414
|
try {
|
|
579772
580415
|
this._failureStore.insert({
|
|
@@ -579816,13 +580459,48 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
579816
580459
|
}
|
|
579817
580460
|
if (tc.name === "todo_write") {
|
|
579818
580461
|
try {
|
|
579819
|
-
|
|
580462
|
+
let _todosNow = this.readSessionTodos() || [];
|
|
579820
580463
|
for (const _tp of _todosNow) {
|
|
579821
580464
|
const _tpId = _tp.id;
|
|
579822
580465
|
if (_tp.status === "in_progress" && _tpId && !this._todoInProgressTurn.has(_tpId)) {
|
|
579823
580466
|
this._todoInProgressTurn.set(_tpId, turn);
|
|
579824
580467
|
}
|
|
579825
580468
|
}
|
|
580469
|
+
const truth = reconcileCompletedTodosWithEvidence({
|
|
580470
|
+
todos: _todosNow,
|
|
580471
|
+
toolCallLog,
|
|
580472
|
+
todoStartTurnById: this._todoInProgressTurn
|
|
580473
|
+
});
|
|
580474
|
+
if (truth.changed) {
|
|
580475
|
+
const sid = this._sessionId || process.env["OMNIUS_SESSION_ID"] || "default";
|
|
580476
|
+
writeTodos(sid, truth.todos.map((t2) => ({
|
|
580477
|
+
id: t2.id,
|
|
580478
|
+
content: t2.content,
|
|
580479
|
+
status: t2.status,
|
|
580480
|
+
parentId: t2.parentId,
|
|
580481
|
+
blocker: t2.blocker,
|
|
580482
|
+
verifyCommand: t2.verifyCommand,
|
|
580483
|
+
declaredArtifacts: t2.declaredArtifacts
|
|
580484
|
+
})));
|
|
580485
|
+
_todosNow = this.readSessionTodos() || truth.todos;
|
|
580486
|
+
const downgradeLines = truth.downgrades.slice(0, 6).map((d2) => `- ${d2.content}: ${d2.from} -> ${d2.to}; ${d2.evidence}`).join("\n");
|
|
580487
|
+
messages2.push({
|
|
580488
|
+
role: "system",
|
|
580489
|
+
content: [
|
|
580490
|
+
`[TODO TRUTH RECONCILIATION]`,
|
|
580491
|
+
`One or more completed todo claims contradicted the evidence or nested child status and were rewritten in the active todo list.`,
|
|
580492
|
+
downgradeLines,
|
|
580493
|
+
``,
|
|
580494
|
+
`Reconfigure the affected subtask tree now: read/verify the current state, choose a different tool or target if the prior route failed, or leave the child todo blocked with the root cause. Do not mark a parent completed until every child is completed with evidence.`
|
|
580495
|
+
].join("\n")
|
|
580496
|
+
});
|
|
580497
|
+
this.emit({
|
|
580498
|
+
type: "status",
|
|
580499
|
+
content: `Todo truth reconciled ${truth.downgrades.length} completed claim(s) from evidence/nested child state`,
|
|
580500
|
+
turn,
|
|
580501
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
580502
|
+
});
|
|
580503
|
+
}
|
|
579826
580504
|
if (!this._newFieldNudgeFired) {
|
|
579827
580505
|
this._todoWritesObservedForNudge++;
|
|
579828
580506
|
const _anyFieldUsed = _todosNow.some((t2) => typeof t2.verifyCommand === "string" || Array.isArray(t2.declaredArtifacts));
|
|
@@ -580562,7 +581240,7 @@ Then use file_read on individual FILES inside it.`);
|
|
|
580562
581240
|
if (process.env["OMNIUS_DISABLE_FAILURE_HANDOFF"] !== "1" && !result.success && turn - lastFailureHandoffTurn >= 4) {
|
|
580563
581241
|
const runtimeHandoff = buildFailureModeHandoff({
|
|
580564
581242
|
taskGoal: persistentTaskGoal,
|
|
580565
|
-
errorPatterns: this.
|
|
581243
|
+
errorPatterns: this._taskRelevantErrorPatterns,
|
|
580566
581244
|
toolCallLog,
|
|
580567
581245
|
taskState: this._taskState,
|
|
580568
581246
|
maxPatterns: 5,
|
|
@@ -582419,7 +583097,7 @@ ${caveat}` : caveat;
|
|
|
582419
583097
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
582420
583098
|
});
|
|
582421
583099
|
try {
|
|
582422
|
-
const { mkdirSync: mkdirSync106, readdirSync: readdirSync59, statSync: statSync59, unlinkSync: unlinkSync36, writeFileSync:
|
|
583100
|
+
const { mkdirSync: mkdirSync106, readdirSync: readdirSync59, statSync: statSync59, unlinkSync: unlinkSync36, writeFileSync: writeFileSync90 } = __require("node:fs");
|
|
582423
583101
|
const { join: join179 } = __require("node:path");
|
|
582424
583102
|
const contextDir = join179(this._workingDirectory || process.cwd(), ".omnius", "context");
|
|
582425
583103
|
mkdirSync106(contextDir, { recursive: true });
|
|
@@ -582466,14 +583144,14 @@ ${caveat}` : caveat;
|
|
|
582466
583144
|
mkdirSync106(kgSummaryDir, { recursive: true });
|
|
582467
583145
|
const summaryFilename = `kg-summary-${this._sessionId}.md`;
|
|
582468
583146
|
const outPath = join179(kgSummaryDir, summaryFilename);
|
|
582469
|
-
|
|
582470
|
-
|
|
582471
|
-
|
|
583147
|
+
writeFileSync90(outPath, lines.join("\n"), "utf-8");
|
|
583148
|
+
writeFileSync90(join179(kgSummaryDir, "latest.md"), lines.join("\n"), "utf-8");
|
|
583149
|
+
writeFileSync90(join179(contextDir, `kg-summary-latest.md`), [
|
|
582472
583150
|
"Latest KG summary moved to `.omnius/context/kg-summary/latest.md`.",
|
|
582473
583151
|
"",
|
|
582474
583152
|
lines.join("\n")
|
|
582475
583153
|
].join("\n"), "utf-8");
|
|
582476
|
-
|
|
583154
|
+
writeFileSync90(join179(kgSummaryDir, "index.json"), JSON.stringify({
|
|
582477
583155
|
schema: "omnius.kg-summary-index.v1",
|
|
582478
583156
|
latest: "latest.md",
|
|
582479
583157
|
latestSessionFile: summaryFilename,
|
|
@@ -583310,7 +583988,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
583310
583988
|
if (!this._workingDirectory)
|
|
583311
583989
|
return;
|
|
583312
583990
|
try {
|
|
583313
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
583991
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = __require("node:fs");
|
|
583314
583992
|
const { join: join179 } = __require("node:path");
|
|
583315
583993
|
const sessionDir2 = this.options.stateDir ? join179(this.omniusStateDir(), "session", this._sessionId) : join179(this._workingDirectory, ".omnius", "session", this._sessionId);
|
|
583316
583994
|
mkdirSync106(sessionDir2, { recursive: true });
|
|
@@ -583325,7 +584003,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
583325
584003
|
memexEntryCount: this._memexArchive.size,
|
|
583326
584004
|
fileRegistrySize: this._fileRegistry.size
|
|
583327
584005
|
};
|
|
583328
|
-
|
|
584006
|
+
writeFileSync90(join179(sessionDir2, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
583329
584007
|
} catch {
|
|
583330
584008
|
}
|
|
583331
584009
|
}
|
|
@@ -583462,7 +584140,7 @@ ${tail}`;
|
|
|
583462
584140
|
const analysis = await this.analyzeImageDataForContext(image.mime, image.base64, image.textWithoutImage.slice(0, 2e3));
|
|
583463
584141
|
const imageNote = analysis.contextBlock ? `${analysis.contextBlock}
|
|
583464
584142
|
|
|
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"}.
|
|
584143
|
+
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
584144
|
return {
|
|
583467
584145
|
...result,
|
|
583468
584146
|
llmContent: `${image.textWithoutImage.trim()}
|
|
@@ -583498,7 +584176,7 @@ ${imageNote}`.trim()
|
|
|
583498
584176
|
const imageUrl = `data:${mime};base64,${base642}`;
|
|
583499
584177
|
const tmpImgPath = this.writeTempImageForOcr(mime, base642);
|
|
583500
584178
|
const [visionOutcome, ocrOutcome] = await Promise.allSettled([
|
|
583501
|
-
this.describeImageViaVisionSubagent(imageUrl, textContent),
|
|
584179
|
+
tmpImgPath ? this.describeImageViaPrimaryVision(tmpImgPath, imageUrl, textContent) : this.describeImageViaVisionSubagent(imageUrl, textContent),
|
|
583502
584180
|
tmpImgPath ? this.extractImageOcrText(tmpImgPath) : Promise.resolve("")
|
|
583503
584181
|
]);
|
|
583504
584182
|
const visionDesc = visionOutcome.status === "fulfilled" ? visionOutcome.value.trim() : "";
|
|
@@ -583513,6 +584191,26 @@ ${imageNote}`.trim()
|
|
|
583513
584191
|
const errorReason = visionOutcome.status === "rejected" ? String(visionOutcome.reason?.message ?? visionOutcome.reason) : void 0;
|
|
583514
584192
|
return { contextBlock: "", errorReason };
|
|
583515
584193
|
}
|
|
584194
|
+
async describeImageViaPrimaryVision(imagePath, imageUrl, textContent) {
|
|
584195
|
+
try {
|
|
584196
|
+
const vision = new VisionTool(this._workingDirectory || process.cwd());
|
|
584197
|
+
const prompt = textContent ? `User context: ${textContent}
|
|
584198
|
+
|
|
584199
|
+
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.";
|
|
584200
|
+
const result = await vision.execute({
|
|
584201
|
+
image: imagePath,
|
|
584202
|
+
action: "query",
|
|
584203
|
+
prompt,
|
|
584204
|
+
length: "long"
|
|
584205
|
+
});
|
|
584206
|
+
const output = String(result.llmContent || result.output || "").trim();
|
|
584207
|
+
if (result.success && output.length > 20)
|
|
584208
|
+
return output;
|
|
584209
|
+
throw new Error(result.error || "vision tool returned no description");
|
|
584210
|
+
} catch {
|
|
584211
|
+
return await this.describeImageViaVisionSubagent(imageUrl, textContent);
|
|
584212
|
+
}
|
|
584213
|
+
}
|
|
583516
584214
|
async describeImageViaVisionSubagent(imageUrl, textContent) {
|
|
583517
584215
|
const visionMessages = [
|
|
583518
584216
|
{
|
|
@@ -584066,7 +584764,7 @@ ${content.slice(0, 8e3)}
|
|
|
584066
584764
|
try {
|
|
584067
584765
|
const compactFailureHandoff = buildFailureModeHandoff({
|
|
584068
584766
|
taskGoal: this._taskState.goal,
|
|
584069
|
-
errorPatterns: this.
|
|
584767
|
+
errorPatterns: this._taskRelevantErrorPatterns,
|
|
584070
584768
|
taskState: this._taskState,
|
|
584071
584769
|
maxPatterns: 6,
|
|
584072
584770
|
maxRecentCalls: 0
|
|
@@ -585985,12 +586683,12 @@ ${result}`
|
|
|
585985
586683
|
let resizedBase64 = null;
|
|
585986
586684
|
try {
|
|
585987
586685
|
const { execSync: execSync63 } = await import("node:child_process");
|
|
585988
|
-
const { writeFileSync:
|
|
586686
|
+
const { writeFileSync: writeFileSync90, readFileSync: readFileSync133, unlinkSync: unlinkSync36 } = await import("node:fs");
|
|
585989
586687
|
const { join: join179 } = await import("node:path");
|
|
585990
586688
|
const { tmpdir: tmpdir24 } = await import("node:os");
|
|
585991
586689
|
const tmpIn = join179(tmpdir24(), `omnius_img_in_${Date.now()}.png`);
|
|
585992
586690
|
const tmpOut = join179(tmpdir24(), `omnius_img_out_${Date.now()}.jpg`);
|
|
585993
|
-
|
|
586691
|
+
writeFileSync90(tmpIn, buffer2);
|
|
585994
586692
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
585995
586693
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
585996
586694
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
@@ -594971,10 +595669,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
594971
595669
|
wordTimestamps: false
|
|
594972
595670
|
});
|
|
594973
595671
|
if (outputDir2) {
|
|
594974
|
-
const { basename:
|
|
595672
|
+
const { basename: basename40 } = await import("node:path");
|
|
594975
595673
|
const transcriptDir = join120(outputDir2, ".omnius", "transcripts");
|
|
594976
595674
|
mkdirSync63(transcriptDir, { recursive: true });
|
|
594977
|
-
const outFile = join120(transcriptDir, `${
|
|
595675
|
+
const outFile = join120(transcriptDir, `${basename40(filePath)}.txt`);
|
|
594978
595676
|
writeFileSync53(outFile, result.text, "utf-8");
|
|
594979
595677
|
}
|
|
594980
595678
|
return {
|
|
@@ -594990,10 +595688,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
594990
595688
|
const fb = await transcribeFileViaWhisper(filePath, this.config.model);
|
|
594991
595689
|
if (fb) {
|
|
594992
595690
|
if (outputDir2) {
|
|
594993
|
-
const { basename:
|
|
595691
|
+
const { basename: basename40 } = await import("node:path");
|
|
594994
595692
|
const transcriptDir = join120(outputDir2, ".omnius", "transcripts");
|
|
594995
595693
|
mkdirSync63(transcriptDir, { recursive: true });
|
|
594996
|
-
const outFile = join120(transcriptDir, `${
|
|
595694
|
+
const outFile = join120(transcriptDir, `${basename40(filePath)}.txt`);
|
|
594997
595695
|
writeFileSync53(outFile, fb.text, "utf-8");
|
|
594998
595696
|
}
|
|
594999
595697
|
return fb;
|
|
@@ -612842,6 +613540,33 @@ function buildTodoProgressBar(todos, maxWidth) {
|
|
|
612842
613540
|
if (truncated && maxWidth > 0) out += `${DIM_LABEL}…${RESET3}`;
|
|
612843
613541
|
return out;
|
|
612844
613542
|
}
|
|
613543
|
+
function orderTodosForDisplay(todos) {
|
|
613544
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
613545
|
+
const byId = new Set(todos.map((t2) => t2.id));
|
|
613546
|
+
const roots = [];
|
|
613547
|
+
for (const todo of todos) {
|
|
613548
|
+
if (todo.parentId && byId.has(todo.parentId)) {
|
|
613549
|
+
const arr = byParent.get(todo.parentId) ?? [];
|
|
613550
|
+
arr.push(todo);
|
|
613551
|
+
byParent.set(todo.parentId, arr);
|
|
613552
|
+
} else {
|
|
613553
|
+
roots.push(todo);
|
|
613554
|
+
}
|
|
613555
|
+
}
|
|
613556
|
+
const out = [];
|
|
613557
|
+
const seen = /* @__PURE__ */ new Set();
|
|
613558
|
+
const visit = (todo, depth) => {
|
|
613559
|
+
if (seen.has(todo.id)) return;
|
|
613560
|
+
seen.add(todo.id);
|
|
613561
|
+
out.push({ ...todo, depth: Math.min(depth, 4) });
|
|
613562
|
+
for (const child of byParent.get(todo.id) ?? []) {
|
|
613563
|
+
visit(child, depth + 1);
|
|
613564
|
+
}
|
|
613565
|
+
};
|
|
613566
|
+
for (const root of roots) visit(root, 0);
|
|
613567
|
+
for (const todo of todos) visit(todo, 0);
|
|
613568
|
+
return out;
|
|
613569
|
+
}
|
|
612845
613570
|
function render() {
|
|
612846
613571
|
if (!_enabled) return;
|
|
612847
613572
|
if (!panelEffectivelyVisible()) {
|
|
@@ -612867,16 +613592,18 @@ function render() {
|
|
|
612867
613592
|
const progressBar = buildTodoProgressBar(_lastTodos, maxBarWidth);
|
|
612868
613593
|
const headerText = `${headerPrefix}${progressBar}`;
|
|
612869
613594
|
lines.push(headerText);
|
|
612870
|
-
const
|
|
613595
|
+
const displayTodos = orderTodosForDisplay(_lastTodos);
|
|
613596
|
+
const visible = displayTodos.slice(0, MAX_VISIBLE_ROWS - 1);
|
|
612871
613597
|
for (const t2 of visible) {
|
|
612872
613598
|
const { mark, color } = statusToAnsi(t2.status);
|
|
612873
613599
|
const contentWidth = Math.max(4, cols - 8);
|
|
612874
|
-
const
|
|
613600
|
+
const indent2 = t2.depth > 0 ? `${" ".repeat(t2.depth - 1)}- ` : "";
|
|
613601
|
+
const contentText = indent2 + t2.content + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
|
|
612875
613602
|
const truncated = truncate2(contentText, contentWidth);
|
|
612876
613603
|
lines.push(`${color}${mark}${RESET3} ${color}${truncated}${RESET3}`);
|
|
612877
613604
|
}
|
|
612878
|
-
if (
|
|
612879
|
-
const more =
|
|
613605
|
+
if (displayTodos.length > visible.length) {
|
|
613606
|
+
const more = displayTodos.length - visible.length;
|
|
612880
613607
|
lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${RESET3}`;
|
|
612881
613608
|
}
|
|
612882
613609
|
let out = HIDE + SAVE;
|
|
@@ -635942,13 +636669,13 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
635942
636669
|
try {
|
|
635943
636670
|
const { randomBytes: randomBytes30 } = await import("node:crypto");
|
|
635944
636671
|
const { homedir: homedir62 } = await import("node:os");
|
|
635945
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
636672
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
635946
636673
|
const { join: join179 } = await import("node:path");
|
|
635947
636674
|
const newKey = randomBytes30(16).toString("hex");
|
|
635948
636675
|
process.env["OMNIUS_API_KEY"] = newKey;
|
|
635949
636676
|
const dir = join179(homedir62(), ".omnius");
|
|
635950
636677
|
mkdirSync106(dir, { recursive: true });
|
|
635951
|
-
|
|
636678
|
+
writeFileSync90(join179(dir, "api.key"), newKey + "\n", "utf8");
|
|
635952
636679
|
renderInfo(`New API key: ${c3.bold(c3.yellow(newKey))}`);
|
|
635953
636680
|
renderInfo(
|
|
635954
636681
|
"Restart the daemon to apply if needed. Use /access any to restart quickly."
|
|
@@ -636219,11 +636946,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636219
636946
|
);
|
|
636220
636947
|
try {
|
|
636221
636948
|
const { homedir: homedir63 } = await import("node:os");
|
|
636222
|
-
const { mkdirSync: mkdirSync107, writeFileSync:
|
|
636949
|
+
const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync91 } = await import("node:fs");
|
|
636223
636950
|
const { join: join180 } = await import("node:path");
|
|
636224
636951
|
const dir = join180(homedir63(), ".omnius");
|
|
636225
636952
|
mkdirSync107(dir, { recursive: true });
|
|
636226
|
-
|
|
636953
|
+
writeFileSync91(join180(dir, "api.key"), apiKey + "\n", "utf8");
|
|
636227
636954
|
} catch {
|
|
636228
636955
|
}
|
|
636229
636956
|
}
|
|
@@ -636235,11 +636962,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636235
636962
|
const port2 = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
636236
636963
|
try {
|
|
636237
636964
|
const { homedir: homedir63 } = await import("node:os");
|
|
636238
|
-
const { mkdirSync: mkdirSync107, writeFileSync:
|
|
636965
|
+
const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync91 } = await import("node:fs");
|
|
636239
636966
|
const { join: join180 } = await import("node:path");
|
|
636240
636967
|
const dir = join180(homedir63(), ".omnius");
|
|
636241
636968
|
mkdirSync107(dir, { recursive: true });
|
|
636242
|
-
|
|
636969
|
+
writeFileSync91(join180(dir, "access"), `${val2}
|
|
636243
636970
|
`, "utf8");
|
|
636244
636971
|
} catch {
|
|
636245
636972
|
}
|
|
@@ -636339,11 +637066,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636339
637066
|
);
|
|
636340
637067
|
try {
|
|
636341
637068
|
const { homedir: homedir63 } = await import("node:os");
|
|
636342
|
-
const { mkdirSync: mkdirSync107, writeFileSync:
|
|
637069
|
+
const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync91 } = await import("node:fs");
|
|
636343
637070
|
const { join: join180 } = await import("node:path");
|
|
636344
637071
|
const dir = join180(homedir63(), ".omnius");
|
|
636345
637072
|
mkdirSync107(dir, { recursive: true });
|
|
636346
|
-
|
|
637073
|
+
writeFileSync91(join180(dir, "api.key"), apiKey + "\n", "utf8");
|
|
636347
637074
|
} catch {
|
|
636348
637075
|
}
|
|
636349
637076
|
}
|
|
@@ -636354,12 +637081,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
636354
637081
|
}
|
|
636355
637082
|
const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
636356
637083
|
const { homedir: homedir62 } = await import("node:os");
|
|
636357
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
637084
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
636358
637085
|
const { join: join179 } = await import("node:path");
|
|
636359
637086
|
try {
|
|
636360
637087
|
const dir = join179(homedir62(), ".omnius");
|
|
636361
637088
|
mkdirSync106(dir, { recursive: true });
|
|
636362
|
-
|
|
637089
|
+
writeFileSync90(join179(dir, "access"), `${val}
|
|
636363
637090
|
`, "utf8");
|
|
636364
637091
|
} catch (e2) {
|
|
636365
637092
|
renderWarning(
|
|
@@ -645195,14 +645922,14 @@ async function handleVoiceMenu(ctx3, save3, hasLocal) {
|
|
|
645195
645922
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
645196
645923
|
continue;
|
|
645197
645924
|
}
|
|
645198
|
-
const { basename:
|
|
645925
|
+
const { basename: basename40, join: pathJoin } = await import("node:path");
|
|
645199
645926
|
const {
|
|
645200
645927
|
copyFileSync: copyFileSync8,
|
|
645201
645928
|
mkdirSync: mkdirSync106,
|
|
645202
645929
|
existsSync: exists2
|
|
645203
645930
|
} = await import("node:fs");
|
|
645204
645931
|
const { homedir: homedir62 } = await import("node:os");
|
|
645205
|
-
const modelName =
|
|
645932
|
+
const modelName = basename40(onnxDrop.path, ".onnx").replace(
|
|
645206
645933
|
/[^a-zA-Z0-9_-]/g,
|
|
645207
645934
|
"-"
|
|
645208
645935
|
);
|
|
@@ -645722,7 +646449,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
645722
646449
|
copyFileSync: cpf,
|
|
645723
646450
|
mkdirSync: mkd
|
|
645724
646451
|
} = __require("node:fs");
|
|
645725
|
-
const { basename:
|
|
646452
|
+
const { basename: basename40, join: pjoin } = __require("node:path");
|
|
645726
646453
|
if (!fe(src2)) {
|
|
645727
646454
|
renderError(`File not found: ${src2}`);
|
|
645728
646455
|
helpers.render();
|
|
@@ -645735,7 +646462,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
645735
646462
|
"clone-refs"
|
|
645736
646463
|
);
|
|
645737
646464
|
mkd(refsDir, { recursive: true });
|
|
645738
|
-
const destName =
|
|
646465
|
+
const destName = basename40(src2);
|
|
645739
646466
|
const dest = pjoin(refsDir, destName);
|
|
645740
646467
|
cpf(src2, dest);
|
|
645741
646468
|
renderInfo(`Imported "${destName}" → ${dest}`);
|
|
@@ -646992,13 +647719,13 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
646992
647719
|
sponsors.push(...verified);
|
|
646993
647720
|
if (verified.length > 0) {
|
|
646994
647721
|
try {
|
|
646995
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
647722
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = __require("node:fs");
|
|
646996
647723
|
mkdirSync106(sponsorDir2, { recursive: true });
|
|
646997
647724
|
const cached = verified.map((s2) => ({
|
|
646998
647725
|
...s2,
|
|
646999
647726
|
lastVerified: Date.now()
|
|
647000
647727
|
}));
|
|
647001
|
-
|
|
647728
|
+
writeFileSync90(knownFile, JSON.stringify(cached, null, 2));
|
|
647002
647729
|
} catch {
|
|
647003
647730
|
}
|
|
647004
647731
|
}
|
|
@@ -647202,7 +647929,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647202
647929
|
}
|
|
647203
647930
|
if (models.length > 0) {
|
|
647204
647931
|
try {
|
|
647205
|
-
const { writeFileSync:
|
|
647932
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106 } = await import("node:fs");
|
|
647206
647933
|
const { join: join179, dirname: dirname54 } = await import("node:path");
|
|
647207
647934
|
const cachePath2 = join179(
|
|
647208
647935
|
ctx3.repoRoot || process.cwd(),
|
|
@@ -647211,7 +647938,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647211
647938
|
"peer-models-cache.json"
|
|
647212
647939
|
);
|
|
647213
647940
|
mkdirSync106(dirname54(cachePath2), { recursive: true });
|
|
647214
|
-
|
|
647941
|
+
writeFileSync90(
|
|
647215
647942
|
cachePath2,
|
|
647216
647943
|
JSON.stringify(
|
|
647217
647944
|
{
|
|
@@ -647285,7 +648012,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647285
648012
|
"Live model probe failed; using sponsor directory model advertisement."
|
|
647286
648013
|
);
|
|
647287
648014
|
try {
|
|
647288
|
-
const { writeFileSync:
|
|
648015
|
+
const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync106 } = await import("node:fs");
|
|
647289
648016
|
const { join: join179, dirname: dirname54 } = await import("node:path");
|
|
647290
648017
|
const cachePath2 = join179(
|
|
647291
648018
|
ctx3.repoRoot || process.cwd(),
|
|
@@ -647294,7 +648021,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
|
|
|
647294
648021
|
"peer-models-cache.json"
|
|
647295
648022
|
);
|
|
647296
648023
|
mkdirSync106(dirname54(cachePath2), { recursive: true });
|
|
647297
|
-
|
|
648024
|
+
writeFileSync90(
|
|
647298
648025
|
cachePath2,
|
|
647299
648026
|
JSON.stringify(
|
|
647300
648027
|
{
|
|
@@ -649992,13 +650719,13 @@ var init_commands = __esm({
|
|
|
649992
650719
|
try {
|
|
649993
650720
|
const { randomBytes: randomBytes30 } = await import("node:crypto");
|
|
649994
650721
|
const { homedir: homedir62 } = await import("node:os");
|
|
649995
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
650722
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
649996
650723
|
const { join: join179 } = await import("node:path");
|
|
649997
650724
|
const apiKey = randomBytes30(16).toString("hex");
|
|
649998
650725
|
process.env["OMNIUS_API_KEY"] = apiKey;
|
|
649999
650726
|
const dir = join179(homedir62(), ".omnius");
|
|
650000
650727
|
mkdirSync106(dir, { recursive: true });
|
|
650001
|
-
|
|
650728
|
+
writeFileSync90(join179(dir, "api.key"), apiKey + "\n", "utf8");
|
|
650002
650729
|
renderInfo(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
650003
650730
|
renderInfo(
|
|
650004
650731
|
"Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it."
|
|
@@ -650017,11 +650744,11 @@ var init_commands = __esm({
|
|
|
650017
650744
|
const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
650018
650745
|
try {
|
|
650019
650746
|
const { homedir: homedir62 } = await import("node:os");
|
|
650020
|
-
const { mkdirSync: mkdirSync106, writeFileSync:
|
|
650747
|
+
const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync90 } = await import("node:fs");
|
|
650021
650748
|
const { join: join179 } = await import("node:path");
|
|
650022
650749
|
const dir = join179(homedir62(), ".omnius");
|
|
650023
650750
|
mkdirSync106(dir, { recursive: true });
|
|
650024
|
-
|
|
650751
|
+
writeFileSync90(join179(dir, "access"), `${val}
|
|
650025
650752
|
`, "utf8");
|
|
650026
650753
|
} catch {
|
|
650027
650754
|
}
|
|
@@ -661171,6 +661898,175 @@ var init_soul_observations = __esm({
|
|
|
661171
661898
|
}
|
|
661172
661899
|
});
|
|
661173
661900
|
|
|
661901
|
+
// packages/cli/src/tui/visual-object-association.ts
|
|
661902
|
+
var visual_object_association_exports = {};
|
|
661903
|
+
__export(visual_object_association_exports, {
|
|
661904
|
+
associateVisualObjectFromImage: () => associateVisualObjectFromImage,
|
|
661905
|
+
extractExplicitVisualObjectLabels: () => extractExplicitVisualObjectLabels,
|
|
661906
|
+
formatVisualObjectMemoryContext: () => formatVisualObjectMemoryContext
|
|
661907
|
+
});
|
|
661908
|
+
import { basename as basename35 } from "node:path";
|
|
661909
|
+
function stringValue2(value2) {
|
|
661910
|
+
return typeof value2 === "string" ? value2.trim() : "";
|
|
661911
|
+
}
|
|
661912
|
+
function stringList(value2) {
|
|
661913
|
+
if (Array.isArray(value2)) {
|
|
661914
|
+
return value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
|
|
661915
|
+
}
|
|
661916
|
+
const single = stringValue2(value2);
|
|
661917
|
+
return single ? [single] : [];
|
|
661918
|
+
}
|
|
661919
|
+
function splitLabels(value2) {
|
|
661920
|
+
return value2.split(/[;,]/).map((part) => part.trim()).filter(Boolean).slice(0, 12);
|
|
661921
|
+
}
|
|
661922
|
+
function normalizeLabel(value2) {
|
|
661923
|
+
return value2.replace(/\s+/g, " ").replace(/^["'`]+|["'`]+$/g, "").trim();
|
|
661924
|
+
}
|
|
661925
|
+
function uniqueLabels(values) {
|
|
661926
|
+
const seen = /* @__PURE__ */ new Set();
|
|
661927
|
+
const out = [];
|
|
661928
|
+
for (const raw of values) {
|
|
661929
|
+
const label = normalizeLabel(raw);
|
|
661930
|
+
const key = label.toLowerCase();
|
|
661931
|
+
if (!label || seen.has(key)) continue;
|
|
661932
|
+
seen.add(key);
|
|
661933
|
+
out.push(label);
|
|
661934
|
+
}
|
|
661935
|
+
return out;
|
|
661936
|
+
}
|
|
661937
|
+
function explicitCaptionLabels(caption) {
|
|
661938
|
+
const text2 = stringValue2(caption);
|
|
661939
|
+
if (!text2) return [];
|
|
661940
|
+
const match = text2.match(/^\s*(?:object[_ -]?label|object|label|labels)\s*:\s*(.+)$/i);
|
|
661941
|
+
return match?.[1] ? splitLabels(match[1]) : [];
|
|
661942
|
+
}
|
|
661943
|
+
function identityNames(payload) {
|
|
661944
|
+
const names = /* @__PURE__ */ new Set();
|
|
661945
|
+
const add3 = (value2) => {
|
|
661946
|
+
const name10 = normalizeLabel(String(value2 ?? ""));
|
|
661947
|
+
if (name10) names.add(name10.toLowerCase());
|
|
661948
|
+
};
|
|
661949
|
+
for (const key of ["person", "person_name", "personName", "face_name", "faceName"]) {
|
|
661950
|
+
add3(payload[key]);
|
|
661951
|
+
}
|
|
661952
|
+
for (const person of stringList(payload["people"])) add3(person);
|
|
661953
|
+
const assertions = Array.isArray(payload["identityAssertions"]) ? payload["identityAssertions"] : Array.isArray(payload["identity_assertions"]) ? payload["identity_assertions"] : [];
|
|
661954
|
+
for (const item of assertions) {
|
|
661955
|
+
if (item && typeof item === "object") add3(item["name"]);
|
|
661956
|
+
}
|
|
661957
|
+
return names;
|
|
661958
|
+
}
|
|
661959
|
+
function isRejectedObjectLabel(label, payload) {
|
|
661960
|
+
const key = normalizeLabel(label).toLowerCase();
|
|
661961
|
+
if (!key) return true;
|
|
661962
|
+
if (/^(visual_identity|pending_visual_identity|person|face|speaker)(?:[_:\s-]|$)/i.test(label)) return true;
|
|
661963
|
+
if (identityNames(payload).has(key)) return true;
|
|
661964
|
+
return false;
|
|
661965
|
+
}
|
|
661966
|
+
function extractExplicitVisualObjectLabels(payload) {
|
|
661967
|
+
const media = payload["media"] && typeof payload["media"] === "object" ? payload["media"] : {};
|
|
661968
|
+
const candidates = uniqueLabels([
|
|
661969
|
+
...stringList(payload["object_label"]),
|
|
661970
|
+
...stringList(payload["objectLabel"]),
|
|
661971
|
+
...stringList(payload["object_labels"]),
|
|
661972
|
+
...stringList(payload["objectLabels"]),
|
|
661973
|
+
...stringList(payload["visualObjectLabel"]),
|
|
661974
|
+
...stringList(payload["visual_object_label"]),
|
|
661975
|
+
...stringList(payload["visualObjectLabels"]),
|
|
661976
|
+
...stringList(payload["visual_object_labels"]),
|
|
661977
|
+
...stringList(payload["label"]),
|
|
661978
|
+
...stringList(payload["labels"]),
|
|
661979
|
+
...stringList(media["objectLabel"]),
|
|
661980
|
+
...stringList(media["object_label"]),
|
|
661981
|
+
...stringList(media["objectLabels"]),
|
|
661982
|
+
...stringList(media["object_labels"]),
|
|
661983
|
+
...stringList(media["label"]),
|
|
661984
|
+
...stringList(media["labels"]),
|
|
661985
|
+
...explicitCaptionLabels(payload["caption"]),
|
|
661986
|
+
...explicitCaptionLabels(media["caption"])
|
|
661987
|
+
]).filter((label) => !isRejectedObjectLabel(label, payload));
|
|
661988
|
+
const aliases = uniqueLabels([
|
|
661989
|
+
...stringList(payload["aliases"]),
|
|
661990
|
+
...stringList(payload["object_aliases"]),
|
|
661991
|
+
...stringList(payload["objectAliases"]),
|
|
661992
|
+
...stringList(payload["visualObjectAliases"]),
|
|
661993
|
+
...stringList(payload["visual_object_aliases"]),
|
|
661994
|
+
...stringList(media["aliases"]),
|
|
661995
|
+
...stringList(media["objectAliases"]),
|
|
661996
|
+
...stringList(media["object_aliases"]),
|
|
661997
|
+
...candidates.slice(1)
|
|
661998
|
+
]).filter((label) => !isRejectedObjectLabel(label, payload));
|
|
661999
|
+
return {
|
|
662000
|
+
label: candidates[0],
|
|
662001
|
+
aliases,
|
|
662002
|
+
source: candidates.length > 0 ? "explicit_visual_object_label" : void 0
|
|
662003
|
+
};
|
|
662004
|
+
}
|
|
662005
|
+
function formatVisualObjectMemoryContext(result) {
|
|
662006
|
+
if (!result.taught || !result.label) return "";
|
|
662007
|
+
const lines = [
|
|
662008
|
+
"Visual Object Memory",
|
|
662009
|
+
`- Learned object label: ${result.label}`
|
|
662010
|
+
];
|
|
662011
|
+
if (result.aliases.length > 0) lines.push(`- Aliases: ${result.aliases.join(", ")}`);
|
|
662012
|
+
return lines.join("\n");
|
|
662013
|
+
}
|
|
662014
|
+
async function associateVisualObjectFromImage(options2) {
|
|
662015
|
+
const payload = options2.payload ?? {};
|
|
662016
|
+
const extraction = extractExplicitVisualObjectLabels({
|
|
662017
|
+
...payload,
|
|
662018
|
+
media: options2.media ?? payload["media"]
|
|
662019
|
+
});
|
|
662020
|
+
if (!extraction.label) {
|
|
662021
|
+
return {
|
|
662022
|
+
attempted: false,
|
|
662023
|
+
taught: false,
|
|
662024
|
+
aliases: [],
|
|
662025
|
+
contextBlock: ""
|
|
662026
|
+
};
|
|
662027
|
+
}
|
|
662028
|
+
const visual = options2.visualMemoryTool ?? new VisualMemoryTool();
|
|
662029
|
+
const aliases = uniqueLabels(extraction.aliases.filter((alias) => alias.toLowerCase() !== extraction.label.toLowerCase()));
|
|
662030
|
+
const labels = uniqueLabels([extraction.label, ...aliases]);
|
|
662031
|
+
const teach = await visual.execute({
|
|
662032
|
+
action: "teach",
|
|
662033
|
+
image: options2.imagePath,
|
|
662034
|
+
label: extraction.label,
|
|
662035
|
+
aliases,
|
|
662036
|
+
labels,
|
|
662037
|
+
sourceSurface: options2.sourceSurface,
|
|
662038
|
+
sessionId: options2.sessionId,
|
|
662039
|
+
fileUniqueId: options2.media?.fileUniqueId
|
|
662040
|
+
});
|
|
662041
|
+
if (!teach.success) {
|
|
662042
|
+
return {
|
|
662043
|
+
attempted: true,
|
|
662044
|
+
taught: false,
|
|
662045
|
+
label: extraction.label,
|
|
662046
|
+
aliases,
|
|
662047
|
+
contextBlock: "",
|
|
662048
|
+
output: teach.output,
|
|
662049
|
+
degradedReason: teach.error || teach.output || `visual_memory teach failed for ${basename35(options2.imagePath)}`
|
|
662050
|
+
};
|
|
662051
|
+
}
|
|
662052
|
+
const result = {
|
|
662053
|
+
attempted: true,
|
|
662054
|
+
taught: true,
|
|
662055
|
+
label: extraction.label,
|
|
662056
|
+
aliases,
|
|
662057
|
+
contextBlock: "",
|
|
662058
|
+
output: teach.output
|
|
662059
|
+
};
|
|
662060
|
+
result.contextBlock = formatVisualObjectMemoryContext(result);
|
|
662061
|
+
return result;
|
|
662062
|
+
}
|
|
662063
|
+
var init_visual_object_association = __esm({
|
|
662064
|
+
"packages/cli/src/tui/visual-object-association.ts"() {
|
|
662065
|
+
"use strict";
|
|
662066
|
+
init_dist5();
|
|
662067
|
+
}
|
|
662068
|
+
});
|
|
662069
|
+
|
|
661174
662070
|
// packages/cli/src/tui/telegram-channel-dmn.ts
|
|
661175
662071
|
import {
|
|
661176
662072
|
existsSync as existsSync144,
|
|
@@ -663671,55 +664567,16 @@ function advancedOcr(imagePath) {
|
|
|
663671
664567
|
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
664568
|
if (!isVisionModel(modelName)) return "";
|
|
663673
664569
|
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
664570
|
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
|
-
})
|
|
664571
|
+
const tool = new VisionTool(process.cwd());
|
|
664572
|
+
const result = await tool.execute({
|
|
664573
|
+
image: imagePath,
|
|
664574
|
+
action: "query",
|
|
664575
|
+
prompt,
|
|
664576
|
+
model: modelName
|
|
663718
664577
|
});
|
|
663719
|
-
if (!
|
|
663720
|
-
|
|
663721
|
-
const data = await response.json();
|
|
663722
|
-
return (data.response || "").trim();
|
|
664578
|
+
if (!result.success) return "";
|
|
664579
|
+
return String(result.llmContent || result.output || "").trim();
|
|
663723
664580
|
} catch {
|
|
663724
664581
|
return "";
|
|
663725
664582
|
}
|
|
@@ -663790,13 +664647,13 @@ import {
|
|
|
663790
664647
|
statSync as statSync50,
|
|
663791
664648
|
statfsSync as statfsSync7,
|
|
663792
664649
|
readFileSync as readFileSync119,
|
|
663793
|
-
writeFileSync as
|
|
664650
|
+
writeFileSync as writeFileSync77,
|
|
663794
664651
|
appendFileSync as appendFileSync15
|
|
663795
664652
|
} from "node:fs";
|
|
663796
664653
|
import {
|
|
663797
664654
|
join as join158,
|
|
663798
664655
|
resolve as resolve62,
|
|
663799
|
-
basename as
|
|
664656
|
+
basename as basename36,
|
|
663800
664657
|
relative as relative16,
|
|
663801
664658
|
isAbsolute as isAbsolute11,
|
|
663802
664659
|
extname as extname21
|
|
@@ -666265,6 +667122,7 @@ var init_telegram_bridge = __esm({
|
|
|
666265
667122
|
init_soul_observations();
|
|
666266
667123
|
init_identity_memory_tool();
|
|
666267
667124
|
init_visual_identity_association();
|
|
667125
|
+
init_visual_object_association();
|
|
666268
667126
|
init_telegram_channel_dmn();
|
|
666269
667127
|
init_telegram_reflection_corpus();
|
|
666270
667128
|
init_memory_paths();
|
|
@@ -669265,6 +670123,14 @@ ${mediaContext}` : ""
|
|
|
669265
670123
|
const messageText = isReplyMedia ? msg.replyContext?.text || msg.replyContext?.caption || msg.replyToText || media.caption : msg.text || media.caption;
|
|
669266
670124
|
const sender = isReplyMedia ? this.telegramMemorySenderFromReply(msg) : this.telegramMemorySenderFromMessage(msg);
|
|
669267
670125
|
const modality = media.type === "audio" || media.type === "voice" ? "audio" : telegramMediaIsImage(media) ? "visual" : "text";
|
|
670126
|
+
const objectLabels = extractExplicitVisualObjectLabels({
|
|
670127
|
+
caption: media.caption,
|
|
670128
|
+
media: { caption: media.caption }
|
|
670129
|
+
});
|
|
670130
|
+
const structuredObjectLabels = [
|
|
670131
|
+
objectLabels.label,
|
|
670132
|
+
...objectLabels.aliases
|
|
670133
|
+
].filter((label) => typeof label === "string" && label.trim().length > 0);
|
|
669268
670134
|
const payload = {
|
|
669269
670135
|
sourceSurface: "telegram",
|
|
669270
670136
|
sessionId: this.sessionKeyForMessage(msg),
|
|
@@ -669300,8 +670166,12 @@ ${mediaContext}` : ""
|
|
|
669300
670166
|
sender_id: sender?.id,
|
|
669301
670167
|
username: sender?.username,
|
|
669302
670168
|
display_name: sender?.displayName,
|
|
669303
|
-
labels:
|
|
670169
|
+
labels: structuredObjectLabels
|
|
669304
670170
|
};
|
|
670171
|
+
if (objectLabels.label) {
|
|
670172
|
+
payload.object_label = objectLabels.label;
|
|
670173
|
+
payload.aliases = objectLabels.aliases;
|
|
670174
|
+
}
|
|
669305
670175
|
if (extractedContent) {
|
|
669306
670176
|
if (modality === "audio") payload.transcript = extractedContent;
|
|
669307
670177
|
else payload.extractedContent = extractedContent;
|
|
@@ -670202,7 +671072,7 @@ ${mediaContext}` : ""
|
|
|
670202
671072
|
autoFollowup: false
|
|
670203
671073
|
}
|
|
670204
671074
|
};
|
|
670205
|
-
|
|
671075
|
+
writeFileSync77(
|
|
670206
671076
|
this.telegramConversationPath(sessionKey),
|
|
670207
671077
|
JSON.stringify(payload, null, 2) + "\n",
|
|
670208
671078
|
"utf8"
|
|
@@ -671031,7 +671901,7 @@ ${mediaContext}` : ""
|
|
|
671031
671901
|
}
|
|
671032
671902
|
const matchingEntry = mediaEntries.find((entry) => {
|
|
671033
671903
|
if (resolve62(entry.localPath) === resolve62(raw)) return true;
|
|
671034
|
-
if (
|
|
671904
|
+
if (basename36(entry.localPath) === raw) return true;
|
|
671035
671905
|
if (entry.fileUniqueId === raw || entry.fileId === raw) return true;
|
|
671036
671906
|
if (entry.messageId && String(entry.messageId) === raw) return true;
|
|
671037
671907
|
if (entry.messageId && `message_id:${entry.messageId}` === raw.toLowerCase())
|
|
@@ -671072,7 +671942,7 @@ ${mediaContext}` : ""
|
|
|
671072
671942
|
sourceMessageId,
|
|
671073
671943
|
chatKey,
|
|
671074
671944
|
mediaKind,
|
|
671075
|
-
safeAlias:
|
|
671945
|
+
safeAlias: basename36(result.path)
|
|
671076
671946
|
}
|
|
671077
671947
|
};
|
|
671078
671948
|
}
|
|
@@ -671113,7 +671983,7 @@ ${mediaContext}` : ""
|
|
|
671113
671983
|
}
|
|
671114
671984
|
return entries.find((entry2) => {
|
|
671115
671985
|
if (resolve62(entry2.localPath) === resolve62(ref)) return true;
|
|
671116
|
-
if (
|
|
671986
|
+
if (basename36(entry2.localPath) === ref) return true;
|
|
671117
671987
|
if (entry2.fileUniqueId === ref || entry2.fileId === ref) return true;
|
|
671118
671988
|
if (entry2.messageId && String(entry2.messageId) === ref) return true;
|
|
671119
671989
|
return false;
|
|
@@ -671141,7 +672011,7 @@ ${mediaContext}` : ""
|
|
|
671141
672011
|
caption: entry.caption
|
|
671142
672012
|
},
|
|
671143
672013
|
modality,
|
|
671144
|
-
label: `Telegram message_id ${entry.messageId || "unknown"} ${
|
|
672014
|
+
label: `Telegram message_id ${entry.messageId || "unknown"} ${basename36(entry.localPath)}`,
|
|
671145
672015
|
extractedContent: entry.extractedContent
|
|
671146
672016
|
};
|
|
671147
672017
|
}
|
|
@@ -672307,8 +673177,8 @@ ${cardLines.join("\n")}`
|
|
|
672307
673177
|
const caption = entry.caption ? ` caption=${telegramContextJsonString(entry.caption, 120)}` : "";
|
|
672308
673178
|
const extracted = entry.extractedContent ? `
|
|
672309
673179
|
extracted=${telegramContextJsonString(entry.extractedContent.replace(/\s+/g, " "), 220)}` : "";
|
|
672310
|
-
const alias = entry.messageId ? `message_id:${entry.messageId}` :
|
|
672311
|
-
return `- ${alias}${replyMark}: ${kind}; file ${
|
|
673180
|
+
const alias = entry.messageId ? `message_id:${entry.messageId}` : basename36(entry.localPath);
|
|
673181
|
+
return `- ${alias}${replyMark}: ${kind}; file ${basename36(entry.localPath)}${caption}${extracted}`;
|
|
672312
673182
|
});
|
|
672313
673183
|
sections.push(
|
|
672314
673184
|
[
|
|
@@ -674805,7 +675675,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`
|
|
|
674805
675675
|
throw e2;
|
|
674806
675676
|
}
|
|
674807
675677
|
}
|
|
674808
|
-
|
|
675678
|
+
writeFileSync77(
|
|
674809
675679
|
lockFile,
|
|
674810
675680
|
JSON.stringify(
|
|
674811
675681
|
{
|
|
@@ -679758,7 +680628,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
679758
680628
|
}
|
|
679759
680629
|
writeTelegramToolButtonState(state) {
|
|
679760
680630
|
mkdirSync89(this.telegramToolButtonDir, { recursive: true });
|
|
679761
|
-
|
|
680631
|
+
writeFileSync77(
|
|
679762
680632
|
this.telegramToolButtonPath(state.nonce),
|
|
679763
680633
|
JSON.stringify(state, null, 2) + "\n",
|
|
679764
680634
|
"utf-8"
|
|
@@ -680661,12 +681531,12 @@ Advanced text extraction signal: chars=${advancedSignal.chars}, lines=${advanced
|
|
|
680661
681531
|
};
|
|
680662
681532
|
}
|
|
680663
681533
|
const lines = entries.map((entry, index) => {
|
|
680664
|
-
const pathAlias = entry.messageId ? `message_id:${entry.messageId}` :
|
|
681534
|
+
const pathAlias = entry.messageId ? `message_id:${entry.messageId}` : basename36(entry.localPath);
|
|
680665
681535
|
const parts = [
|
|
680666
681536
|
`${index + 1}. message_id ${entry.messageId || "unknown"}`,
|
|
680667
681537
|
currentMsg?.replyToMessageId === entry.messageId ? "replied-to" : "",
|
|
680668
681538
|
telegramCachedMediaIsImage(entry) ? "image" : telegramCachedMediaIsPdf(entry) ? "pdf" : telegramCachedMediaIsAudio(entry) ? "audio" : telegramCachedMediaIsVideo(entry) ? "video" : entry.mediaType,
|
|
680669
|
-
`file=${
|
|
681539
|
+
`file=${basename36(entry.localPath)}`,
|
|
680670
681540
|
`path_alias=${pathAlias}`,
|
|
680671
681541
|
entry.caption ? `caption=${telegramContextJsonString(entry.caption, 140)}` : ""
|
|
680672
681542
|
].filter(Boolean);
|
|
@@ -680849,8 +681719,8 @@ Advanced text extraction signal: chars=${advancedSignal.chars}, lines=${advanced
|
|
|
680849
681719
|
)) {
|
|
680850
681720
|
return {
|
|
680851
681721
|
success: true,
|
|
680852
|
-
output: `Telegram file already sent in this turn: ${
|
|
680853
|
-
llmContent: `Already sent ${
|
|
681722
|
+
output: `Telegram file already sent in this turn: ${basename36(file.path)} as ${kind} to ${String(target.chatId)}`,
|
|
681723
|
+
llmContent: `Already sent ${basename36(file.path)} to Telegram as ${kind}; do not send it again.`,
|
|
680854
681724
|
durationMs: performance.now() - start2,
|
|
680855
681725
|
mutated: false,
|
|
680856
681726
|
mutatedFiles: []
|
|
@@ -680877,8 +681747,8 @@ Advanced text extraction signal: chars=${advancedSignal.chars}, lines=${advanced
|
|
|
680877
681747
|
);
|
|
680878
681748
|
return {
|
|
680879
681749
|
success: true,
|
|
680880
|
-
output: `Sent Telegram file: ${
|
|
680881
|
-
llmContent: `Sent ${
|
|
681750
|
+
output: `Sent Telegram file: ${basename36(file.path)} as ${kind} to ${String(target.chatId)}${messageId ? ` (message_id ${messageId})` : ""}`,
|
|
681751
|
+
llmContent: `Sent ${basename36(file.path)} to Telegram as ${kind}.`,
|
|
680882
681752
|
durationMs: performance.now() - start2,
|
|
680883
681753
|
mutated: false,
|
|
680884
681754
|
mutatedFiles: []
|
|
@@ -681164,6 +682034,7 @@ ${visionContext}]`;
|
|
|
681164
682034
|
cacheEntry.extractedContent
|
|
681165
682035
|
);
|
|
681166
682036
|
let visualIdentityContext = "";
|
|
682037
|
+
let visualObjectContext = "";
|
|
681167
682038
|
let ingestReachedDaemon = false;
|
|
681168
682039
|
try {
|
|
681169
682040
|
const ingestResponse = await fetch(
|
|
@@ -681181,6 +682052,9 @@ ${visionContext}]`;
|
|
|
681181
682052
|
const block = ingested?.visualIdentity?.contextBlock;
|
|
681182
682053
|
if (typeof block === "string" && block.trim())
|
|
681183
682054
|
visualIdentityContext = block.trim();
|
|
682055
|
+
const objectBlock = ingested?.visualObjectMemory?.contextBlock;
|
|
682056
|
+
if (typeof objectBlock === "string" && objectBlock.trim())
|
|
682057
|
+
visualObjectContext = objectBlock.trim();
|
|
681184
682058
|
}
|
|
681185
682059
|
} catch {
|
|
681186
682060
|
}
|
|
@@ -681202,8 +682076,29 @@ ${visionContext}]`;
|
|
|
681202
682076
|
visualIdentityContext = association.contextBlock;
|
|
681203
682077
|
} catch {
|
|
681204
682078
|
}
|
|
682079
|
+
try {
|
|
682080
|
+
const objectMemory = await associateVisualObjectFromImage({
|
|
682081
|
+
repoRoot: this.repoRoot,
|
|
682082
|
+
imagePath: localPath,
|
|
682083
|
+
sourceSurface: "telegram",
|
|
682084
|
+
scope: ingestPayload["scope"],
|
|
682085
|
+
sender: ingestPayload["sender"],
|
|
682086
|
+
message: ingestPayload["message"],
|
|
682087
|
+
replyTo: ingestPayload["replyTo"],
|
|
682088
|
+
sessionId: typeof ingestPayload["sessionId"] === "string" ? ingestPayload["sessionId"] : this.sessionKeyForMessage(msg),
|
|
682089
|
+
media: ingestPayload["media"],
|
|
682090
|
+
extractedContent: cacheEntry.extractedContent,
|
|
682091
|
+
payload: ingestPayload
|
|
682092
|
+
});
|
|
682093
|
+
if (objectMemory.contextBlock)
|
|
682094
|
+
visualObjectContext = objectMemory.contextBlock;
|
|
682095
|
+
} catch {
|
|
682096
|
+
}
|
|
681205
682097
|
}
|
|
681206
|
-
description = appendMediaContextBlock(
|
|
682098
|
+
description = appendMediaContextBlock(
|
|
682099
|
+
description,
|
|
682100
|
+
[visualIdentityContext, visualObjectContext].filter(Boolean).join("\n\n")
|
|
682101
|
+
);
|
|
681207
682102
|
} else if (isImageMedia) {
|
|
681208
682103
|
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
682104
|
cacheEntry.analysisComplete = false;
|
|
@@ -681512,7 +682407,7 @@ ${text2}`.trim()
|
|
|
681512
682407
|
throw new Error(`File does not exist: ${media.value}`);
|
|
681513
682408
|
const buffer2 = readFileSync119(media.value);
|
|
681514
682409
|
const boundary = `----omnius-media-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
681515
|
-
const filename =
|
|
682410
|
+
const filename = basename36(media.value);
|
|
681516
682411
|
const contentType = mimeForPath(media.value, media.kind);
|
|
681517
682412
|
const parts = [];
|
|
681518
682413
|
const addField = (name10, value2) => {
|
|
@@ -681750,7 +682645,7 @@ Content-Type: ${contentType}\r
|
|
|
681750
682645
|
audioAsVoice: false
|
|
681751
682646
|
},
|
|
681752
682647
|
{
|
|
681753
|
-
caption: `Vision action loop screenshot: ${
|
|
682648
|
+
caption: `Vision action loop screenshot: ${basename36(abs)}`
|
|
681754
682649
|
}
|
|
681755
682650
|
).catch(() => null);
|
|
681756
682651
|
}
|
|
@@ -681830,7 +682725,7 @@ Content-Type: ${contentType}\r
|
|
|
681830
682725
|
continue;
|
|
681831
682726
|
}
|
|
681832
682727
|
const buffer2 = readFileSync119(pathOrFileId);
|
|
681833
|
-
const filename =
|
|
682728
|
+
const filename = basename36(pathOrFileId);
|
|
681834
682729
|
parts.push(Buffer.from(`--${boundary}\r
|
|
681835
682730
|
`));
|
|
681836
682731
|
parts.push(
|
|
@@ -683607,9 +684502,9 @@ __export(projects_exports, {
|
|
|
683607
684502
|
setCurrentProject: () => setCurrentProject,
|
|
683608
684503
|
unregisterProject: () => unregisterProject
|
|
683609
684504
|
});
|
|
683610
|
-
import { readFileSync as readFileSync120, writeFileSync as
|
|
684505
|
+
import { readFileSync as readFileSync120, writeFileSync as writeFileSync78, mkdirSync as mkdirSync90, existsSync as existsSync147, statSync as statSync51, renameSync as renameSync12 } from "node:fs";
|
|
683611
684506
|
import { homedir as homedir52 } from "node:os";
|
|
683612
|
-
import { basename as
|
|
684507
|
+
import { basename as basename37, join as join159, resolve as resolve63 } from "node:path";
|
|
683613
684508
|
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
683614
684509
|
function readAll2() {
|
|
683615
684510
|
try {
|
|
@@ -683625,7 +684520,7 @@ function readAll2() {
|
|
|
683625
684520
|
function writeAll(file) {
|
|
683626
684521
|
mkdirSync90(OMNIUS_DIR3, { recursive: true });
|
|
683627
684522
|
const tmp = `${PROJECTS_FILE}.${randomUUID19().slice(0, 8)}.tmp`;
|
|
683628
|
-
|
|
684523
|
+
writeFileSync78(tmp, JSON.stringify(file, null, 2), "utf8");
|
|
683629
684524
|
renameSync12(tmp, PROJECTS_FILE);
|
|
683630
684525
|
}
|
|
683631
684526
|
function listProjects() {
|
|
@@ -683657,7 +684552,7 @@ function registerProject(root, pid) {
|
|
|
683657
684552
|
} else {
|
|
683658
684553
|
entry = {
|
|
683659
684554
|
root: canonical,
|
|
683660
|
-
name:
|
|
684555
|
+
name: basename37(canonical) || canonical,
|
|
683661
684556
|
firstSeen: now2,
|
|
683662
684557
|
lastSeen: now2,
|
|
683663
684558
|
pid: pid ?? null,
|
|
@@ -683708,7 +684603,7 @@ function setCurrentProject(root) {
|
|
|
683708
684603
|
currentRoot = canonical;
|
|
683709
684604
|
try {
|
|
683710
684605
|
mkdirSync90(OMNIUS_DIR3, { recursive: true });
|
|
683711
|
-
|
|
684606
|
+
writeFileSync78(CURRENT_FILE, `${canonical}
|
|
683712
684607
|
`, "utf8");
|
|
683713
684608
|
} catch {
|
|
683714
684609
|
}
|
|
@@ -684605,7 +685500,7 @@ var init_access_policy = __esm({
|
|
|
684605
685500
|
|
|
684606
685501
|
// packages/cli/src/api/project-preferences.ts
|
|
684607
685502
|
import { createHash as createHash42 } from "node:crypto";
|
|
684608
|
-
import { existsSync as existsSync148, mkdirSync as mkdirSync91, readFileSync as readFileSync121, renameSync as renameSync13, writeFileSync as
|
|
685503
|
+
import { existsSync as existsSync148, mkdirSync as mkdirSync91, readFileSync as readFileSync121, renameSync as renameSync13, writeFileSync as writeFileSync79, unlinkSync as unlinkSync34 } from "node:fs";
|
|
684609
685504
|
import { homedir as homedir53 } from "node:os";
|
|
684610
685505
|
import { join as join160, resolve as resolve64 } from "node:path";
|
|
684611
685506
|
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
@@ -684628,7 +685523,7 @@ function ensureDir(root) {
|
|
|
684628
685523
|
const sentinel = rootSentinelPath(root);
|
|
684629
685524
|
try {
|
|
684630
685525
|
if (!existsSync148(sentinel)) {
|
|
684631
|
-
|
|
685526
|
+
writeFileSync79(sentinel, `${resolve64(root)}
|
|
684632
685527
|
`, "utf8");
|
|
684633
685528
|
}
|
|
684634
685529
|
} catch {
|
|
@@ -684657,12 +685552,12 @@ function writeProjectPreferences(root, partial) {
|
|
|
684657
685552
|
};
|
|
684658
685553
|
const file = prefsPath(root);
|
|
684659
685554
|
const tmp = `${file}.${randomUUID20().slice(0, 8)}.tmp`;
|
|
684660
|
-
|
|
685555
|
+
writeFileSync79(tmp, JSON.stringify(merged, null, 2), "utf8");
|
|
684661
685556
|
try {
|
|
684662
685557
|
renameSync13(tmp, file);
|
|
684663
685558
|
} catch (err) {
|
|
684664
685559
|
try {
|
|
684665
|
-
|
|
685560
|
+
writeFileSync79(file, JSON.stringify(merged, null, 2), "utf8");
|
|
684666
685561
|
} catch {
|
|
684667
685562
|
}
|
|
684668
685563
|
try {
|
|
@@ -685067,7 +685962,7 @@ data: ${JSON.stringify(ev)}
|
|
|
685067
685962
|
|
|
685068
685963
|
// packages/cli/src/api/routes-media.ts
|
|
685069
685964
|
import { existsSync as existsSync151, mkdirSync as mkdirSync94, statSync as statSync53, copyFileSync as copyFileSync7, createReadStream } from "node:fs";
|
|
685070
|
-
import { basename as
|
|
685965
|
+
import { basename as basename38, join as join162, resolve as pathResolve2 } from "node:path";
|
|
685071
685966
|
function mediaWorkDir() {
|
|
685072
685967
|
return join162(omniusHomeDir(), "media", "_work");
|
|
685073
685968
|
}
|
|
@@ -685089,7 +685984,7 @@ function extractGeneratedPath(output) {
|
|
|
685089
685984
|
function publishToGallery(srcPath, kind) {
|
|
685090
685985
|
ensureGlobalMediaDirs();
|
|
685091
685986
|
const dir = globalMediaDir(kind);
|
|
685092
|
-
const name10 =
|
|
685987
|
+
const name10 = basename38(srcPath);
|
|
685093
685988
|
const dest = join162(dir, name10);
|
|
685094
685989
|
try {
|
|
685095
685990
|
if (pathResolve2(srcPath) !== pathResolve2(dest)) {
|
|
@@ -685290,7 +686185,7 @@ async function handleAvAnalyze(ctx3) {
|
|
|
685290
686185
|
adapterStatus[role] = a2 && !a2.meta.isMock ? "live" : "mock";
|
|
685291
686186
|
if (adapterStatus[role] === "live") anyLive = true;
|
|
685292
686187
|
}
|
|
685293
|
-
const episodeId = `rest-${
|
|
686188
|
+
const episodeId = `rest-${basename38(filePath)}-${Date.now().toString(36)}`;
|
|
685294
686189
|
const ingest = await ingestMedia(episodeId, `file://${filePath}`);
|
|
685295
686190
|
const store2 = await analyzeEpisode({ episodeId, mediaUri: `file://${filePath}`, durationSec: ingest.source.durationSec, registry: registry4, windows: ingest.shots, roles: AV_ROLES });
|
|
685296
686191
|
const world = store2.snapshot();
|
|
@@ -685460,7 +686355,7 @@ function handleFile(ctx3) {
|
|
|
685460
686355
|
return true;
|
|
685461
686356
|
}
|
|
685462
686357
|
const dir = globalMediaDir(kind);
|
|
685463
|
-
const full = pathResolve2(dir,
|
|
686358
|
+
const full = pathResolve2(dir, basename38(name10));
|
|
685464
686359
|
if (!full.startsWith(pathResolve2(dir)) || !existsSync151(full)) {
|
|
685465
686360
|
sendProblem(ctx3.res, problemDetails({
|
|
685466
686361
|
type: P.notFound,
|
|
@@ -685705,7 +686600,7 @@ var init_direct_tool_registry = __esm({
|
|
|
685705
686600
|
});
|
|
685706
686601
|
|
|
685707
686602
|
// packages/cli/src/api/external-tool-registry.ts
|
|
685708
|
-
import { existsSync as existsSync152, mkdirSync as mkdirSync95, readFileSync as readFileSync123, writeFileSync as
|
|
686603
|
+
import { existsSync as existsSync152, mkdirSync as mkdirSync95, readFileSync as readFileSync123, writeFileSync as writeFileSync80, renameSync as renameSync14 } from "node:fs";
|
|
685709
686604
|
import { join as join163 } from "node:path";
|
|
685710
686605
|
function externalToolStorePath(workingDir) {
|
|
685711
686606
|
return join163(workingDir, ".omnius", "external-tools.json");
|
|
@@ -685728,7 +686623,7 @@ function persist3(workingDir, tools) {
|
|
|
685728
686623
|
mkdirSync95(join163(workingDir, ".omnius"), { recursive: true });
|
|
685729
686624
|
const file = { version: STORE_VERSION, tools };
|
|
685730
686625
|
const tmp = `${path12}.tmp`;
|
|
685731
|
-
|
|
686626
|
+
writeFileSync80(tmp, JSON.stringify(file, null, 2), { mode: 384 });
|
|
685732
686627
|
renameSync14(tmp, path12);
|
|
685733
686628
|
}
|
|
685734
686629
|
function validateManifest2(input, existing) {
|
|
@@ -686840,7 +687735,7 @@ __export(runtime_keys_exports, {
|
|
|
686840
687735
|
mintKey: () => mintKey,
|
|
686841
687736
|
revokeByPrefix: () => revokeByPrefix
|
|
686842
687737
|
});
|
|
686843
|
-
import { existsSync as existsSync154, readFileSync as readFileSync125, writeFileSync as
|
|
687738
|
+
import { existsSync as existsSync154, readFileSync as readFileSync125, writeFileSync as writeFileSync81, mkdirSync as mkdirSync96, chmodSync as chmodSync4 } from "node:fs";
|
|
686844
687739
|
import { join as join165 } from "node:path";
|
|
686845
687740
|
import { homedir as homedir55 } from "node:os";
|
|
686846
687741
|
import { randomBytes as randomBytes27 } from "node:crypto";
|
|
@@ -686861,7 +687756,7 @@ function loadAll() {
|
|
|
686861
687756
|
}
|
|
686862
687757
|
function persistAll(records) {
|
|
686863
687758
|
ensureDir2();
|
|
686864
|
-
|
|
687759
|
+
writeFileSync81(KEYS_FILE, JSON.stringify(records, null, 2), "utf-8");
|
|
686865
687760
|
try {
|
|
686866
687761
|
chmodSync4(KEYS_FILE, 384);
|
|
686867
687762
|
} catch {
|
|
@@ -687095,7 +687990,7 @@ __export(graphical_sudo_exports, {
|
|
|
687095
687990
|
runGraphicalSudo: () => runGraphicalSudo
|
|
687096
687991
|
});
|
|
687097
687992
|
import { spawn as spawn31 } from "node:child_process";
|
|
687098
|
-
import { existsSync as existsSync156, mkdirSync as mkdirSync97, writeFileSync as
|
|
687993
|
+
import { existsSync as existsSync156, mkdirSync as mkdirSync97, writeFileSync as writeFileSync82, chmodSync as chmodSync5 } from "node:fs";
|
|
687099
687994
|
import { join as join167 } from "node:path";
|
|
687100
687995
|
import { tmpdir as tmpdir22 } from "node:os";
|
|
687101
687996
|
function detectSudoHelper() {
|
|
@@ -687131,7 +688026,7 @@ exec zenity --password --title="Omnius needs sudo" --text="${description.replace
|
|
|
687131
688026
|
exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
|
|
687132
688027
|
`;
|
|
687133
688028
|
}
|
|
687134
|
-
|
|
688029
|
+
writeFileSync82(shim, body, "utf-8");
|
|
687135
688030
|
chmodSync5(shim, 493);
|
|
687136
688031
|
return shim;
|
|
687137
688032
|
}
|
|
@@ -702167,7 +703062,7 @@ var init_auth_oidc = __esm({
|
|
|
702167
703062
|
});
|
|
702168
703063
|
|
|
702169
703064
|
// packages/cli/src/api/usage-tracker.ts
|
|
702170
|
-
import { mkdirSync as mkdirSync99, readFileSync as readFileSync128, writeFileSync as
|
|
703065
|
+
import { mkdirSync as mkdirSync99, readFileSync as readFileSync128, writeFileSync as writeFileSync83, existsSync as existsSync158 } from "node:fs";
|
|
702171
703066
|
import { join as join169 } from "node:path";
|
|
702172
703067
|
function initUsageTracker(omniusDir) {
|
|
702173
703068
|
const dir = join169(omniusDir, "usage");
|
|
@@ -702211,7 +703106,7 @@ function flush2() {
|
|
|
702211
703106
|
if (!initialized2 || !dirty) return;
|
|
702212
703107
|
try {
|
|
702213
703108
|
store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
|
|
702214
|
-
|
|
703109
|
+
writeFileSync83(usageFile, JSON.stringify(store, null, 2), "utf-8");
|
|
702215
703110
|
dirty = false;
|
|
702216
703111
|
} catch {
|
|
702217
703112
|
}
|
|
@@ -702386,7 +703281,7 @@ var init_chat_followup = __esm({
|
|
|
702386
703281
|
|
|
702387
703282
|
// packages/cli/src/docker.ts
|
|
702388
703283
|
import { execSync as execSync59, spawn as spawn32 } from "node:child_process";
|
|
702389
|
-
import { existsSync as existsSync159, mkdirSync as mkdirSync100, writeFileSync as
|
|
703284
|
+
import { existsSync as existsSync159, mkdirSync as mkdirSync100, writeFileSync as writeFileSync84 } from "node:fs";
|
|
702390
703285
|
import { join as join170, resolve as resolve65, dirname as dirname50 } from "node:path";
|
|
702391
703286
|
import { homedir as homedir58 } from "node:os";
|
|
702392
703287
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
@@ -702611,8 +703506,8 @@ chown -R node:node /workspace /home/node/.omnius 2>/dev/null || true
|
|
|
702611
703506
|
if [ "$1" = "omnius" ]; then shift; exec su - node -c "cd /workspace && omnius $*"; fi
|
|
702612
703507
|
exec "$@"
|
|
702613
703508
|
`;
|
|
702614
|
-
|
|
702615
|
-
|
|
703509
|
+
writeFileSync84(join170(dir, "Dockerfile"), dockerfile);
|
|
703510
|
+
writeFileSync84(join170(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
702616
703511
|
}
|
|
702617
703512
|
function hasNvidiaGpu() {
|
|
702618
703513
|
try {
|
|
@@ -702685,7 +703580,7 @@ __export(embedding_workers_exports, {
|
|
|
702685
703580
|
startEmbeddingWorkers: () => startEmbeddingWorkers,
|
|
702686
703581
|
stopEmbeddingWorkers: () => stopEmbeddingWorkers
|
|
702687
703582
|
});
|
|
702688
|
-
import { basename as
|
|
703583
|
+
import { basename as basename39, join as join171 } from "node:path";
|
|
702689
703584
|
function startEmbeddingWorkers(opts) {
|
|
702690
703585
|
if (_running) return;
|
|
702691
703586
|
_running = true;
|
|
@@ -702751,7 +703646,7 @@ async function runEmbeddingTask(modality, episodeId, taskId, opts) {
|
|
|
702751
703646
|
try {
|
|
702752
703647
|
if (!_aligner) {
|
|
702753
703648
|
const stateRoot = process.env.OMNIUS_DIR || process.cwd();
|
|
702754
|
-
const omniusDir =
|
|
703649
|
+
const omniusDir = basename39(stateRoot) === ".omnius" ? stateRoot : join171(stateRoot, ".omnius");
|
|
702755
703650
|
const memDir = join171(omniusDir, "memory");
|
|
702756
703651
|
_aligner = new EmbeddingAligner(
|
|
702757
703652
|
`${modality}-${emb.length}`,
|
|
@@ -702873,7 +703768,7 @@ import { spawn as spawn33, execSync as execSync60 } from "node:child_process";
|
|
|
702873
703768
|
import {
|
|
702874
703769
|
createReadStream as createReadStream2,
|
|
702875
703770
|
mkdirSync as mkdirSync101,
|
|
702876
|
-
writeFileSync as
|
|
703771
|
+
writeFileSync as writeFileSync85,
|
|
702877
703772
|
readFileSync as readFileSync129,
|
|
702878
703773
|
readdirSync as readdirSync56,
|
|
702879
703774
|
existsSync as existsSync160,
|
|
@@ -704534,11 +705429,11 @@ function atomicJobWrite(dir, id, job) {
|
|
|
704534
705429
|
const finalPath = join172(dir, `${id}.json`);
|
|
704535
705430
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
704536
705431
|
try {
|
|
704537
|
-
|
|
705432
|
+
writeFileSync85(tmpPath, JSON.stringify(job, null, 2), "utf-8");
|
|
704538
705433
|
renameSync15(tmpPath, finalPath);
|
|
704539
705434
|
} catch {
|
|
704540
705435
|
try {
|
|
704541
|
-
|
|
705436
|
+
writeFileSync85(finalPath, JSON.stringify(job, null, 2), "utf-8");
|
|
704542
705437
|
} catch {
|
|
704543
705438
|
}
|
|
704544
705439
|
try {
|
|
@@ -706370,7 +707265,7 @@ function writeUpdateState(state) {
|
|
|
706370
707265
|
mkdirSync101(dir, { recursive: true });
|
|
706371
707266
|
const finalPath = updateStateFile();
|
|
706372
707267
|
const tmpPath = `${finalPath}.tmp.${process.pid}`;
|
|
706373
|
-
|
|
707268
|
+
writeFileSync85(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
706374
707269
|
renameSync15(tmpPath, finalPath);
|
|
706375
707270
|
} catch {
|
|
706376
707271
|
}
|
|
@@ -708720,13 +709615,13 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
|
|
|
708720
709615
|
return;
|
|
708721
709616
|
}
|
|
708722
709617
|
const { tmpdir: tmpdir24 } = await import("node:os");
|
|
708723
|
-
const { writeFileSync:
|
|
709618
|
+
const { writeFileSync: writeFileSync90, unlinkSync: unlinkSync36 } = await import("node:fs");
|
|
708724
709619
|
const { join: pjoin } = await import("node:path");
|
|
708725
709620
|
const tmpPath = pjoin(
|
|
708726
709621
|
tmpdir24(),
|
|
708727
709622
|
`omnius-clone-upload-${Date.now()}-${safeName3}`
|
|
708728
709623
|
);
|
|
708729
|
-
|
|
709624
|
+
writeFileSync90(tmpPath, buf);
|
|
708730
709625
|
try {
|
|
708731
709626
|
const ve = getVoiceEngine();
|
|
708732
709627
|
const msg = await ve.setCloneVoice(tmpPath);
|
|
@@ -709450,7 +710345,7 @@ data: ${JSON.stringify(data)}
|
|
|
709450
710345
|
}
|
|
709451
710346
|
for (const f2 of seenFiles) {
|
|
709452
710347
|
try {
|
|
709453
|
-
|
|
710348
|
+
writeFileSync85(f2, JSON.stringify({ tasks: [] }, null, 2));
|
|
709454
710349
|
deleted++;
|
|
709455
710350
|
} catch {
|
|
709456
710351
|
}
|
|
@@ -711249,11 +712144,11 @@ function setScheduledEnabled(id, enabled2) {
|
|
|
711249
712144
|
arr[target.index].enabled = enabled2;
|
|
711250
712145
|
if (Array.isArray(json?.tasks)) {
|
|
711251
712146
|
json.tasks = arr;
|
|
711252
|
-
|
|
712147
|
+
writeFileSync85(target.file, JSON.stringify(json, null, 2));
|
|
711253
712148
|
} else if (Array.isArray(json)) {
|
|
711254
|
-
|
|
712149
|
+
writeFileSync85(target.file, JSON.stringify(arr, null, 2));
|
|
711255
712150
|
} else {
|
|
711256
|
-
|
|
712151
|
+
writeFileSync85(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
711257
712152
|
}
|
|
711258
712153
|
if (!enabled2) {
|
|
711259
712154
|
try {
|
|
@@ -711283,11 +712178,11 @@ function deleteScheduledById(id) {
|
|
|
711283
712178
|
arr.splice(target.index, 1);
|
|
711284
712179
|
if (Array.isArray(json?.tasks)) {
|
|
711285
712180
|
json.tasks = arr;
|
|
711286
|
-
|
|
712181
|
+
writeFileSync85(target.file, JSON.stringify(json, null, 2));
|
|
711287
712182
|
} else if (Array.isArray(json)) {
|
|
711288
|
-
|
|
712183
|
+
writeFileSync85(target.file, JSON.stringify(arr, null, 2));
|
|
711289
712184
|
} else {
|
|
711290
|
-
|
|
712185
|
+
writeFileSync85(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
711291
712186
|
}
|
|
711292
712187
|
const candidates = [];
|
|
711293
712188
|
if (id) candidates.push(id);
|
|
@@ -711521,7 +712416,7 @@ function reconcileScheduledTasks(apply) {
|
|
|
711521
712416
|
mkdirSync101(join172(wdir, ".omnius", "scheduled", "logs"), {
|
|
711522
712417
|
recursive: true
|
|
711523
712418
|
});
|
|
711524
|
-
|
|
712419
|
+
writeFileSync85(file, JSON.stringify(toWrite, null, 2));
|
|
711525
712420
|
adopted.push({ file, index: arr.length - 1 });
|
|
711526
712421
|
}
|
|
711527
712422
|
} else {
|
|
@@ -711699,8 +712594,8 @@ WantedBy=timers.target
|
|
|
711699
712594
|
`;
|
|
711700
712595
|
if (!dryRun) {
|
|
711701
712596
|
mkdirSync101(unitDir, { recursive: true });
|
|
711702
|
-
|
|
711703
|
-
|
|
712597
|
+
writeFileSync85(svc, svcText);
|
|
712598
|
+
writeFileSync85(tim, timText);
|
|
711704
712599
|
try {
|
|
711705
712600
|
const { execSync: es } = require4("node:child_process");
|
|
711706
712601
|
es("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
@@ -712084,7 +712979,7 @@ function startApiServer(options2 = {}) {
|
|
|
712084
712979
|
try {
|
|
712085
712980
|
const dir = join172(homedir59(), ".omnius");
|
|
712086
712981
|
mkdirSync101(dir, { recursive: true });
|
|
712087
|
-
|
|
712982
|
+
writeFileSync85(
|
|
712088
712983
|
join172(dir, "access"),
|
|
712089
712984
|
`${runtimeAccessMode}
|
|
712090
712985
|
`,
|
|
@@ -712497,7 +713392,7 @@ function startApiServer(options2 = {}) {
|
|
|
712497
713392
|
}
|
|
712498
713393
|
try {
|
|
712499
713394
|
const {
|
|
712500
|
-
writeFileSync:
|
|
713395
|
+
writeFileSync: writeFileSync90,
|
|
712501
713396
|
mkdirSync: mkdirSync106,
|
|
712502
713397
|
existsSync: _exists,
|
|
712503
713398
|
readFileSync: _rfs
|
|
@@ -712536,7 +713431,7 @@ function startApiServer(options2 = {}) {
|
|
|
712536
713431
|
for (const dir of dirSet) {
|
|
712537
713432
|
try {
|
|
712538
713433
|
if (!_exists(dir)) mkdirSync106(dir, { recursive: true });
|
|
712539
|
-
|
|
713434
|
+
writeFileSync90(_join(dir, "api-port.json"), apiHint);
|
|
712540
713435
|
written++;
|
|
712541
713436
|
} catch {
|
|
712542
713437
|
}
|
|
@@ -712905,7 +713800,7 @@ async function handleChatAttachmentUpload(req3, res) {
|
|
|
712905
713800
|
dir,
|
|
712906
713801
|
`${Date.now()}-${randomUUID21().slice(0, 8)}-${safeName3}`
|
|
712907
713802
|
);
|
|
712908
|
-
|
|
713803
|
+
writeFileSync85(localPath, Buffer.from(base642, "base64"));
|
|
712909
713804
|
const mimeType = typeof b.mimeType === "string" ? b.mimeType : typeof b.mime_type === "string" ? b.mime_type : "";
|
|
712910
713805
|
const isImage = mimeType.toLowerCase().startsWith("image/") || /\.(png|jpe?g|gif|webp|bmp|tiff?)$/i.test(safeName3);
|
|
712911
713806
|
const sessionId = typeof b.sessionId === "string" ? b.sessionId : typeof b.session_id === "string" ? b.session_id : void 0;
|
|
@@ -712962,6 +713857,7 @@ async function handleChatAttachmentUpload(req3, res) {
|
|
|
712962
713857
|
graph.close();
|
|
712963
713858
|
}
|
|
712964
713859
|
let visualIdentity = void 0;
|
|
713860
|
+
let visualObjectMemory = void 0;
|
|
712965
713861
|
let contextBlock = [
|
|
712966
713862
|
`GUI attachment saved: ${safeName3}`,
|
|
712967
713863
|
`path: ${localPath}`,
|
|
@@ -713000,6 +713896,40 @@ ${association.contextBlock}`;
|
|
|
713000
713896
|
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713001
713897
|
};
|
|
713002
713898
|
}
|
|
713899
|
+
try {
|
|
713900
|
+
const { associateVisualObjectFromImage: associateVisualObjectFromImage2 } = await Promise.resolve().then(() => (init_visual_object_association(), visual_object_association_exports));
|
|
713901
|
+
const objectMemory = await associateVisualObjectFromImage2({
|
|
713902
|
+
repoRoot: process.cwd(),
|
|
713903
|
+
imagePath: localPath,
|
|
713904
|
+
sourceSurface: "gui",
|
|
713905
|
+
scope,
|
|
713906
|
+
sender,
|
|
713907
|
+
message: message2,
|
|
713908
|
+
sessionId,
|
|
713909
|
+
media,
|
|
713910
|
+
payload: b
|
|
713911
|
+
});
|
|
713912
|
+
visualObjectMemory = {
|
|
713913
|
+
attempted: objectMemory.attempted,
|
|
713914
|
+
taught: objectMemory.taught,
|
|
713915
|
+
label: objectMemory.label,
|
|
713916
|
+
aliases: objectMemory.aliases,
|
|
713917
|
+
contextBlock: objectMemory.contextBlock,
|
|
713918
|
+
degradedReason: objectMemory.degradedReason
|
|
713919
|
+
};
|
|
713920
|
+
if (objectMemory.contextBlock)
|
|
713921
|
+
contextBlock += `
|
|
713922
|
+
|
|
713923
|
+
${objectMemory.contextBlock}`;
|
|
713924
|
+
} catch (err) {
|
|
713925
|
+
visualObjectMemory = {
|
|
713926
|
+
attempted: true,
|
|
713927
|
+
taught: false,
|
|
713928
|
+
aliases: [],
|
|
713929
|
+
contextBlock: "",
|
|
713930
|
+
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713931
|
+
};
|
|
713932
|
+
}
|
|
713003
713933
|
}
|
|
713004
713934
|
jsonResponse(res, 200, {
|
|
713005
713935
|
id: ingestId,
|
|
@@ -713008,7 +713938,8 @@ ${association.contextBlock}`;
|
|
|
713008
713938
|
mimeType,
|
|
713009
713939
|
modality,
|
|
713010
713940
|
contextBlock,
|
|
713011
|
-
visualIdentity
|
|
713941
|
+
visualIdentity,
|
|
713942
|
+
visualObjectMemory
|
|
713012
713943
|
});
|
|
713013
713944
|
} catch (err) {
|
|
713014
713945
|
jsonResponse(res, 400, {
|
|
@@ -713141,6 +714072,7 @@ async function handleMemoryIngest2(req3, res, ollamaUrl) {
|
|
|
713141
714072
|
embeddings
|
|
713142
714073
|
});
|
|
713143
714074
|
let visualIdentity = void 0;
|
|
714075
|
+
let visualObjectMemory = void 0;
|
|
713144
714076
|
if (modality === "visual" && mediaPath) {
|
|
713145
714077
|
try {
|
|
713146
714078
|
const { associateVisualIdentityFromImage: associateVisualIdentityFromImage2 } = await Promise.resolve().then(() => (init_visual_identity_association(), visual_identity_association_exports));
|
|
@@ -713174,8 +714106,40 @@ async function handleMemoryIngest2(req3, res, ollamaUrl) {
|
|
|
713174
714106
|
degradedReason: err instanceof Error ? err.message : String(err)
|
|
713175
714107
|
};
|
|
713176
714108
|
}
|
|
714109
|
+
try {
|
|
714110
|
+
const { associateVisualObjectFromImage: associateVisualObjectFromImage2 } = await Promise.resolve().then(() => (init_visual_object_association(), visual_object_association_exports));
|
|
714111
|
+
const objectMemory = await associateVisualObjectFromImage2({
|
|
714112
|
+
repoRoot: process.cwd(),
|
|
714113
|
+
imagePath: mediaPath,
|
|
714114
|
+
sourceSurface,
|
|
714115
|
+
scope,
|
|
714116
|
+
sender,
|
|
714117
|
+
message: message2,
|
|
714118
|
+
replyTo,
|
|
714119
|
+
sessionId,
|
|
714120
|
+
media,
|
|
714121
|
+
extractedContent: b.extracted_content || b.extractedContent,
|
|
714122
|
+
payload: b
|
|
714123
|
+
});
|
|
714124
|
+
visualObjectMemory = {
|
|
714125
|
+
attempted: objectMemory.attempted,
|
|
714126
|
+
taught: objectMemory.taught,
|
|
714127
|
+
label: objectMemory.label,
|
|
714128
|
+
aliases: objectMemory.aliases,
|
|
714129
|
+
contextBlock: objectMemory.contextBlock,
|
|
714130
|
+
degradedReason: objectMemory.degradedReason
|
|
714131
|
+
};
|
|
714132
|
+
} catch (err) {
|
|
714133
|
+
visualObjectMemory = {
|
|
714134
|
+
attempted: true,
|
|
714135
|
+
taught: false,
|
|
714136
|
+
aliases: [],
|
|
714137
|
+
contextBlock: "",
|
|
714138
|
+
degradedReason: err instanceof Error ? err.message : String(err)
|
|
714139
|
+
};
|
|
714140
|
+
}
|
|
713177
714141
|
}
|
|
713178
|
-
jsonResponse(res, 200, { id: result.episodeId, ...result, visualIdentity });
|
|
714142
|
+
jsonResponse(res, 200, { id: result.episodeId, ...result, visualIdentity, visualObjectMemory });
|
|
713179
714143
|
} catch (err) {
|
|
713180
714144
|
jsonResponse(res, 400, {
|
|
713181
714145
|
error: "bad_request",
|
|
@@ -713391,7 +714355,7 @@ __export(clipboard_media_exports, {
|
|
|
713391
714355
|
pasteClipboardImageToFile: () => pasteClipboardImageToFile
|
|
713392
714356
|
});
|
|
713393
714357
|
import { execFileSync as execFileSync11, execSync as execSync61 } from "node:child_process";
|
|
713394
|
-
import { mkdirSync as mkdirSync102, readFileSync as readFileSync130, rmSync as rmSync13, writeFileSync as
|
|
714358
|
+
import { mkdirSync as mkdirSync102, readFileSync as readFileSync130, rmSync as rmSync13, writeFileSync as writeFileSync86 } from "node:fs";
|
|
713395
714359
|
import { join as join173 } from "node:path";
|
|
713396
714360
|
function pasteClipboardImageToFile(repoRoot) {
|
|
713397
714361
|
const image = readClipboardImage();
|
|
@@ -713399,7 +714363,7 @@ function pasteClipboardImageToFile(repoRoot) {
|
|
|
713399
714363
|
const dir = join173(repoRoot, ".omnius", "clipboard");
|
|
713400
714364
|
mkdirSync102(dir, { recursive: true });
|
|
713401
714365
|
const path12 = join173(dir, `clipboard-${Date.now()}${image.ext}`);
|
|
713402
|
-
|
|
714366
|
+
writeFileSync86(path12, image.buffer);
|
|
713403
714367
|
return { path: path12, buffer: image.buffer, mime: image.mime };
|
|
713404
714368
|
}
|
|
713405
714369
|
function readClipboardImage() {
|
|
@@ -713468,7 +714432,7 @@ import { createRequire as createRequire9 } from "node:module";
|
|
|
713468
714432
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
713469
714433
|
import {
|
|
713470
714434
|
readFileSync as readFileSync131,
|
|
713471
|
-
writeFileSync as
|
|
714435
|
+
writeFileSync as writeFileSync87,
|
|
713472
714436
|
appendFileSync as appendFileSync17,
|
|
713473
714437
|
rmSync as rmSync14,
|
|
713474
714438
|
readdirSync as readdirSync57,
|
|
@@ -714595,7 +715559,7 @@ function createFanoutExploreTool(config, repoRoot, ctxWindowSize) {
|
|
|
714595
715559
|
);
|
|
714596
715560
|
if (debug) {
|
|
714597
715561
|
try {
|
|
714598
|
-
|
|
715562
|
+
writeFileSync87(
|
|
714599
715563
|
join174(repoRoot, ".omnius", "fanout-debug.json"),
|
|
714600
715564
|
JSON.stringify({ objective, regions, rawReturns, digests }, null, 2)
|
|
714601
715565
|
);
|
|
@@ -715381,7 +716345,7 @@ ${skillPack}`;
|
|
|
715381
716345
|
You have vision capabilities. Choose the RIGHT tool for each situation:
|
|
715382
716346
|
|
|
715383
716347
|
FOR IMAGE FILES (photos, screenshots, diagrams):
|
|
715384
|
-
image_read(
|
|
716348
|
+
image_read(path="path") — Read image metadata/base64/OCR; use vision(image="path") for semantic Moondream analysis
|
|
715385
716349
|
vision(image="path", action="caption") — Describe image contents via Moondream
|
|
715386
716350
|
vision(image="path", action="query", prompt="question") — Ask questions about an image
|
|
715387
716351
|
vision(image="path", action="detect", prompt="object") — Find objects (bounding boxes)
|
|
@@ -716951,6 +717915,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
716951
717915
|
},
|
|
716952
717916
|
async () => {
|
|
716953
717917
|
const result = await runner.run(effectiveTask, systemContext);
|
|
717918
|
+
_apiCallbacks?.onRunResult?.(result);
|
|
716954
717919
|
const tokens = {
|
|
716955
717920
|
total: result.totalTokens,
|
|
716956
717921
|
estimated: result.estimatedTokens
|
|
@@ -718910,7 +719875,7 @@ This is an independent background session started from /background.`
|
|
|
718910
719875
|
if (Math.random() < 0.02) {
|
|
718911
719876
|
const all2 = readFileSync131(HISTORY_FILE, "utf8").trim().split("\n");
|
|
718912
719877
|
if (all2.length > MAX_HISTORY_LINES) {
|
|
718913
|
-
|
|
719878
|
+
writeFileSync87(
|
|
718914
719879
|
HISTORY_FILE,
|
|
718915
719880
|
all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n",
|
|
718916
719881
|
"utf8"
|
|
@@ -719851,7 +720816,7 @@ Log: ${nexusLogPath}`
|
|
|
719851
720816
|
sessionTitle = title.trim() || null;
|
|
719852
720817
|
try {
|
|
719853
720818
|
mkdirSync103(join174(repoRoot, ".omnius"), { recursive: true });
|
|
719854
|
-
|
|
720819
|
+
writeFileSync87(
|
|
719855
720820
|
join174(repoRoot, ".omnius", "session-title"),
|
|
719856
720821
|
`${sessionTitle ?? ""}
|
|
719857
720822
|
`,
|
|
@@ -719945,7 +720910,7 @@ Log: ${nexusLogPath}`
|
|
|
719945
720910
|
queuePrompt(
|
|
719946
720911
|
imageContext ? `${imageContext}
|
|
719947
720912
|
|
|
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}.
|
|
720913
|
+
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
720914
|
"clipboard"
|
|
719950
720915
|
);
|
|
719951
720916
|
return {
|
|
@@ -722575,7 +723540,7 @@ ${result.text}`;
|
|
|
722575
723540
|
|
|
722576
723541
|
${imageContext}
|
|
722577
723542
|
|
|
722578
|
-
|
|
723543
|
+
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
723544
|
}
|
|
722580
723545
|
if (isMedia && fullInput === input && (voiceEngine.isLuxtts || voiceEngine.isMisotts)) {
|
|
722581
723546
|
const cloneExts = [".wav", ".mp3", ".ogg", ".flac", ".m4a"];
|
|
@@ -723233,6 +724198,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723233
724198
|
}
|
|
723234
724199
|
}
|
|
723235
724200
|
_apiCallbacks = callbacks ?? null;
|
|
724201
|
+
const headlessMode = Boolean(callbacks);
|
|
723236
724202
|
await bootstrapMcpAndPlugins(repoRoot);
|
|
723237
724203
|
renderCompactHeader(config.model);
|
|
723238
724204
|
renderUserMessage(task);
|
|
@@ -723243,6 +724209,10 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723243
724209
|
try {
|
|
723244
724210
|
const handle2 = startTask(task, config, repoRoot);
|
|
723245
724211
|
await handle2.promise;
|
|
724212
|
+
if (headlessMode) {
|
|
724213
|
+
_apiCallbacks = null;
|
|
724214
|
+
return;
|
|
724215
|
+
}
|
|
723246
724216
|
try {
|
|
723247
724217
|
const ikDir = join174(repoRoot, ".omnius", "identity");
|
|
723248
724218
|
const ikFile = join174(ikDir, "self-state.json");
|
|
@@ -723303,7 +724273,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723303
724273
|
);
|
|
723304
724274
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
723305
724275
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
723306
|
-
|
|
724276
|
+
writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
|
|
723307
724277
|
} catch (ikErr) {
|
|
723308
724278
|
}
|
|
723309
724279
|
try {
|
|
@@ -723336,7 +724306,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723336
724306
|
});
|
|
723337
724307
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
723338
724308
|
mkdirSync103(archeDir, { recursive: true });
|
|
723339
|
-
|
|
724309
|
+
writeFileSync87(archeFile, JSON.stringify(variants, null, 2));
|
|
723340
724310
|
} catch {
|
|
723341
724311
|
}
|
|
723342
724312
|
}
|
|
@@ -723367,7 +724337,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723367
724337
|
updated = true;
|
|
723368
724338
|
}
|
|
723369
724339
|
if (updated) {
|
|
723370
|
-
|
|
724340
|
+
writeFileSync87(metaFile2, JSON.stringify(store2, null, 2));
|
|
723371
724341
|
}
|
|
723372
724342
|
}
|
|
723373
724343
|
} catch {
|
|
@@ -723476,7 +724446,7 @@ Rules:
|
|
|
723476
724446
|
});
|
|
723477
724447
|
if (store2.length > 100) store2 = store2.slice(-100);
|
|
723478
724448
|
mkdirSync103(metaDir, { recursive: true });
|
|
723479
|
-
|
|
724449
|
+
writeFileSync87(storeFile, JSON.stringify(store2, null, 2));
|
|
723480
724450
|
}
|
|
723481
724451
|
}
|
|
723482
724452
|
} catch {
|
|
@@ -723526,6 +724496,10 @@ Rules:
|
|
|
723526
724496
|
} catch {
|
|
723527
724497
|
}
|
|
723528
724498
|
} catch (err) {
|
|
724499
|
+
if (headlessMode) {
|
|
724500
|
+
_apiCallbacks = null;
|
|
724501
|
+
throw err;
|
|
724502
|
+
}
|
|
723529
724503
|
try {
|
|
723530
724504
|
const ikFile = join174(repoRoot, ".omnius", "identity", "self-state.json");
|
|
723531
724505
|
if (existsSync161(ikFile)) {
|
|
@@ -723540,7 +724514,7 @@ Rules:
|
|
|
723540
724514
|
);
|
|
723541
724515
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
723542
724516
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
723543
|
-
|
|
724517
|
+
writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
|
|
723544
724518
|
}
|
|
723545
724519
|
const metaFile2 = join174(
|
|
723546
724520
|
repoRoot,
|
|
@@ -723568,7 +724542,7 @@ Rules:
|
|
|
723568
724542
|
(item.scores.confidence || 0.5) - 0.02
|
|
723569
724543
|
);
|
|
723570
724544
|
}
|
|
723571
|
-
|
|
724545
|
+
writeFileSync87(metaFile2, JSON.stringify(store2, null, 2));
|
|
723572
724546
|
}
|
|
723573
724547
|
try {
|
|
723574
724548
|
const archeDir = join174(repoRoot, ".omnius", "arche");
|
|
@@ -723591,7 +724565,7 @@ Rules:
|
|
|
723591
724565
|
});
|
|
723592
724566
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
723593
724567
|
mkdirSync103(archeDir, { recursive: true });
|
|
723594
|
-
|
|
724568
|
+
writeFileSync87(archeFile, JSON.stringify(variants, null, 2));
|
|
723595
724569
|
} catch {
|
|
723596
724570
|
}
|
|
723597
724571
|
} catch {
|
|
@@ -723704,7 +724678,7 @@ import { resolve as resolve68 } from "node:path";
|
|
|
723704
724678
|
import { spawn as spawn34 } from "node:child_process";
|
|
723705
724679
|
import {
|
|
723706
724680
|
mkdirSync as mkdirSync104,
|
|
723707
|
-
writeFileSync as
|
|
724681
|
+
writeFileSync as writeFileSync88,
|
|
723708
724682
|
readFileSync as readFileSync132,
|
|
723709
724683
|
readdirSync as readdirSync58,
|
|
723710
724684
|
existsSync as existsSync162
|
|
@@ -723752,6 +724726,7 @@ async function runJson(task, config, repoPath2) {
|
|
|
723752
724726
|
let result;
|
|
723753
724727
|
const assistantTexts = [];
|
|
723754
724728
|
const toolCallLog = [];
|
|
724729
|
+
let runnerResult = null;
|
|
723755
724730
|
try {
|
|
723756
724731
|
await runWithTUI(task, config, repoPath2, {
|
|
723757
724732
|
onAssistantText: (text2) => {
|
|
@@ -723775,13 +724750,29 @@ async function runJson(task, config, repoPath2) {
|
|
|
723775
724750
|
},
|
|
723776
724751
|
onStatus: (content) => {
|
|
723777
724752
|
origWrite(JSON.stringify({ type: "status", content }) + "\n");
|
|
724753
|
+
},
|
|
724754
|
+
onRunResult: (runResult) => {
|
|
724755
|
+
runnerResult = {
|
|
724756
|
+
status: runResult.status,
|
|
724757
|
+
completed: runResult.completed,
|
|
724758
|
+
summary: runResult.summary,
|
|
724759
|
+
turns: runResult.turns,
|
|
724760
|
+
toolCalls: runResult.toolCalls,
|
|
724761
|
+
filesEdited: runResult.filesEdited,
|
|
724762
|
+
testsRun: runResult.testsRun
|
|
724763
|
+
};
|
|
723778
724764
|
}
|
|
723779
724765
|
});
|
|
724766
|
+
const rr = runnerResult;
|
|
723780
724767
|
result = {
|
|
723781
|
-
status: "completed",
|
|
723782
|
-
summary: extractSummary(captured),
|
|
724768
|
+
status: rr?.completed ? "completed" : rr?.status ?? "completed",
|
|
724769
|
+
summary: rr?.summary || extractSummary(captured),
|
|
724770
|
+
turns: rr?.turns,
|
|
724771
|
+
toolCalls: rr?.toolCalls,
|
|
724772
|
+
filesModified: rr?.filesEdited,
|
|
724773
|
+
testsRun: rr?.testsRun,
|
|
723783
724774
|
durationMs: Date.now() - startTime,
|
|
723784
|
-
exitCode: 0
|
|
724775
|
+
exitCode: rr && !rr.completed ? 2 : 0
|
|
723785
724776
|
};
|
|
723786
724777
|
} catch (err) {
|
|
723787
724778
|
result = {
|
|
@@ -723805,7 +724796,14 @@ async function runJson(task, config, repoPath2) {
|
|
|
723805
724796
|
result.tool_calls = toolCallLog;
|
|
723806
724797
|
}
|
|
723807
724798
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
723808
|
-
if (result.exitCode !== 0) process.exit(
|
|
724799
|
+
if (result.exitCode !== 0) process.exit(result.exitCode);
|
|
724800
|
+
if (shouldForceJsonExit()) process.exit(0);
|
|
724801
|
+
}
|
|
724802
|
+
function shouldForceJsonExit() {
|
|
724803
|
+
if (process.env["OMNIUS_JSON_NO_FORCE_EXIT"] === "1") return false;
|
|
724804
|
+
if (process.env["VITEST"] === "true" || process.env["NODE_ENV"] === "test")
|
|
724805
|
+
return false;
|
|
724806
|
+
return true;
|
|
723809
724807
|
}
|
|
723810
724808
|
function extractSummary(captured) {
|
|
723811
724809
|
const all2 = captured.join("");
|
|
@@ -723844,7 +724842,7 @@ async function runBackground(task, config, opts) {
|
|
|
723844
724842
|
}
|
|
723845
724843
|
});
|
|
723846
724844
|
job.pid = child.pid ?? 0;
|
|
723847
|
-
|
|
724845
|
+
writeFileSync88(join175(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
723848
724846
|
let output = "";
|
|
723849
724847
|
child.stdout?.on("data", (chunk) => {
|
|
723850
724848
|
output += chunk.toString();
|
|
@@ -723860,7 +724858,7 @@ async function runBackground(task, config, opts) {
|
|
|
723860
724858
|
job.summary = result.summary;
|
|
723861
724859
|
job.durationMs = result.durationMs;
|
|
723862
724860
|
job.error = result.error;
|
|
723863
|
-
|
|
724861
|
+
writeFileSync88(join175(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
723864
724862
|
} catch {
|
|
723865
724863
|
}
|
|
723866
724864
|
});
|
|
@@ -724499,7 +725497,7 @@ __export(eval_exports, {
|
|
|
724499
725497
|
evalCommand: () => evalCommand
|
|
724500
725498
|
});
|
|
724501
725499
|
import { tmpdir as tmpdir23 } from "node:os";
|
|
724502
|
-
import { mkdirSync as mkdirSync105, writeFileSync as
|
|
725500
|
+
import { mkdirSync as mkdirSync105, writeFileSync as writeFileSync89 } from "node:fs";
|
|
724503
725501
|
import { join as join177 } from "node:path";
|
|
724504
725502
|
async function evalCommand(opts, config) {
|
|
724505
725503
|
const suiteName = opts.suite ?? "basic";
|
|
@@ -724631,7 +725629,7 @@ async function evalCommand(opts, config) {
|
|
|
724631
725629
|
function createTempEvalRepo() {
|
|
724632
725630
|
const dir = join177(tmpdir23(), `omnius-eval-${Date.now()}`);
|
|
724633
725631
|
mkdirSync105(dir, { recursive: true });
|
|
724634
|
-
|
|
725632
|
+
writeFileSync89(
|
|
724635
725633
|
join177(dir, "package.json"),
|
|
724636
725634
|
JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
|
|
724637
725635
|
"utf8"
|
|
@@ -724868,8 +725866,16 @@ function routeCommand(command) {
|
|
|
724868
725866
|
}
|
|
724869
725867
|
function parseCliArgs(argv) {
|
|
724870
725868
|
const args = argv.slice(2);
|
|
725869
|
+
const parseInput = [...args];
|
|
725870
|
+
const selfTestFlagIndex = parseInput.indexOf("--self-test");
|
|
725871
|
+
if (selfTestFlagIndex >= 0) {
|
|
725872
|
+
const next = parseInput[selfTestFlagIndex + 1];
|
|
725873
|
+
if (!next || next.startsWith("-")) {
|
|
725874
|
+
parseInput.splice(selfTestFlagIndex, 1, "--self-test=crossmodal");
|
|
725875
|
+
}
|
|
725876
|
+
}
|
|
724871
725877
|
const { values, positionals } = nodeParseArgs2({
|
|
724872
|
-
args,
|
|
725878
|
+
args: parseInput,
|
|
724873
725879
|
options: {
|
|
724874
725880
|
"dry-run": { type: "boolean" },
|
|
724875
725881
|
verbose: { type: "boolean", short: "v" },
|
|
@@ -724886,6 +725892,7 @@ function parseCliArgs(argv) {
|
|
|
724886
725892
|
live: { type: "boolean" },
|
|
724887
725893
|
json: { type: "boolean", short: "j" },
|
|
724888
725894
|
background: { type: "boolean" },
|
|
725895
|
+
"self-test": { type: "string" },
|
|
724889
725896
|
help: { type: "boolean", short: "h" },
|
|
724890
725897
|
version: { type: "boolean", short: "V" }
|
|
724891
725898
|
},
|
|
@@ -724908,6 +725915,7 @@ function parseCliArgs(argv) {
|
|
|
724908
725915
|
local: values.local === true,
|
|
724909
725916
|
json: values.json === true,
|
|
724910
725917
|
background: values.background === true,
|
|
725918
|
+
selfTest: typeof values["self-test"] === "string" ? values["self-test"] : void 0,
|
|
724911
725919
|
help: values.help === true,
|
|
724912
725920
|
version: values.version === true
|
|
724913
725921
|
};
|
|
@@ -725013,6 +726021,23 @@ Examples:
|
|
|
725013
726021
|
`.trim();
|
|
725014
726022
|
process.stdout.write(text2 + "\n");
|
|
725015
726023
|
}
|
|
726024
|
+
async function runSelfTest(mode) {
|
|
726025
|
+
if (mode !== "crossmodal") {
|
|
726026
|
+
throw new Error(`Unknown self-test mode: ${mode}`);
|
|
726027
|
+
}
|
|
726028
|
+
process.stdout.write("Running crossmodal smoke tests...\n");
|
|
726029
|
+
const { spawn: spawn35 } = await import("node:child_process");
|
|
726030
|
+
const run2 = (file) => new Promise((resolve71, reject) => {
|
|
726031
|
+
const p2 = spawn35(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
|
|
726032
|
+
p2.stdout.on("data", (d2) => process.stdout.write(d2));
|
|
726033
|
+
p2.stderr.on("data", (d2) => process.stdout.write(d2));
|
|
726034
|
+
onChildExit(p2, (code8) => code8 === 0 ? resolve71() : reject(new Error(`${file} exited ${code8}`)));
|
|
726035
|
+
});
|
|
726036
|
+
const base3 = process.cwd();
|
|
726037
|
+
await run2(`${base3}/eval/test-crossmodal.mjs`);
|
|
726038
|
+
await run2(`${base3}/eval/test-memory-search.mjs`);
|
|
726039
|
+
process.stdout.write("Self-test complete.\n");
|
|
726040
|
+
}
|
|
725016
726041
|
async function main() {
|
|
725017
726042
|
const version4 = getVersion5();
|
|
725018
726043
|
const parsed = parseCliArgs(process.argv);
|
|
@@ -725026,6 +726051,10 @@ async function main() {
|
|
|
725026
726051
|
printHelp2(version4);
|
|
725027
726052
|
return;
|
|
725028
726053
|
}
|
|
726054
|
+
if (parsed.selfTest) {
|
|
726055
|
+
await runSelfTest(parsed.selfTest);
|
|
726056
|
+
return;
|
|
726057
|
+
}
|
|
725029
726058
|
if (!parsed.json) {
|
|
725030
726059
|
const updateInfo = await checkForUpdate(version4);
|
|
725031
726060
|
if (updateInfo) {
|
|
@@ -725044,27 +726073,6 @@ async function main() {
|
|
|
725044
726073
|
});
|
|
725045
726074
|
try {
|
|
725046
726075
|
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
726076
|
case "run": {
|
|
725069
726077
|
const { runCommand: runCommand3 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
725070
726078
|
await runCommand3(
|