Files
OmniRoute/tests/unit/feature-flags-route-virtual-lanes.test.ts
Brandon Bennett 6615a5445b feat: combo-lane awareness + activation UX + MCP visibility (Wave 2 of #9654) (#10039)
* feat(admission): per-target lane-aware probes for combo/fusion fan-out (#9654 Wave 2)

Combo and fusion fan out N targets without ever consulting the adaptive-admission
layer: the parent request holds one lease, but each fan-out target is dispatched
unconditionally. With virtual lanes enabled (OMNIROUTE_CHAT_VIRTUAL_LANES=1), a
connection whose lane queue is full now SKIPS additional fan-out targets instead
of piling more queued work onto an already-congested session.

Adds PerTargetAdmissionHook (admission/types.ts) + createPerTargetAdmissionHook
factory (chatAdmission.ts): strictly non-blocking (maxWaitMs 0 - skip, never
queue), a no-op when virtual lanes are off, keyed to the parent tenantKey, and
release-on-admit so the probe is a capacity gate, not a hold.

Threaded through every parallel fan-out path:
- priority/weighted executeTarget + round-robin skip chains (combo.ts)
- fusion panel before fan-out (fusion.ts), judge fallback prefers survivors
- chaos parallel panel (autoCombo/chaosEngine.ts)
- tryFusionDispatch / tryRuntimeUnitDispatch / buildBaseOptions (dispatchPrelude.ts)
- chat.ts primary + safety-net redirect call sites

Snapshot exposes virtualLanes so the no-op gate is cheap and honest.

Tests: tests/unit/combo-lane-awareness-9654.test.ts (10 tests) - factory
semantics, priority/RR skip, fusion panel drop + all-skipped 503, no-hook
backward-compat baseline.

* feat(flags): activation UX - env-wins adaptive virtual-lanes flag + env docs (#9654 Wave 2)

U7: make adaptive virtual admission lanes discoverable + activatable.
- New OMNIROUTE_CHAT_VIRTUAL_LANES feature flag (boolean/runtime/requiresRestart) in featureFlagDefinitions + en.json i18n key.
- lib/admissionVirtualLanes.ts: env-wins resolver (env > DB > default) + boot warm folding a DB-sourced override into the process-global runtime env via reloadAdaptiveAdmissionRuntime(options.env) - no process.env mutation, no open-sse changes. Env still wins; DB toggle gates at next boot.
- GET /api/settings/feature-flags special-cases the flag to report the gate true source (ccDiscoveryAliases precedent); flagPayload helper dedupes the payload shape.
- Wire the warm into instrumentation-node registerNodejs (non-fatal, DB-ready).
- Document the master switch in .env.example + ENVIRONMENT.md with the system-1/system-2 distinction; zero new env-doc-sync drift.
- 11 new tests (resolver precedence + warm); 60/60 across feature-flag suites; typecheck core clean; ESLint + doc gates green.

* feat(mcp): surface adaptive admission lane data in omniroute_get_health (#9654 Wave 2)

U8: make adaptive virtual-lane admission visible to agents via the MCP health tool. handleGetHealth now surfaces a curated adaptiveAdmission block from the health payload (which already carried the runtime snapshot but was dropping it): virtualLanes/pressure/utilization/laneCount/laneQueuedCount/laneQueuedCost, laneTenants capped at top-10 by queued cost, admitted/rejected/wouldReject counts, shutdown. Block omitted entirely when the health endpoint reports none.

isLaneFlagOn mirrors the runtime 1|true convention so a string serialization can never invert a boolean lane report. getHealthOutput schema extended with the matching optional shape; tool description updated.

4 new dispatch tests (full block, top-10 cap/order, omission, defensive coercion of string flags + malformed lane entries) - 22/22 in essentialTools.test.ts. README: Adaptive Admission Lane Data table + Skills & Tool Navigability audit (29/43 schema entries covered, 14 undocumented, tool_search keyword runtime discovery, full catalog in docs/frameworks/MCP-SERVER.md).

No new lint errors (4 pre-existing in server.ts), typecheck core clean, doc counts + fabricated-docs gates green.

* docs: add changelog entry for #9654 Wave 2 (#10039)

* fix(codeql): suppress js/insufficient-password-hash false positive in lane-key fingerprinting (#10039)

resolveSessionId sha256-hashes bearer/x-api-key/x-goog-api-key to derive a deterministic, non-reversible per-key lane-bucket ID for virtual admission lanes (#9654). This is not password storage or verification, so the rule is a false positive; suppress it inline (same house style as src/lib/sync/tokens.ts) to clear the codeqlAlerts ratchet (2 > baseline 1) that blocks #10039 and every PR against release/v3.8.50.

* docs(mcp): complete MCP server README tool reference (#10039)

The MCP server README covered only 29 of the 43 schema entries, listing the
remaining tools solely as a gap note with omniroute_tool_search as the runtime
fallback. Add tool-reference tables for the agent-skills trio, oneproxy trio,
web_fetch/web_search, tool_search, create_combo, set_routing_strategy,
pick_fastest_model, sync_pricing, and db_health_check so the README covers the
full schemas catalog, and fold the coverage note into the tool_search discovery
paragraph.

* fix(chat): drop unused correlationId from safety-net combo redirect (#10039)

handleComboChat's HandleComboChatOptions has no correlationId member and
the combo pipeline never consumes it; the property was copied from the
handleSingleModelChat options shape by accident and introduced a new
TS2353 under the open-sse workspace typecheck gate.

* fix(i18n): translate featureFlagChatVirtualLanesEnabledDescription into 42 locales (#10039)

en.json gained the flag description in this PR but the locale catalogs
were never mirrored, failing the pt-BR key-parity (#6695) and vi
completeness gates. Adds a real translation to every locale, keeping the
zh-CN/zh-TW glossary canonical terms (提供者/儀表板) and no ICU drift.

* chore(quality): ratchet open-sse-typecheck baseline down (#10039)

The Wave 2 admission refactor removed 66 baselined open-sse type errors;
re-freeze the baseline so the gate pins the new, tighter state.

* docs: resync provider reference to 341 and CLI tools to 34

The release branch gained an 11th no-auth provider (freeaiapikey registry
resync, #10233) and a 26th CLI Code tool without regenerating the
auto-generated docs, leaving every PR against release/v3.8.50 failing the
Docs Gates strict validator (code 341 vs doc 340, CLI 34 vs "33 tools").

Regenerate docs/reference/PROVIDER_REFERENCE.md and sync the provider/tool
counts across README.md, AGENTS.md, llm.txt plus 42 i18n mirrors,
package.json description, and the four diagram SVGs.

* fix(tests): align count expectations with live catalogs (pre-existing release drift)

Release/v3.8.50 currently fails five gates on its own tree; this PR inherits
them. Fix the stale expectations to match live code:

- feature-flags-settings: 48 -> 49 flags (Wave 2 adds OMNIROUTE_CHAT_VIRTUAL_LANES)
- cli-tools-schema / cli-catalog-counts: 33 -> 34 tools (zcode added; 26 code = 21 visible + 5 none)
- optional-transformers-dependency: onnxruntime-node ~1.24.3 -> ~1.27.0 (bump #10382)
- stryker.conf.json: register chatcore-header-drop-warn-dedupe-10315 test
- check-public-creds: freeze zcodeProtocol clientId false positive (client identifier, not a credential)

* fix(tests): follow release's onnxruntime-node revert to ~1.24.3

release/v3.8.50's #10543 pinned onnxruntime-node back to ~1.24.3 after
#10403's ~1.27.0 bump caused npm to nest a second native copy under
@huggingface/transformers and broke the Docker SONAME contract. This
PR's own drift-alignment commit (57b9c033) predates that revert and
still expected ~1.27.0; the 3-way merge did not flag it as a textual
conflict since only one side touched this exact line, but the merged
tree became internally inconsistent (package.json ~1.24.3 vs test
expecting ~1.27.0). Align the test with the now-canonical release
value.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(quality): dedupe stryker.conf.json chatcore-header-drop-warn-dedupe entry

The 3-way merge applied both sides' insertion of the same test-file entry
at different positions, producing a duplicate with broken indentation.
Adopted release's clean version of the file.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: Brandon Bennett <brandonbennett@macbookair.myfiosgateway.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Brandon Bennett <branben@users.noreply.github.com>
2026-08-18 11:31:46 -03:00

128 lines
4.7 KiB
TypeScript

/**
* U7 (#9654 Wave 2) — route-level acceptance for the adaptive virtual-lanes flag.
*
* Ticket acceptance: "flag appears in GET /api/settings/feature-flags; env
* still wins." Exercises the GET + PUT handlers directly (JWT cookie auth),
* asserting the env-wins source reporting and the requiresRestart surface.
*
* Run: bun test tests/unit/feature-flags-route-virtual-lanes.test.ts
*/
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import test, { after, before } from "node:test";
import { SignJWT } from "jose";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-ff-vl-route-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const { GET, PUT } = await import("../../src/app/api/settings/feature-flags/route.ts");
const { removeFeatureFlagOverride, setFeatureFlagOverride } =
await import("../../src/lib/db/featureFlags");
const { ADAPTIVE_VIRTUAL_LANES_FLAG_KEY } = await import("../../src/lib/admissionVirtualLanes.ts");
const ORIGINAL_ENV_VALUE = process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
type FlagPayload = {
key: string;
label: string;
type: string;
defaultValue: string;
effectiveValue: string;
source: string;
requiresRestart: boolean;
};
async function authCookie(): Promise<string> {
process.env.JWT_SECRET = "test-feature-flags-route-secret";
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
const token = await new SignJWT({ sub: "test-user" })
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("1h")
.sign(secret);
return `auth_token=${token}`;
}
async function buildGetRequest(): Promise<Request> {
const cookie = await authCookie();
return new Request("http://localhost/api/settings/feature-flags", {
headers: { cookie },
});
}
async function buildPutRequest(value: string): Promise<Request> {
const cookie = await authCookie();
return new Request("http://localhost/api/settings/feature-flags", {
method: "PUT",
headers: { cookie, "Content-Type": "application/json" },
body: JSON.stringify({ key: ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, value }),
});
}
async function getFlag(): Promise<FlagPayload> {
const res = await GET(await buildGetRequest());
assert.equal(res.status, 200);
const json = (await res.json()) as { flags: FlagPayload[] };
const flag = json.flags.find((f) => f.key === ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
assert.ok(flag, `flag ${ADAPTIVE_VIRTUAL_LANES_FLAG_KEY} must appear in GET`);
return flag;
}
before(() => {
removeFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
});
after(() => {
if (ORIGINAL_ENV_VALUE === undefined) {
delete process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
} else {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = ORIGINAL_ENV_VALUE;
}
removeFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
});
test("flag appears in GET with the requiresRestart boolean surface (default off)", async () => {
delete process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
const flag = await getFlag();
assert.equal(flag.type, "boolean");
assert.equal(flag.defaultValue, "false");
assert.equal(flag.requiresRestart, true, "runtime reads env at construction — restart required");
assert.equal(flag.effectiveValue, "false");
assert.equal(flag.source, "default");
});
test('env wins over a DB override in GET (env "1" + DB false -> env)', async () => {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = "1";
setFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, "false");
const flag = await getFlag();
assert.equal(flag.effectiveValue, "true");
assert.equal(flag.source, "env");
});
test('env explicit off still wins in GET (env "0" + DB true -> env off)', async () => {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = "0";
setFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, "true");
const flag = await getFlag();
assert.equal(flag.effectiveValue, "false");
assert.equal(flag.source, "env");
});
test("DB override enables when env is absent (source db)", async () => {
delete process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
setFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, "true");
const flag = await getFlag();
assert.equal(flag.effectiveValue, "true");
assert.equal(flag.source, "db");
});
test("PUT response reports env-wins truth when env is set (operator toggle cannot lie)", async () => {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = "0";
const res = await PUT(await buildPutRequest("true"));
assert.equal(res.status, 200);
const json = (await res.json()) as { effectiveValue: string; source: string };
assert.equal(json.effectiveValue, "false", 'env "0" must still win over a dashboard PUT "true"');
assert.equal(json.source, "env");
});