mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-16 11:52:26 +03:00
fix(ci): clear the release/v3.8.51 base-reds left by the 09-15 batch — stryker coverage, CLI ready_timeout key, paid-target fixture, call-log traceId, Jina custom prefix
Every PR into release/v3.8.51 pushed after #13635/#13678 still failed Fast Quality Gates and all four Unit fast-path shards on the same 16 tests. Each one reproduces on the pure tip; none is a product defect: - mutation-test-coverage: noauth-model-lockout and local-token-budget-429-skips-cooldown (#13606) were missing from stryker.conf.json tap.testFiles. - cli-i18n-catalog: --ready-timeout calls t("serve.ready_timeout") with no catalog entry; added to en, zh-CN and zh-TW (the parity-checked locales). - paid-model-target(-routes)-6540: #13407 removed Together's one-time credit from the free catalog, so "together/..." classifies as unknown and the save-time guard correctly lets it through. Fixture is now gemini/gemini-3.1-pro-preview, plus a precondition test on the fixtures. - attempt-logging-early-keepalive-merge / video-bridge-log-redaction: #13546 keys the call-log row on traceId; baseCtx now defaults traceId to pendingRequestId (same pattern as chatcore-attempt-logging). The keepalive test also moves to the 30s wall-clock poll deadline video-bridge uses. - models-catalog-route: custom Jina rows keep the jina-ai/ prefix; #13403 changed the custom assertion to jina/ (only synced rows use the alias). Refs #12732
This commit is contained in:
@@ -256,6 +256,7 @@
|
||||
"max_restarts": "Max crash restarts within 30s before giving up (default: 2)",
|
||||
"tray": "Start in the system tray (desktop only, opt-in)",
|
||||
"no_tray": "Disable system tray icon",
|
||||
"ready_timeout": "Readiness probe timeout in ms (also OMNIROUTE_READY_TIMEOUT_MS, default 60000)",
|
||||
"tls_cert": "Path to a TLS certificate (PEM) to serve HTTPS (also OMNIROUTE_TLS_CERT)",
|
||||
"tls_key": "Path to the TLS private key (PEM) to serve HTTPS (also OMNIROUTE_TLS_KEY)"
|
||||
},
|
||||
|
||||
@@ -254,6 +254,7 @@
|
||||
"max_restarts": "30 秒内的最大崩溃重启次数(默认:2)",
|
||||
"tray": "显示系统托盘图标(仅桌面,选择加入)",
|
||||
"no_tray": "禁用系统托盘图标",
|
||||
"ready_timeout": "就绪探测超时(毫秒)(也可用 OMNIROUTE_READY_TIMEOUT_MS,默认 60000)",
|
||||
"tls_cert": "用于提供 HTTPS 服务的 TLS 证书(PEM)路径(也可用 OMNIROUTE_TLS_CERT)",
|
||||
"tls_key": "用于提供 HTTPS 服务的 TLS 私钥(PEM)路径(也可用 OMNIROUTE_TLS_KEY)"
|
||||
},
|
||||
|
||||
@@ -254,6 +254,7 @@
|
||||
"max_restarts": "30 秒內的最大崩潰重啟次數(預設:2)",
|
||||
"tray": "顯示系統托盤圖示(僅桌面,選擇加入)",
|
||||
"no_tray": "停用系統托盤圖示",
|
||||
"ready_timeout": "就緒探測逾時(毫秒)(也可用 OMNIROUTE_READY_TIMEOUT_MS,預設 60000)",
|
||||
"tls_cert": "用於提供 HTTPS 服務的 TLS 憑證(PEM)路徑(也可用 OMNIROUTE_TLS_CERT)",
|
||||
"tls_key": "用於提供 HTTPS 服務的 TLS 私鑰(PEM)路徑(也可用 OMNIROUTE_TLS_KEY)"
|
||||
},
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
- **test(call-logs):** the early-keepalive merge and video-bridge redaction tests pass a `traceId` (defaulting to `pendingRequestId`) now that #13546 keys each attempt's call-log row on it, and the keepalive test polls against a 30s wall-clock deadline like the video-bridge test instead of a 2.4s try count ([#12732](https://github.com/diegosouzapw/OmniRoute/issues/12732))
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(cli):** add the `serve.ready_timeout` string to the `en`, `zh-CN` and `zh-TW` CLI catalogs; `--ready-timeout` shipped calling `t("serve.ready_timeout")` without a catalog entry, which the CLI i18n key-coverage and parity tests report ([#12732](https://github.com/diegosouzapw/OmniRoute/issues/12732))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(models):** the custom Jina specialty-model catalog test expects the `jina-ai/` prefix again: custom rows keep the connection provider id, only synced rows resolve through the `jina` alias, and #13403 had switched the custom assertion to `jina/` ([#12732](https://github.com/diegosouzapw/OmniRoute/issues/12732))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(settings):** the #6540 paid-target tests now use `gemini/gemini-3.1-pro-preview` as the paid fixture and assert the fixtures still classify as paid/free/unknown; the old Together target became "unknown" once #13407 removed Together's one-time signup credit from the free catalog, so the three save-time blocking tests read a correct 200 as a missing guard ([#12732](https://github.com/diegosouzapw/OmniRoute/issues/12732))
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(ci):** register `noauth-model-lockout` and `local-token-budget-429-skips-cooldown` in `stryker.conf.json` `tap.testFiles`; both cover `accountFallback.ts`/`auth.ts`/`comboPredicates.ts`, so the strict `mutation-test-coverage` gate failed Fast Quality Gates on every PR into the release line ([#12732](https://github.com/diegosouzapw/OmniRoute/issues/12732))
|
||||
@@ -291,6 +291,7 @@
|
||||
"tests/unit/lkgp-stale-pin-exhaustion-11911.test.ts",
|
||||
"tests/unit/search-432-plan-limit-cooldown.test.ts",
|
||||
"tests/unit/livews-forward-backoff-4604.test.ts",
|
||||
"tests/unit/local-token-budget-429-skips-cooldown.test.ts",
|
||||
"tests/unit/management-auth-hardening.test.ts",
|
||||
"tests/unit/mark-account-unavailable-numeric-epoch-guard.test.ts",
|
||||
"tests/unit/masked-200-exhaustion-fallback-6427.test.ts",
|
||||
@@ -309,6 +310,7 @@
|
||||
"tests/unit/native-codex-turn-pin-model-scoped-fallback.test.ts",
|
||||
"tests/unit/no-memory-header.test.ts",
|
||||
"tests/unit/noauth-autocombo-lockout-7623.test.ts",
|
||||
"tests/unit/noauth-model-lockout.test.ts",
|
||||
"tests/unit/ollama-404-model-lockout-11071.test.ts",
|
||||
"tests/unit/non-streaming-client-translate.test.ts",
|
||||
"tests/unit/non-streaming-provider-leg.test.ts",
|
||||
|
||||
@@ -23,7 +23,11 @@ const { recordEarlyKeepaliveBytes, takeEarlyKeepaliveBytes } =
|
||||
await import("../../open-sse/utils/earlyKeepaliveByteBuffer.ts");
|
||||
|
||||
function baseCtx(overrides: Record<string, unknown> = {}) {
|
||||
// #13481/#13546: the call log row is keyed on traceId. It defaults to
|
||||
// pendingRequestId so these tests keep polling by the id they pass in.
|
||||
const pendingRequestId = (overrides.pendingRequestId as string) ?? "REPLACE";
|
||||
return {
|
||||
traceId: overrides.traceId ?? pendingRequestId,
|
||||
provider: "openai",
|
||||
connectionId: "conn-1",
|
||||
model: "gpt-x",
|
||||
@@ -48,13 +52,19 @@ function baseCtx(overrides: Record<string, unknown> = {}) {
|
||||
} as Parameters<typeof persistAttemptLogs>[1];
|
||||
}
|
||||
|
||||
async function pollForCallLog(id: string, tries = 120) {
|
||||
for (let i = 0; i < tries; i++) {
|
||||
// Wall-clock deadline instead of 120 tries x 20ms (2.4s): on a loaded runner the
|
||||
// async SQLite write routinely outlasts that ceiling and the row reads as missing.
|
||||
// Same budget and rationale as tests/unit/video-bridge-log-redaction.test.ts.
|
||||
const POLL_DEADLINE_MS = 30_000;
|
||||
|
||||
async function pollForCallLog(id: string, deadlineMs = POLL_DEADLINE_MS) {
|
||||
const deadline = Date.now() + deadlineMs;
|
||||
for (;;) {
|
||||
const row = await getCallLogById(id);
|
||||
if (row) return row as Record<string, unknown>;
|
||||
if (Date.now() >= deadline) return null;
|
||||
await new Promise((r) => setTimeout(r, 20));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
|
||||
@@ -1093,9 +1093,11 @@ test("v1 models catalog does not duplicate custom Jina specialty models", async
|
||||
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(visibleJinaEmbeddingRows.length, 1);
|
||||
assert.equal(visibleJinaEmbeddingRows[0].id, "jina/jina-embeddings-v5-text-small");
|
||||
// Custom rows keep the connection's provider id as the prefix; only the synced
|
||||
// rows above resolve through the `jina` alias (#13403 flipped this by mistake).
|
||||
assert.equal(visibleJinaEmbeddingRows[0].id, "jina-ai/jina-embeddings-v5-text-small");
|
||||
assert.equal(visibleJinaRerankRows.length, 1);
|
||||
assert.equal(visibleJinaRerankRows[0].id, "jina/jina-reranker-v3");
|
||||
assert.equal(visibleJinaRerankRows[0].id, "jina-ai/jina-reranker-v3");
|
||||
});
|
||||
|
||||
test("v1 models catalog exposes image model input and output modalities for advanced image providers", async () => {
|
||||
|
||||
@@ -7,7 +7,7 @@ test("isPaidModelTarget — documented free model → 'free'", () => {
|
||||
});
|
||||
|
||||
test("isPaidModelTarget — provider in free catalog but model not listed free → 'paid'", () => {
|
||||
assert.equal(isPaidModelTarget("together/Qwen/Qwen3-235B-A22B"), "paid");
|
||||
assert.equal(isPaidModelTarget("gemini/gemini-3.1-pro-preview"), "paid");
|
||||
});
|
||||
|
||||
test("isPaidModelTarget — no separator (combo/alias name) → 'unknown' (fail open)", () => {
|
||||
|
||||
@@ -14,10 +14,13 @@ const settingsRoute = await import("../../src/app/api/settings/route.ts");
|
||||
const comboDefaultsRoute = await import("../../src/app/api/settings/combo-defaults/route.ts");
|
||||
const backgroundDegradationRoute =
|
||||
await import("../../src/app/api/settings/background-degradation/route.ts");
|
||||
const { isPaidModelTarget } = await import("../../src/shared/utils/freeModels.ts");
|
||||
|
||||
// A provider present in the free-model catalog (so providerHasFreeModels is
|
||||
// true) but a model id that is NOT one of its documented free models.
|
||||
const PAID_TARGET = "together/Qwen/Qwen3-235B-A22B";
|
||||
// true) but a model id that is NOT one of its documented free models. Gemini's
|
||||
// free tier is recurring and excludes the Pro line; the previous Together target
|
||||
// stopped classifying once its one-time signup credit left the catalog (#13407).
|
||||
const PAID_TARGET = "gemini/gemini-3.1-pro-preview";
|
||||
// A documented free model.
|
||||
const FREE_TARGET = "openrouter/auto";
|
||||
// No "/" or "," — a combo/alias name, fails open ("unknown").
|
||||
@@ -38,6 +41,12 @@ test.after(() => {
|
||||
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
||||
});
|
||||
|
||||
test("fixtures classify as intended against the current free-model catalog", () => {
|
||||
assert.equal(isPaidModelTarget(PAID_TARGET), "paid", "PAID_TARGET must stay a paid model");
|
||||
assert.equal(isPaidModelTarget(FREE_TARGET), "free", "FREE_TARGET must stay a free model");
|
||||
assert.equal(isPaidModelTarget(UNKNOWN_TARGET), "unknown");
|
||||
});
|
||||
|
||||
// ── PATCH /api/settings — webSearchRouteModel ──────────────────────────────
|
||||
|
||||
test("PATCH /api/settings blocks a paid webSearchRouteModel when hidePaidModels is on", async () => {
|
||||
|
||||
@@ -60,7 +60,11 @@ function videoBody() {
|
||||
}
|
||||
|
||||
function baseCtx(overrides: Record<string, unknown> = {}) {
|
||||
// #13481/#13546: the call log row is keyed on traceId. It defaults to
|
||||
// pendingRequestId so these tests keep polling by the id they pass in.
|
||||
const pendingRequestId = (overrides.pendingRequestId as string) ?? "REPLACE";
|
||||
return {
|
||||
traceId: overrides.traceId ?? pendingRequestId,
|
||||
provider: "openai",
|
||||
connectionId: "conn-1",
|
||||
model: "gpt-x",
|
||||
|
||||
Reference in New Issue
Block a user