mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-14 10:52:17 +03:00
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host. Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean. Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import test from "node:test";
|
|
|
|
const REPO_ROOT = join(import.meta.dirname, "..", "..");
|
|
|
|
/**
|
|
* Regression guards for the CodeQL alerts triaged on 2026-08-12.
|
|
*
|
|
* Both are source-level invariants rather than behavioral round-trips: the functions they
|
|
* protect are module-private (`decodeXmlText`) or only reachable through a live upstream
|
|
* handshake (`tinycms` nonce), so the guard asserts the property on the source itself.
|
|
*/
|
|
|
|
test("decodeXmlText decodes & last so encoded entities do not double-unescape", () => {
|
|
const source = readFileSync(
|
|
join(REPO_ROOT, "open-sse/vendor/codex-chatgpt-web/adapters/chatgpt-web/environment.ts"),
|
|
"utf8"
|
|
);
|
|
const body = /function decodeXmlText\(value: string\): string \{([\s\S]*?)\n\}/.exec(source)?.[1];
|
|
assert.ok(body, "decodeXmlText not found — update this guard if the helper was renamed");
|
|
|
|
const order = [...body.matchAll(/replaceAll\("(&[^"]+;)"/g)].map((match) => match[1]);
|
|
assert.ok(order.length >= 2, `expected several entity replacements, got ${order.length}`);
|
|
assert.equal(
|
|
order.at(-1),
|
|
"&",
|
|
`"&" must be the LAST entity decoded, otherwise """ decodes to '"' instead ` +
|
|
`of the literal """. Current order: ${order.join(" -> ")}`
|
|
);
|
|
|
|
// Mirror the implementation to document the property the ordering buys us.
|
|
const decode = (value: string) =>
|
|
order.reduce((acc, entity) => {
|
|
const plain = { "<": "<", ">": ">", """: '"', "'": "'", "&": "&" }[entity];
|
|
return plain === undefined ? acc : acc.replaceAll(entity, plain);
|
|
}, value);
|
|
assert.equal(decode("&quot;"), """);
|
|
assert.equal(decode("&#39;"), "'");
|
|
assert.equal(decode("&lt;"), "<");
|
|
});
|
|
|
|
test("tinycms signs its anti-replay nonce with a CSPRNG, never Math.random", () => {
|
|
const source = readFileSync(join(REPO_ROOT, "open-sse/executors/tinycms.ts"), "utf8");
|
|
|
|
assert.match(
|
|
source,
|
|
/const nonceJs = randomUUID\(\)/,
|
|
"the tinycms nonce must come from node:crypto randomUUID"
|
|
);
|
|
assert.doesNotMatch(
|
|
source,
|
|
/Math\.random\(\)/,
|
|
"Math.random() is not a CSPRNG — the nonce is signed into the anti-replay payload"
|
|
);
|
|
});
|