mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-13 18:32:12 +03:00
MaxAI joins as a first-class signed provider: 13 chat models discovered live from /models/get_config plus 6 image models, routed through the standard /v1 endpoints with per-request X-Authorization signing, browserless onboarding, prompted tool-calling, vision input, image generation and document RAG. Reconciled on merge — worth reading, because the branch forked 227 commits back and 77 files conflicted. Only five carried MaxAI content; the rest was drift from the older release line and took the tip's side, taking the diff from 113 files to 37 (then 93 as counted against the current base). - executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so MaxAI is registered in that shape rather than the branch's static import. - imageRegistry.ts: kept only the maxai block. The branch still carried microsoft-designer-web, which #11754 retired. - models/route.ts: the conflicting hunk was an unrelated Vertex/Anthropic URL change, not MaxAI — tip's side. - volcengine agent-plan/coding-plan registries: git auto-merged both sides and produced a duplicated supportsVision key, which TypeScript rejects (TS1117). Removed. One real integration break that only the combined state shows: the MaxAI entry declared no serviceKinds, which #11392 made required a few hours ago. Provider validation threw at load time and check:provider-consistency crashed outright. Declared ["llm"] — the image kinds derive from imageRegistry, per the convention in that PR's backfill. Every count was measured rather than taken from the branch, and each would have been wrong: reserved prefixes are 402, not the 397 the branch computed from its stale 395 base; providers are 353, not 354. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in those files is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines, identical). The executor-map golden snapshot was regenerated: keyCount 133 -> 134. The branch's file-size-baseline.json predates #12411's ratchet re-tightening, so it was discarded rather than merged — taking it would have silently undone that. The three files this PR grows (proxyFetch.ts +20 for the Windows/firefox_150 TLS profile, imageGeneration.ts +12, models/route.ts +48) were entered against the current baseline under one _rebaseline annotation; no other cap moves. Verified: typecheck:core clean, check:provider-consistency OK (269 REGISTRY entries, 353 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, and 79/79 across the MaxAI suites plus 21/21 reserved-prefix and 2/2 executor-map-golden. Thanks @arminanton — the provider work itself is thorough; it was the 227 commits of base that needed the attention.
85 lines
2.6 KiB
JavaScript
85 lines
2.6 KiB
JavaScript
#!/usr/bin/env node
|
|
import { readFile, readdir, stat } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const repoRoot = fileURLToPath(new URL("../..", import.meta.url));
|
|
const providerDir = join(repoRoot, "public", "providers");
|
|
const MAX_RASTER_BYTES = 128 * 1024;
|
|
const MAX_RASTER_DIMENSION = 512;
|
|
const RASTER_EXTENSIONS = new Set([".png", ".jpg", ".jpeg"]);
|
|
|
|
function extensionOf(fileName) {
|
|
const dot = fileName.lastIndexOf(".");
|
|
return dot >= 0 ? fileName.slice(dot).toLowerCase() : "";
|
|
}
|
|
|
|
function readPngDimensions(buffer) {
|
|
if (buffer.length < 24 || buffer.toString("ascii", 1, 4) !== "PNG") return null;
|
|
return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20) };
|
|
}
|
|
|
|
function readJpegDimensions(buffer) {
|
|
let offset = 2;
|
|
while (offset + 9 < buffer.length) {
|
|
if (buffer[offset] !== 0xff) return null;
|
|
const marker = buffer[offset + 1];
|
|
const length = buffer.readUInt16BE(offset + 2);
|
|
if (marker >= 0xc0 && marker <= 0xc3) {
|
|
return { height: buffer.readUInt16BE(offset + 5), width: buffer.readUInt16BE(offset + 7) };
|
|
}
|
|
offset += 2 + length;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function readDimensions(filePath, extension) {
|
|
const buffer = await readFile(filePath);
|
|
if (buffer.length >= 4 && buffer.toString("ascii", 1, 4) === "PNG") {
|
|
return readPngDimensions(buffer);
|
|
}
|
|
if (buffer.length >= 2 && buffer[0] === 0xff && buffer[1] === 0xd8) {
|
|
return readJpegDimensions(buffer);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const failures = [];
|
|
const files = await readdir(providerDir);
|
|
|
|
for (const fileName of files) {
|
|
const extension = extensionOf(fileName);
|
|
if (!RASTER_EXTENSIONS.has(extension)) continue;
|
|
|
|
const filePath = join(providerDir, fileName);
|
|
const info = await stat(filePath);
|
|
const dimensions = await readDimensions(filePath, extension);
|
|
if (!dimensions) {
|
|
if (info.size > 4 * 1024) {
|
|
failures.push(`${fileName}: could not read image dimensions`);
|
|
}
|
|
continue;
|
|
}
|
|
const width = dimensions.width || 0;
|
|
const height = dimensions.height || 0;
|
|
|
|
if (info.size > MAX_RASTER_BYTES) {
|
|
failures.push(
|
|
`${fileName}: ${(info.size / 1024).toFixed(1)} KiB exceeds ${MAX_RASTER_BYTES / 1024} KiB`
|
|
);
|
|
}
|
|
if (width > MAX_RASTER_DIMENSION || height > MAX_RASTER_DIMENSION) {
|
|
failures.push(
|
|
`${fileName}: ${width}x${height} exceeds ${MAX_RASTER_DIMENSION}px max dimension`
|
|
);
|
|
}
|
|
}
|
|
|
|
if (failures.length > 0) {
|
|
console.error("Provider asset budget failed:");
|
|
for (const failure of failures) console.error(`- ${failure}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log("Provider asset budget passed.");
|