omnius 1.0.330 → 1.0.331
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 +95 -16
- package/docs/reference/rest-api.md +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -279078,7 +279078,7 @@ if __name__ == "__main__":
|
|
|
279078
279078
|
});
|
|
279079
279079
|
|
|
279080
279080
|
// packages/execution/dist/tools/media-store-migrate.js
|
|
279081
|
-
import { existsSync as existsSync41, readdirSync as readdirSync16, readFileSync as readFileSync30, statSync as statSync16, mkdirSync as mkdirSync22, copyFileSync, rmSync as rmSync5, statfsSync as statfsSync2 } from "node:fs";
|
|
279081
|
+
import { existsSync as existsSync41, readdirSync as readdirSync16, readFileSync as readFileSync30, statSync as statSync16, lstatSync, readlinkSync as readlinkSync2, symlinkSync, mkdirSync as mkdirSync22, copyFileSync, rmSync as rmSync5, statfsSync as statfsSync2 } from "node:fs";
|
|
279082
279082
|
import { join as join50, dirname as dirname13, extname as extname6, resolve as resolvePath } from "node:path";
|
|
279083
279083
|
function approxDirBytes(dir, budget = { nodes: 2e5 }) {
|
|
279084
279084
|
let total = 0;
|
|
@@ -279209,19 +279209,41 @@ function freeBytesAt(path12) {
|
|
|
279209
279209
|
return Number.MAX_SAFE_INTEGER;
|
|
279210
279210
|
}
|
|
279211
279211
|
}
|
|
279212
|
+
function treeSizeNoFollow(dir) {
|
|
279213
|
+
let entries;
|
|
279214
|
+
try {
|
|
279215
|
+
entries = readdirSync16(dir, { withFileTypes: true });
|
|
279216
|
+
} catch {
|
|
279217
|
+
return 0;
|
|
279218
|
+
}
|
|
279219
|
+
let total = 0;
|
|
279220
|
+
for (const ent of entries) {
|
|
279221
|
+
const p2 = join50(dir, ent.name);
|
|
279222
|
+
try {
|
|
279223
|
+
if (ent.isSymbolicLink())
|
|
279224
|
+
total += lstatSync(p2).size;
|
|
279225
|
+
else if (ent.isDirectory())
|
|
279226
|
+
total += treeSizeNoFollow(p2);
|
|
279227
|
+
else if (ent.isFile())
|
|
279228
|
+
total += statSync16(p2).size;
|
|
279229
|
+
} catch {
|
|
279230
|
+
}
|
|
279231
|
+
}
|
|
279232
|
+
return total;
|
|
279233
|
+
}
|
|
279212
279234
|
function copyDirWithProgress(src2, dst, onFile) {
|
|
279213
279235
|
mkdirSync22(dst, { recursive: true });
|
|
279214
279236
|
for (const ent of readdirSync16(src2, { withFileTypes: true })) {
|
|
279215
279237
|
const s2 = join50(src2, ent.name);
|
|
279216
279238
|
const d2 = join50(dst, ent.name);
|
|
279217
|
-
if (ent.
|
|
279218
|
-
copyDirWithProgress(s2, d2, onFile);
|
|
279219
|
-
} else if (ent.isSymbolicLink()) {
|
|
279239
|
+
if (ent.isSymbolicLink()) {
|
|
279220
279240
|
try {
|
|
279221
|
-
|
|
279222
|
-
onFile(
|
|
279241
|
+
symlinkSync(readlinkSync2(s2), d2);
|
|
279242
|
+
onFile(lstatSync(d2).size, s2);
|
|
279223
279243
|
} catch {
|
|
279224
279244
|
}
|
|
279245
|
+
} else if (ent.isDirectory()) {
|
|
279246
|
+
copyDirWithProgress(s2, d2, onFile);
|
|
279225
279247
|
} else if (ent.isFile()) {
|
|
279226
279248
|
copyFileSync(s2, d2);
|
|
279227
279249
|
let size = 0;
|
|
@@ -279257,7 +279279,7 @@ function relocateMediaStore(args) {
|
|
|
279257
279279
|
if (!dryRun && existsSync41(dst) && readdirSync16(dst).length > 0) {
|
|
279258
279280
|
throw new Error(`Destination already has a non-empty "${name10}" folder: ${dst}. Choose an empty/new folder.`);
|
|
279259
279281
|
}
|
|
279260
|
-
const bytes =
|
|
279282
|
+
const bytes = treeSizeNoFollow(src2);
|
|
279261
279283
|
present.push({ name: name10, src: src2, dst, bytes });
|
|
279262
279284
|
bytesTotal += bytes;
|
|
279263
279285
|
}
|
|
@@ -279289,8 +279311,8 @@ function relocateMediaStore(args) {
|
|
|
279289
279311
|
emit2({ stage: "copy", bytesDone, bytesTotal, currentPath });
|
|
279290
279312
|
});
|
|
279291
279313
|
emit2({ stage: "verify", bytesDone, bytesTotal, message: `Verifying ${sub2.name}…` });
|
|
279292
|
-
const copied =
|
|
279293
|
-
if (copied < sub2.bytes * 0.
|
|
279314
|
+
const copied = treeSizeNoFollow(sub2.dst);
|
|
279315
|
+
if (copied < sub2.bytes * 0.95) {
|
|
279294
279316
|
throw new Error(`Verification failed for "${sub2.name}" (${formatBytes3(copied)} of ${formatBytes3(sub2.bytes)} copied). Source left intact at ${sub2.src}.`);
|
|
279295
279317
|
}
|
|
279296
279318
|
}
|
|
@@ -279320,9 +279342,15 @@ async function copyDirWithProgressAsync(src2, dst, onFile) {
|
|
|
279320
279342
|
for (const ent of entries) {
|
|
279321
279343
|
const s2 = join50(src2, ent.name);
|
|
279322
279344
|
const d2 = join50(dst, ent.name);
|
|
279323
|
-
if (ent.
|
|
279345
|
+
if (ent.isSymbolicLink()) {
|
|
279346
|
+
try {
|
|
279347
|
+
await fsp2.symlink(await fsp2.readlink(s2), d2);
|
|
279348
|
+
onFile((await fsp2.lstat(d2)).size, s2);
|
|
279349
|
+
} catch {
|
|
279350
|
+
}
|
|
279351
|
+
} else if (ent.isDirectory()) {
|
|
279324
279352
|
await copyDirWithProgressAsync(s2, d2, onFile);
|
|
279325
|
-
} else if (ent.isFile()
|
|
279353
|
+
} else if (ent.isFile()) {
|
|
279326
279354
|
try {
|
|
279327
279355
|
await fsp2.copyFile(s2, d2);
|
|
279328
279356
|
let size = 0;
|
|
@@ -279364,7 +279392,7 @@ async function relocateMediaStoreAsync(args) {
|
|
|
279364
279392
|
if (!dryRun && existsSync41(dst) && readdirSync16(dst).length > 0) {
|
|
279365
279393
|
throw new Error(`Destination already has a non-empty "${name10}" folder: ${dst}. Choose an empty/new folder.`);
|
|
279366
279394
|
}
|
|
279367
|
-
const bytes =
|
|
279395
|
+
const bytes = treeSizeNoFollow(src2);
|
|
279368
279396
|
present.push({ name: name10, src: src2, dst, bytes });
|
|
279369
279397
|
bytesTotal += bytes;
|
|
279370
279398
|
}
|
|
@@ -279389,7 +279417,7 @@ async function relocateMediaStoreAsync(args) {
|
|
|
279389
279417
|
emit2({ stage: "copy", bytesDone, bytesTotal, currentPath });
|
|
279390
279418
|
});
|
|
279391
279419
|
emit2({ stage: "verify", bytesDone, bytesTotal, message: `Verifying ${sub2.name}…` });
|
|
279392
|
-
if (
|
|
279420
|
+
if (treeSizeNoFollow(sub2.dst) < sub2.bytes * 0.95) {
|
|
279393
279421
|
throw new Error(`Verification failed for "${sub2.name}". Source left intact at ${sub2.src}.`);
|
|
279394
279422
|
}
|
|
279395
279423
|
}
|
|
@@ -630946,7 +630974,7 @@ import {
|
|
|
630946
630974
|
writeFileSync as writeFileSync66,
|
|
630947
630975
|
mkdirSync as mkdirSync76,
|
|
630948
630976
|
readdirSync as readdirSync44,
|
|
630949
|
-
lstatSync,
|
|
630977
|
+
lstatSync as lstatSync2,
|
|
630950
630978
|
statSync as statSync48,
|
|
630951
630979
|
rmSync as rmSync10,
|
|
630952
630980
|
appendFileSync as appendFileSync12,
|
|
@@ -639402,7 +639430,7 @@ function cacheCandidatePaths(root, model) {
|
|
|
639402
639430
|
}
|
|
639403
639431
|
function directorySizeBytes2(path12, seen = /* @__PURE__ */ new Set()) {
|
|
639404
639432
|
try {
|
|
639405
|
-
const stat8 =
|
|
639433
|
+
const stat8 = lstatSync2(path12);
|
|
639406
639434
|
if (stat8.isSymbolicLink()) return 0;
|
|
639407
639435
|
if (stat8.isFile()) return stat8.size;
|
|
639408
639436
|
if (!stat8.isDirectory()) return 0;
|
|
@@ -681018,6 +681046,54 @@ function handleRelocateStatus(ctx3) {
|
|
|
681018
681046
|
});
|
|
681019
681047
|
return true;
|
|
681020
681048
|
}
|
|
681049
|
+
async function handleAvAnalyze(ctx3) {
|
|
681050
|
+
if (!requireRunScope(ctx3, "AV analysis")) return true;
|
|
681051
|
+
const body = await parseJsonBodyStrict(ctx3.req).catch(() => null);
|
|
681052
|
+
const raw = body?.path || body?.mediaUri;
|
|
681053
|
+
if (!raw) {
|
|
681054
|
+
sendProblem(ctx3.res, problemDetails({ type: P.invalidRequest, status: 400, title: "Missing media path", detail: "POST body must include {path} or {mediaUri}", instance: ctx3.requestId }));
|
|
681055
|
+
return true;
|
|
681056
|
+
}
|
|
681057
|
+
const filePath = raw.startsWith("file://") ? raw.slice(7) : raw;
|
|
681058
|
+
if (!existsSync149(filePath)) {
|
|
681059
|
+
sendProblem(ctx3.res, problemDetails({ type: P.notFound, status: 404, title: "Media not found", detail: filePath, instance: ctx3.requestId }));
|
|
681060
|
+
return true;
|
|
681061
|
+
}
|
|
681062
|
+
try {
|
|
681063
|
+
const registry4 = buildRegistry();
|
|
681064
|
+
const adapterStatus = {};
|
|
681065
|
+
let anyLive = false;
|
|
681066
|
+
for (const role of AV_ROLES) {
|
|
681067
|
+
const a2 = await registry4.selectForRole(role);
|
|
681068
|
+
adapterStatus[role] = a2 && !a2.meta.isMock ? "live" : "mock";
|
|
681069
|
+
if (adapterStatus[role] === "live") anyLive = true;
|
|
681070
|
+
}
|
|
681071
|
+
const episodeId = `rest-${basename37(filePath)}-${Date.now().toString(36)}`;
|
|
681072
|
+
const ingest = await ingestMedia(episodeId, `file://${filePath}`);
|
|
681073
|
+
const store2 = await analyzeEpisode({ episodeId, mediaUri: `file://${filePath}`, durationSec: ingest.source.durationSec, registry: registry4, windows: ingest.shots, roles: AV_ROLES });
|
|
681074
|
+
const world = store2.snapshot();
|
|
681075
|
+
const answer = composeAnswer(world, body?.question ?? "");
|
|
681076
|
+
const cap = getMediaCapability();
|
|
681077
|
+
sendJson2(ctx3.res, 200, {
|
|
681078
|
+
data: {
|
|
681079
|
+
episodeId,
|
|
681080
|
+
source: ingest.source,
|
|
681081
|
+
shots: ingest.shots,
|
|
681082
|
+
stack: cap.stack,
|
|
681083
|
+
adapters: adapterStatus,
|
|
681084
|
+
modelsLive: anyLive,
|
|
681085
|
+
note: anyLive ? void 0 : "No live AV models loaded yet — entity/event results are scaffold placeholders from mock adapters. They become real once the sidecar models finish downloading.",
|
|
681086
|
+
entities: world.entities,
|
|
681087
|
+
events: world.events,
|
|
681088
|
+
relations: world.relations,
|
|
681089
|
+
answer
|
|
681090
|
+
}
|
|
681091
|
+
});
|
|
681092
|
+
} catch (err) {
|
|
681093
|
+
sendProblem(ctx3.res, problemDetails({ type: P.internalError, status: 500, title: "AV analysis error", detail: err instanceof Error ? err.message : String(err), instance: ctx3.requestId }));
|
|
681094
|
+
}
|
|
681095
|
+
return true;
|
|
681096
|
+
}
|
|
681021
681097
|
async function runGeneration(ctx3, kind, buildTool, buildArgs) {
|
|
681022
681098
|
if (!requireRunScope(ctx3, `${kind} generation`)) return true;
|
|
681023
681099
|
const body = await parseJsonBodyStrict(ctx3.req).catch(() => null);
|
|
@@ -681187,6 +681263,7 @@ async function tryRouteMedia(ctx3) {
|
|
|
681187
681263
|
if (!pathname.startsWith("/v1/media")) return false;
|
|
681188
681264
|
if (pathname === "/v1/media/models" && method === "GET") return handleListModels(ctx3);
|
|
681189
681265
|
if (pathname === "/v1/media/store" && method === "GET") return handleStoreInfo(ctx3);
|
|
681266
|
+
if (pathname === "/v1/media/av/analyze" && method === "POST") return handleAvAnalyze(ctx3);
|
|
681190
681267
|
if (pathname === "/v1/media/migrate" && method === "POST") return handleMigrate(ctx3);
|
|
681191
681268
|
if (pathname === "/v1/media/relocate" && method === "POST") return handleRelocate(ctx3);
|
|
681192
681269
|
if (pathname === "/v1/media/relocate/status" && method === "GET") return handleRelocateStatus(ctx3);
|
|
@@ -681265,7 +681342,7 @@ async function tryRouteMedia(ctx3) {
|
|
|
681265
681342
|
}
|
|
681266
681343
|
return false;
|
|
681267
681344
|
}
|
|
681268
|
-
var PROBLEM_BASE, P, MIME_BY_EXT, _relocateJob;
|
|
681345
|
+
var PROBLEM_BASE, P, MIME_BY_EXT, _relocateJob, AV_ROLES;
|
|
681269
681346
|
var init_routes_media = __esm({
|
|
681270
681347
|
"packages/cli/src/api/routes-media.ts"() {
|
|
681271
681348
|
"use strict";
|
|
@@ -681296,6 +681373,7 @@ var init_routes_media = __esm({
|
|
|
681296
681373
|
".m4a": "audio/mp4"
|
|
681297
681374
|
};
|
|
681298
681375
|
_relocateJob = null;
|
|
681376
|
+
AV_ROLES = ["video_temporal", "grounding", "tracking", "audio_event", "cross_modal"];
|
|
681299
681377
|
}
|
|
681300
681378
|
});
|
|
681301
681379
|
|
|
@@ -696502,6 +696580,7 @@ function getOpenApiSpec() {
|
|
|
696502
696580
|
"/v1/media/migrate": { post: { summary: "Dedup + migrate legacy per-group media caches into the unified store — body {dryRun?, roots?, maxDepth?}", tags: ["Media"], responses: { 200: { description: "Migration report (bytes reclaimed/migrated)" }, 403: { description: "Insufficient scope" } } } },
|
|
696503
696581
|
"/v1/media/relocate": { post: { summary: "Relocate the whole media store (weights/venvs/gallery) to a chosen folder — body {newRoot, dryRun?}; streams media.relocate_progress and returns 202 + job_id", tags: ["Media"], responses: { 200: { description: "Dry-run plan" }, 202: { description: "Relocation started" }, 400: { description: "Missing newRoot" }, 409: { description: "Relocation already running" } } } },
|
|
696504
696582
|
"/v1/media/relocate/status": { get: { summary: "Status of the in-flight (or last) media-store relocation job", tags: ["Media"], responses: { 200: { description: "Relocation job status + progress" } } } },
|
|
696583
|
+
"/v1/media/av/analyze": { post: { summary: "Analyze a media file into a grounded entity/event/evidence answer (AV entity-comprehension) — body {path|mediaUri, question?}; reports per-role live-vs-mock adapter status", tags: ["Media"], responses: { 200: { description: "Grounded answer + entity/event graph" }, 400: { description: "Missing media path" }, 404: { description: "Media not found" } } } },
|
|
696505
696584
|
"/v1/media/image": { post: { summary: "Generate an image — body {prompt, model?, backend?, width?, height?, steps?, guidance?, seed?, aspect_ratio?}", tags: ["Media"], responses: { 200: { description: "Generated image path + gallery URL" }, 400: { description: "Missing prompt" }, 403: { description: "Insufficient scope" }, 502: { description: "Generation failed" } } } },
|
|
696506
696585
|
"/v1/media/video": { post: { summary: "Generate a video — body {prompt, model?, backend?, num_frames?, fps?, width?, height?, steps?, guidance?, seed?}", tags: ["Media"], responses: { 200: { description: "Generated video path + gallery URL" }, 400: { description: "Missing prompt" }, 403: { description: "Insufficient scope" }, 502: { description: "Generation failed" } } } },
|
|
696507
696586
|
"/v1/media/audio": { post: { summary: "Generate a sound effect — body {prompt, model?, backend?, duration?, seed?}", tags: ["Media"], responses: { 200: { description: "Generated audio path + gallery URL" }, 400: { description: "Missing prompt" }, 403: { description: "Insufficient scope" }, 502: { description: "Generation failed" } } } },
|
|
@@ -201,6 +201,7 @@ All generation is backed by the unified `~/.omnius` model store and shared venvs
|
|
|
201
201
|
| `POST` | `/v1/media/migrate` | Dedup + migrate legacy per-group caches into the unified store |
|
|
202
202
|
| `POST` | `/v1/media/relocate` | Relocate the whole media store (weights/venvs/gallery) to a chosen folder |
|
|
203
203
|
| `GET` | `/v1/media/relocate/status` | Status + progress of the media-store relocation job |
|
|
204
|
+
| `POST` | `/v1/media/av/analyze` | Analyze a media file into a grounded entity/event answer (AV comprehension) |
|
|
204
205
|
| `POST` | `/v1/media/image` | Generate an image |
|
|
205
206
|
| `POST` | `/v1/media/video` | Generate a video |
|
|
206
207
|
| `POST` | `/v1/media/audio` | Generate a sound effect |
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.331",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.331",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED