Compare commits

...

9 Commits

Author SHA1 Message Date
diegosouzapw
7826fb8c4c Merge remote-tracking branch 'origin/release/v3.8.50' into HEAD 2026-08-09 00:46:38 -03:00
Diego Rodrigues de Sa e Souza
e0ce95c592 fix(ci): close remaining release-green gaps (#9835)
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
2026-08-08 23:24:11 -03:00
Diego Rodrigues de Sa e Souza
13dcbfd117 Merge pull request #9786 from diegosouzapw/fix/escalated-quality-validation-benign-error
fix(combo): ignore benign empty error fields in streaming quality validation (502 false-positive on opencode tool calls)
2026-08-08 22:40:51 -03:00
Diego Rodrigues de Sa e Souza
ec02945d97 Merge pull request #9820 from diegosouzapw/fix/release-v3.8.50-base-reds-9737-final
fix(tests): clear #9737 release gate blockers
2026-08-08 22:37:35 -03:00
diegosouzapw
69647b3b94 fix(combo): ignore benign empty error fields in streaming quality validation
isStreamingUpstreamError used a key-presence check (parsed.error != null)
which false-positives on benign values some backends emit on every chunk
({}, '', false, 0). When opencode issues a tool-call turn, the upstream SSE
opens with role-only frames (no recognized content) and a later chunk that
carries real tool_calls content PLUS a benign empty error field. The error
gate runs BEFORE content recognizers, so that single frame short-circuits
to 'error' -> 502 'streaming upstream error'. Same combo via kilocode works
because its wire format never emits the empty error field.

Fix: isSubstantiveError() helper — only treat error as real when it carries
non-empty string, non-empty object, or explicit true. Empty object {}, empty
string '', false, and 0 are benign.

TDD: tests/unit/quality-validation-benign-error.test.ts proves tool_calls
chunk with error:{} or error:'' is valid (was 502), while a real error
{message, code} still correctly fails.
2026-08-08 11:03:11 -03:00
diegosouzapw
bf1681727e Merge remote-tracking branch 'origin/release/v3.8.50' into feat/9544-muse-code-cli-provider 2026-08-08 08:47:38 -03:00
diegosouzapw
b80a11e98a fix(providers): register muse-code canonical provider + golden snapshot
- Add muse-code to APIKEY_PROVIDERS_FRONTIER so check:provider-consistency passes
- Regenerate translate-path golden snapshot to include the muse-code entry
  (20 additive lines, no other providers changed)
2026-08-08 08:47:18 -03:00
diegosouzapw
ea7866ae80 Merge remote-tracking branch 'origin/release/v3.8.50' into feat/9544-muse-code-cli-provider 2026-08-07 17:01:16 -03:00
diegosouzapw
ef236934c0 feat(providers): add Muse Code CLI provider preset (#9544) 2026-08-06 21:29:32 -03:00
17 changed files with 734 additions and 42 deletions

View File

@@ -0,0 +1 @@
- feat(providers): add Muse Code CLI provider preset (#9544)

View File

@@ -225,6 +225,7 @@ import { digitaloceanProvider } from "./registry/digitalocean/index.ts";
import { hcnsecProvider } from "./registry/hcnsec/index.ts";
import { promptqlProvider } from "./registry/promptql/index.ts";
import { hyperagentProvider } from "./registry/hyperagent/index.ts";
import { muse_codeProvider } from "./registry/muse-code/index.ts";
export const REGISTRY: Record<string, RegistryEntry> = {
aimlapi: aimlapiProvider,
@@ -451,5 +452,6 @@ export const REGISTRY: Record<string, RegistryEntry> = {
hcnsec: hcnsecProvider,
promptql: promptqlProvider,
hyperagent: hyperagentProvider,
"muse-code": muse_codeProvider,
unorouter: unorouterProvider,
};

View File

@@ -0,0 +1,106 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
/**
* Muse Code CLI — Meta's agentic coding tool.
*
* Wire format: OpenAI Responses API (POST /responses).
* Auth: Bearer token from META_API_KEY env var.
* Reasoning efforts: xhigh/ultra -> high (handled generically).
*
* @see https://github.com/joymadhu49/muse-openrouter-shim
*/
export const muse_codeProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "muse-code",
alias: "mc",
passthroughModels: true,
defaultContextLength: 200000,
models: [
{
id: "llama-4-maverick",
name: "Llama 4 Maverick",
contextLength: 1048576,
maxOutputTokens: 131072,
supportsReasoning: true,
supportsXHighEffort: true,
toolCalling: true,
supportsVision: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs", "logitBias"],
},
{
id: "llama-4-scout",
name: "Llama 4 Scout",
contextLength: 1048576,
maxOutputTokens: 131072,
supportsReasoning: true,
supportsXHighEffort: true,
toolCalling: true,
supportsVision: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs", "logitBias"],
},
{
id: "llama-3.3-70b",
name: "Llama 3.3 70B",
contextLength: 131072,
maxOutputTokens: 32768,
supportsReasoning: false,
toolCalling: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs"],
},
{
id: "llama-3.1-405b",
name: "Llama 3.1 405B",
contextLength: 131072,
maxOutputTokens: 32768,
supportsReasoning: false,
toolCalling: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs"],
},
{
id: "llama-3.1-70b",
name: "Llama 3.1 70B",
contextLength: 131072,
maxOutputTokens: 32768,
supportsReasoning: false,
toolCalling: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs"],
},
{
id: "llama-3.1-8b",
name: "Llama 3.1 8B",
contextLength: 131072,
maxOutputTokens: 32768,
supportsReasoning: false,
toolCalling: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs"],
},
{
id: "llama-3.2-90b-vision",
name: "Llama 3.2 90B Vision",
contextLength: 131072,
maxOutputTokens: 32768,
supportsReasoning: false,
toolCalling: true,
supportsVision: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs"],
},
{
id: "llama-3.2-11b-vision",
name: "Llama 3.2 11B Vision",
contextLength: 131072,
maxOutputTokens: 32768,
supportsReasoning: false,
toolCalling: true,
supportsVision: true,
targetFormat: "openai-responses",
unsupportedParams: ["logprobs", "topLogprobs"],
},
],
});

View File

@@ -190,10 +190,26 @@ function isRecord(value: unknown): value is Record<string, unknown> {
return !!value && typeof value === "object" && !Array.isArray(value);
}
/**
* Whether an `error` field carries a real failure signal. A key-presence check
* (`!= null`) false-positives on benign values some backends emit on every
* chunk (`{}`, `""`, `false`, `0`) — e.g. tool-call turns where a chunk with
* real tool_calls content also carries `"error": {}`. Only substantive values
* are treated as upstream failures.
*/
function isSubstantiveError(value: unknown): boolean {
if (value === null || value === undefined) return false;
if (typeof value === "string") return value.trim().length > 0;
if (typeof value === "object" && !Array.isArray(value)) {
return Object.keys(value as Record<string, unknown>).length > 0;
}
return value === true;
}
function isStreamingUpstreamError(parsed: unknown, eventType: string): boolean {
if (eventType === "response.failed" || eventType === "error") return true;
if (!isRecord(parsed)) return false;
if (parsed.error != null) return true;
if (isSubstantiveError(parsed.error)) return true;
const nestedResponse = isRecord(parsed.response) ? parsed.response : null;
return nestedResponse?.status === "failed" && nestedResponse.error != null;

View File

@@ -609,14 +609,6 @@ async function main() {
args: ["run", "check:pack-artifact"],
timeout: 20 * 60 * 1000,
});
// WS1.2 (#7065 class): boot the REAL packed tarball from a clean install —
// the runtime gate structure checks cannot provide. Reuses the same dist/ build.
slow.push({
id: "pack-boot",
label: "Tarball boot-smoke (installed CLI serves /health)",
args: ["run", "check:pack-boot"],
timeout: 15 * 60 * 1000,
});
}
slow.forEach((g) => announce(`${g.label} [parallel]`));
const slowResults = await Promise.all(
@@ -633,6 +625,41 @@ async function main() {
detail: code === 0 ? "pass" : firstFailureLine(out),
});
});
if (WITH_BUILD) {
// WS1.2 (#7065 class): boot the REAL packed tarball from a clean install.
// check:pack-artifact is the builder for dist/ when staging is absent, so the
// boot smoke MUST run after it completes. Running both in the parallel wave
// races check:pack-boot against dist/server.js creation on clean worktrees.
const packArtifactIndex = slow.findIndex((g) => g.id === "pack-artifact");
const packArtifactResult = slowResults[packArtifactIndex];
const bootLabel = "Tarball boot-smoke (installed CLI serves /health)";
if (!packArtifactResult || packArtifactResult.code !== 0) {
const out = "skipped because package-artifact did not produce a valid dist/ build";
saveGateLog("pack-boot", out);
record({
id: "pack-boot",
label: bootLabel,
kind: "hard",
ok: false,
detail: out,
});
} else {
announce(bootLabel);
const { code, out } = await runAsync(npmCmd, ["run", "check:pack-boot"], {
timeout: 15 * 60 * 1000,
});
saveGateLog("pack-boot", out);
record({
id: "pack-boot",
label: bootLabel,
kind: "hard",
ok: code === 0,
detail: code === 0 ? "pass" : firstFailureLine(out),
});
}
}
} else if (WITH_BUILD) {
// --with-build without the suites (--quick): still verify the package artifact.
const { code, out } = await runAsync(npmCmd, ["run", "check:pack-artifact"], {

View File

@@ -0,0 +1,87 @@
/**
* Muse Code CLI proprietary model catalog endpoint.
*
* Muse CLI calls GET /muse-code/models (or --base-url/muse-code/models)
* to discover available models. Returns the proprietary Muse format:
*
* { object: "list", data: [{ id, object, created, owned_by, metadata }] }
*
* Each model's metadata includes: name, family, reasoning, tool_call,
* modalities, limit, cost.
*/
import { muse_codeProvider } from "@omniroute/open-sse/config/providers/registry/muse-code/index.ts";
const MUSECODE_TIMESTAMP = Math.floor(Date.now() / 1000);
interface MuseCodeModel {
id: string;
object: "model";
created: number;
owned_by: string;
metadata: {
name: string;
family: string;
reasoning: boolean;
tool_call: boolean;
modalities: string[];
limit: number;
cost: number;
};
}
function buildModelCatalog(): MuseCodeModel[] {
const data: MuseCodeModel[] = [];
for (const model of muse_codeProvider.models) {
let family = "llama";
if (model.id.includes("llama-4")) family = "llama-4";
else if (model.id.includes("llama-3.3")) family = "llama-3.3";
else if (model.id.includes("llama-3.2")) family = "llama-3.2";
else if (model.id.includes("llama-3.1")) family = "llama-3.1";
const modalities: string[] = ["text"];
if (model.supportsVision) modalities.push("image");
data.push({
id: model.id,
object: "model",
created: MUSECODE_TIMESTAMP,
owned_by: "meta",
metadata: {
name: model.name,
family,
reasoning: !!model.supportsReasoning,
tool_call: !!model.toolCalling,
modalities,
limit: model.contextLength ?? 200_000,
cost: model.id.includes("maverick") || model.id.includes("405b") ? 3 : 1,
},
});
}
return data;
}
// Cache the catalog for the lifetime of the process — model list is static.
const CATALOG = buildModelCatalog();
const CATALOG_PAYLOAD = JSON.stringify({ object: "list", data: CATALOG }, null, 2);
export async function OPTIONS() {
return new Response(null, {
headers: {
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "*",
},
});
}
export async function GET() {
return new Response(CATALOG_PAYLOAD, {
status: 200,
headers: {
"content-type": "application/json",
"cache-control": "public, max-age=3600",
},
});
}

View File

@@ -51,6 +51,13 @@ const GEMINI_CLI_PROFILE: ClientIdentityProfile = Object.freeze({
"User-Agent": "GeminiCLI/0.1.0 (linux; x64)",
}),
});
const MUSE_CLI_PROFILE: ClientIdentityProfile = Object.freeze({
id: "muse-cli",
label: "Muse Code CLI",
headers: Object.freeze({
"User-Agent": "MuseCodeCLI/0.1.0 (linux; x64)",
}),
});
/** Ordered so `CLIENT_IDENTITY_PROFILE_OPTIONS` renders "Default" first. */
export const CLIENT_IDENTITY_PROFILES: Readonly<Record<string, ClientIdentityProfile>> =
@@ -59,6 +66,7 @@ export const CLIENT_IDENTITY_PROFILES: Readonly<Record<string, ClientIdentityPro
"claude-cli": CLAUDE_CLI_PROFILE,
"codex-cli": CODEX_CLI_PROFILE,
"gemini-cli": GEMINI_CLI_PROFILE,
"muse-cli": MUSE_CLI_PROFILE,
});
export const CLIENT_IDENTITY_PROFILE_IDS: readonly string[] = Object.keys(CLIENT_IDENTITY_PROFILES);

View File

@@ -275,4 +275,19 @@ export const APIKEY_PROVIDERS_FRONTIER = {
"Writer Palmyra is OpenAI-compatible at https://api.writer.com/v1. palmyra-x5 offers a 1M-token context window.",
hasFree: false,
},
"muse-code": {
id: "muse-code",
alias: "mc",
name: "Muse Code (Meta)",
icon: "auto_awesome",
color: "#0866FF",
textIcon: "MC",
website: "https://github.com/meta-llama/llama-stack",
authHint:
"Use your META_API_KEY env var as a Bearer token. Muse Code CLI uses the OpenAI Responses API wire format (POST /responses).",
apiHint:
"Muse Code is OpenAI-compatible. OmniRoute routes chat traffic through the Responses API and exposes the proprietary model catalog at /v1/muse-code/models.",
passthroughModels: true,
hasFree: false,
},
};

View File

@@ -3405,6 +3405,26 @@
"stream": "https://api.morphllm.com/v1/chat/completions"
}
},
"muse-code": {
"format": "openai",
"headers": {
"apiKey": {
"Accept": "text/event-stream",
"Authorization": "Bearer <TOK>",
"Content-Type": "application/json"
},
"nonStream": {
"Authorization": "Bearer <TOK>",
"Content-Type": "application/json"
},
"oauth": {
"Accept": "text/event-stream",
"Authorization": "Bearer <TOK>",
"Content-Type": "application/json"
}
},
"url": {}
},
"muse-spark-web": {
"format": "openai",
"headers": {

View File

@@ -80,6 +80,8 @@ test("#7849: the two-message pathological pair stays bounded", () => {
Date.now() - started < 4000,
"the pathological pair must stay fast; quadratic work would take seconds"
);
assert.strictEqual(result.body, body, "bounded processing must preserve the input body");
assert.equal(result.compressed, false, "the non-deduplicable pair must fail open");
assert.ok(Array.isArray((result.body as { messages?: unknown[] }).messages));
});

View File

@@ -0,0 +1,81 @@
/**
* Tests for Muse Code CLI model catalog endpoint.
*
* Verifies GET /v1/muse-code/models returns the proprietary Muse format.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { muse_codeProvider } from "../../open-sse/config/providers/registry/muse-code/index.ts";
// ── Model catalog shape ─────────────────────────────────────────────────────
test("muse-code provider has at least one model", () => {
assert.ok(muse_codeProvider.models.length >= 1);
});
test("muse-code models have unique ids", () => {
const ids = muse_codeProvider.models.map((m) => m.id);
const unique = new Set(ids);
assert.equal(unique.size, ids.length, "model IDs must be unique");
});
test("muse-code models include llama-4-maverick", () => {
const ids = muse_codeProvider.models.map((m) => m.id);
assert.ok(ids.includes("llama-4-maverick"), "must include llama-4-maverick");
});
test("muse-code models include llama-4-scout", () => {
const ids = muse_codeProvider.models.map((m) => m.id);
assert.ok(ids.includes("llama-4-scout"), "must include llama-4-scout");
});
test("muse-code models include llama-3.3-70b", () => {
const ids = muse_codeProvider.models.map((m) => m.id);
assert.ok(ids.includes("llama-3.3-70b"), "must include llama-3.3-70b");
});
test("llama-4 models have supportsXHighEffort", () => {
const maverick = muse_codeProvider.models.find((m) => m.id === "llama-4-maverick");
assert.ok(maverick, "llama-4-maverick must exist");
assert.equal(maverick.supportsXHighEffort, true);
const scout = muse_codeProvider.models.find((m) => m.id === "llama-4-scout");
assert.ok(scout, "llama-4-scout must exist");
assert.equal(scout.supportsXHighEffort, true);
});
test("llama-3.3-70b does not support reasoning", () => {
const model = muse_codeProvider.models.find((m) => m.id === "llama-3.3-70b");
assert.ok(model, "llama-3.3-70b must exist");
assert.equal(model.supportsReasoning, false);
});
test("non-reasoning models do not declare supportsXHighEffort", () => {
for (const model of muse_codeProvider.models) {
if (!model.supportsReasoning) {
assert.equal(
model.supportsXHighEffort,
undefined,
`${model.id} is not a reasoning model but has supportsXHighEffort`
);
}
}
});
// ── Vision models ───────────────────────────────────────────────────────────
test("vision models have supportsVision: true", () => {
const expectedVision = [
"llama-4-maverick",
"llama-4-scout",
"llama-3.2-90b-vision",
"llama-3.2-11b-vision",
];
for (const model of muse_codeProvider.models) {
if (expectedVision.includes(model.id)) {
assert.equal(model.supportsVision, true, `${model.id} should have supportsVision`);
}
}
});

View File

@@ -0,0 +1,91 @@
/**
* Tests for Muse Code CLI provider registry entry.
*
* Verifies the provider entry loads correctly with expected config.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { muse_codeProvider } from "../../open-sse/config/providers/registry/muse-code/index.ts";
import { getRegistryEntry } from "../../open-sse/config/providerRegistry.ts";
// ── Registry entry structure ────────────────────────────────────────────────
test("muse-code provider entry has id", () => {
assert.equal(muse_codeProvider.id, "muse-code");
});
test("muse-code provider entry has alias", () => {
assert.equal(muse_codeProvider.alias, "mc");
});
test("muse-code provider uses openai format", () => {
assert.equal(muse_codeProvider.format, "openai");
});
test("muse-code provider uses apikey auth", () => {
assert.equal(muse_codeProvider.authType, "apikey");
assert.equal(muse_codeProvider.authHeader, "bearer");
});
test("muse-code provider has passthroughModels enabled", () => {
assert.equal(muse_codeProvider.passthroughModels, true);
});
// ── Model entries ───────────────────────────────────────────────────────────
test("muse-code provider has curated models", () => {
assert.ok(muse_codeProvider.models.length > 0);
});
test("all muse-code models have contextLength", () => {
for (const model of muse_codeProvider.models) {
assert.ok(
typeof model.contextLength === "number" && model.contextLength > 0,
`${model.id} must have positive contextLength`
);
}
});
test("all muse-code models have toolCalling: true", () => {
for (const model of muse_codeProvider.models) {
assert.equal(model.toolCalling, true, `${model.id} must have toolCalling enabled`);
}
});
test("all muse-code models have targetFormat: openai-responses", () => {
for (const model of muse_codeProvider.models) {
assert.equal(
model.targetFormat,
"openai-responses",
`${model.id} must use openai-responses target format`
);
}
});
test("reasoning models have supportsXHighEffort", () => {
for (const model of muse_codeProvider.models) {
if (model.supportsReasoning) {
assert.equal(
model.supportsXHighEffort,
true,
`${model.id} is a reasoning model but missing supportsXHighEffort`
);
}
}
});
// ── Registry discovery ──────────────────────────────────────────────────────
test("muse-code is discoverable via getRegistryEntry", () => {
const entry = getRegistryEntry("muse-code");
assert.ok(entry, "getRegistryEntry must return muse-code entry");
assert.equal(entry.id, "muse-code");
});
test("muse-code is discoverable via alias", () => {
const entry = getRegistryEntry("mc");
assert.ok(entry, "getRegistryEntry must find muse-code by alias mc");
assert.equal(entry.id, "muse-code");
});

View File

@@ -0,0 +1,167 @@
/**
* TDD regression guard — quality validation false-positive on benign `error`
* fields in streaming SSE chunks.
*
* `isStreamingUpstreamError` treats ANY non-null `error` field as an upstream
* failure: `parsed.error != null` is true for `{}`, `""`, `false`, and `0`.
* When a client like opencode issues a tool-call turn, the upstream SSE opens
* with role-only frames (no recognized content) and a later chunk that carries
* real tool_calls content PLUS a benign empty `error` field (a field some
* backends emit on every chunk). The error gate runs BEFORE the content
* recognizers, so that single frame short-circuits to "error" → 502
* "streaming upstream error" — while the same combo via kilocode (different
* wire format) never emits the empty `error` field and works fine.
*/
import test from "node:test";
import assert from "node:assert/strict";
const { validateResponseQuality } = await import("../../open-sse/services/combo.ts");
const encoder = new TextEncoder();
const silentLog = { warn: () => {} };
function openAiSseStream(events: string[]): ReadableStream<Uint8Array> {
const body = events.join("\n") + "\n";
return new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(encoder.encode(body));
controller.close();
},
});
}
/**
* OpenAI-compatible tool-call stream that ALSO carries a benign empty `error`
* field on the tool_calls chunk. Some backends emit `"error": {}` or
* `"error": ""` alongside every chunk; that is not a real upstream failure.
* The frame must be treated as CONTENT (valid), not ERROR.
*/
function makeToolCallStreamWithBenignError(): Response {
const events = [
// role-only first chunk — no recognized content, widens the peek window
`data: ${JSON.stringify({
id: "chatcmpl_1",
object: "chat.completion.chunk",
created: 123,
model: "gpt-4o",
choices: [{ index: 0, delta: { role: "assistant" }, finish_reason: null }],
})}`,
"",
// tool_calls delta + benign empty `error` field (the bug trigger)
`data: ${JSON.stringify({
id: "chatcmpl_2",
object: "chat.completion.chunk",
created: 123,
model: "gpt-4o",
choices: [
{
index: 0,
delta: {
tool_calls: [
{ index: 0, id: "call_1", type: "function", function: { name: "Bash", arguments: "" } },
],
},
finish_reason: null,
},
],
error: {},
})}`,
"",
`data: [DONE]`,
"",
];
return new Response(openAiSseStream(events), {
status: 200,
headers: { "content-type": "text/event-stream" },
});
}
test("OpenAI stream with tool_calls + benign empty error:{} field is VALID (not 502)", async () => {
const res = makeToolCallStreamWithBenignError();
const out = await validateResponseQuality(res, true, silentLog);
assert.equal(
out.valid,
true,
`expected valid for tool_calls chunk with benign error:{}, got valid=false (reason: ${out.reason})`
);
assert.ok(out.clonedResponse, "clonedResponse must be present for valid streaming response");
});
test("OpenAI stream with tool_calls + benign empty error:'' field is VALID", async () => {
const events = [
`data: ${JSON.stringify({
id: "chatcmpl_3",
object: "chat.completion.chunk",
created: 123,
model: "gpt-4o",
choices: [{ index: 0, delta: { role: "assistant" }, finish_reason: null }],
})}`,
"",
`data: ${JSON.stringify({
id: "chatcmpl_4",
object: "chat.completion.chunk",
created: 123,
model: "gpt-4o",
choices: [
{
index: 0,
delta: {
tool_calls: [
{ index: 0, id: "call_2", type: "function", function: { name: "Read", arguments: "" } },
],
},
finish_reason: null,
},
],
error: "",
})}`,
"",
`data: [DONE]`,
"",
];
const res = new Response(openAiSseStream(events), {
status: 200,
headers: { "content-type": "text/event-stream" },
});
const out = await validateResponseQuality(res, true, silentLog);
assert.equal(
out.valid,
true,
`expected valid for tool_calls chunk with benign error:"", got valid=false (reason: ${out.reason})`
);
});
test("Stream with a REAL non-empty error object is still flagged as invalid", async () => {
const events = [
`data: ${JSON.stringify({
id: "chatcmpl_5",
object: "chat.completion.chunk",
created: 123,
model: "gpt-4o",
choices: [{ index: 0, delta: { role: "assistant" }, finish_reason: null }],
})}`,
"",
`data: ${JSON.stringify({
id: "chatcmpl_6",
object: "chat.completion.chunk",
created: 123,
model: "gpt-4o",
choices: [{ index: 0, delta: {}, finish_reason: null }],
error: { message: "upstream quota exceeded", code: "rate_limit_exceeded" },
})}`,
"",
`data: [DONE]`,
"",
];
const res = new Response(openAiSseStream(events), {
status: 200,
headers: { "content-type": "text/event-stream" },
});
const out = await validateResponseQuality(res, true, silentLog);
assert.equal(
out.valid,
false,
`expected invalid for real error object, got valid=true (reason: ${out.reason})`
);
assert.match(out.reason ?? "", /streaming upstream error/, "reason should mention the upstream error");
});

View File

@@ -26,6 +26,12 @@ function wait(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Leave enough scheduling headroom for a loaded CI/devbox while keeping the
// executing callback longer than the queue-only budget. The actual queued-job
// case stays short because it controls dispatch deterministically.
const DISPATCHED_QUEUE_BUDGET_MS = 2_000;
const QUEUED_QUEUE_BUDGET_MS = 250;
test.afterEach(async () => {
await rateLimitManager.__resetRateLimitManagerForTests();
});
@@ -43,14 +49,23 @@ async function triggerQueueTimeout() {
concurrentRequests: 1,
requestsPerMinute: 100000,
minTimeBetweenRequestsMs: 0,
maxWaitMs: 40,
maxWaitMs: DISPATCHED_QUEUE_BUDGET_MS,
});
rateLimitManager.enableRateLimitProtection("conn-queue-timeout");
const connectionId = "conn-dispatched-timeout";
rateLimitManager.enableRateLimitProtection(connectionId);
return rateLimitManager.withRateLimit("openai", "conn-queue-timeout", "gpt-4o", async () => {
await wait(400); // > maxWaitMs (40ms) → Bottleneck fails the job
return "should-not-reach";
});
let dispatched = false;
const result = await rateLimitManager.withRateLimit(
"test-provider",
connectionId,
null,
async () => {
dispatched = true;
await wait(DISPATCHED_QUEUE_BUDGET_MS + 250);
return "should-not-reach";
}
);
return { dispatched, result };
}
async function triggerQueuedTimeout() {
@@ -60,7 +75,7 @@ async function triggerQueuedTimeout() {
concurrentRequests: 1,
requestsPerMinute: 0,
minTimeBetweenRequestsMs: 0,
maxWaitMs: 40,
maxWaitMs: QUEUED_QUEUE_BUDGET_MS,
});
const connectionId = "conn-queued-timeout";
rateLimitManager.enableRateLimitProtection(connectionId);
@@ -79,13 +94,12 @@ async function triggerQueuedTimeout() {
await firstExecuting;
let caught: unknown;
let queuedDispatched = false;
try {
await rateLimitManager.withRateLimit(
"test-provider",
connectionId,
null,
async () => "should-not-dispatch"
);
await rateLimitManager.withRateLimit("test-provider", connectionId, null, async () => {
queuedDispatched = true;
return "should-not-dispatch";
});
assert.fail("expected the queued job to expire");
} catch (error) {
caught = error;
@@ -93,16 +107,20 @@ async function triggerQueuedTimeout() {
releaseFirst();
await first;
}
return caught;
return { caught, queuedDispatched };
}
test("#4165 a dispatched provider call is not killed by the queue budget", async () => {
const result = await triggerQueueTimeout();
assert.equal(result, "should-not-reach");
const execution = await triggerQueueTimeout();
assert.equal(execution.dispatched, true, "the callback must enter execution");
assert.equal(execution.result, "should-not-reach");
});
test("#4165 queue expiry surfaces a clear local error", async () => {
const caught = (await triggerQueuedTimeout()) as Error & { code?: string };
const result = await triggerQueuedTimeout();
assert.ok(result.caught instanceof Error, "queue expiry must reject with an Error");
assert.equal(result.queuedDispatched, false, "an expired queued callback must never dispatch");
const caught = result.caught as Error & { code?: string };
assert.equal(caught.code, "RATE_LIMIT_QUEUE_TIMEOUT");
assert.match(caught.message, /maxWaitMs/);
assert.match(caught.message, /not an upstream/i);

View File

@@ -452,7 +452,13 @@ test("v1 search POST returns 400 when auto-select finds no configured provider (
const body = (await response.json()) as any;
assert.equal(response.status, 400);
assert.equal(capturedUrl, "", "fallback-only SearXNG must not receive an upstream request");
assert.ok(body.error?.message || body.error);
assert.match(
String(body.error?.message ?? body.error),
/provider|configured/i,
"the response must explain that no provider was selected"
);
} finally {
globalThis.fetch = originalFetch;
}

View File

@@ -200,6 +200,16 @@ test("Claude -> Gemini omits unsigned functionCall instead of injecting a fake t
false,
"signature-less tool_use must not become a native functionCall"
);
assert.equal(
JSON.stringify(result).includes('"thoughtSignature"'),
false,
"the translator must not synthesize a fake thought signature"
);
assert.equal(
JSON.stringify(result).includes("read_file"),
false,
"the omitted unsigned call must not leak its tool payload elsewhere"
);
});
test("Claude -> Gemini sanitizes long tool names and exposes a restore map", () => {

View File

@@ -22,16 +22,12 @@ const extract = extractCiGates as (
) => { id: string; job: string; args: string[]; env?: Record<string, string> }[];
test("eslintCounts sums errors + warnings across files", () => {
const parsed = [
{ errorCount: 2, warningCount: 5 },
{ errorCount: 0, warningCount: 3 },
{},
];
const parsed = [{ errorCount: 2, warningCount: 5 }, { errorCount: 0, warningCount: 3 }, {}];
assert.deepEqual(eslintCounts(parsed), { errors: 2, warnings: 8 });
});
test("parseEslintJson tolerates a leading non-JSON banner", () => {
const out = "npm warn something\n[{\"errorCount\":0,\"warningCount\":1}]";
const out = 'npm warn something\n[{"errorCount":0,"warningCount":1}]';
assert.deepEqual(parseEslintJson(out), [{ errorCount: 0, warningCount: 1 }]);
assert.equal(parseEslintJson("no json here"), null);
});
@@ -52,8 +48,14 @@ test("parseEslintJson tolerates ESLint's trailing unpruned-suppressions stderr s
});
test("parseCognitiveCount reads the gate's count (en + pt)", () => {
assert.equal(parseCognitiveCount("[cognitive-complexity] 797 function(s) exceed the threshold (15)."), 797);
assert.equal(parseCognitiveCount("[cognitive-complexity] REGRESSÃO — 801 violações > baseline 797"), 801);
assert.equal(
parseCognitiveCount("[cognitive-complexity] 797 function(s) exceed the threshold (15)."),
797
);
assert.equal(
parseCognitiveCount("[cognitive-complexity] REGRESSÃO — 801 violações > baseline 797"),
801
);
assert.equal(parseCognitiveCount("no number"), null);
});
@@ -175,8 +177,16 @@ test("pre-flight wires the test-masking PR-context gate against origin/main (v3.
);
// run() must honor a per-gate env override so GITHUB_BASE_REF actually reaches the child
// (routed through buildGateEnv since the --hermetic scrub was added).
assert.match(src, /env:\s*buildGateEnv\(opts\.env\)/, "run() must merge opts.env into the child env");
assert.match(src, /\.\.\.\(extra \|\| \{\}\)/, "buildGateEnv must spread the per-gate env override");
assert.match(
src,
/env:\s*buildGateEnv\(opts\.env\)/,
"run() must merge opts.env into the child env"
);
assert.match(
src,
/\.\.\.\(extra \|\| \{\}\)/,
"buildGateEnv must spread the per-gate env override"
);
});
test("pre-flight --hermetic scrubs the live-test trigger vars (2026-07-05 false-positive fix)", async () => {
@@ -214,6 +224,27 @@ test("pre-flight runs the slow suites CONCURRENTLY (v3.8.45 perf — was ~1h ser
assert.match(src, /slow\.forEach\([\s\S]*?saveGateLog\(g\.id/, "each slow gate persists its log");
});
test("pre-flight runs tarball boot only after the package artifact builder completes", async () => {
const fs = await import("node:fs");
const src = fs.readFileSync(
new URL("../../scripts/quality/validate-release-green.mjs", import.meta.url),
"utf8"
);
const parallelWave = src.indexOf("const slowResults = await Promise.all");
const packBoot = src.indexOf('id: "pack-boot"');
assert.ok(parallelWave >= 0, "the parallel slow-gate wave must exist");
assert.ok(
packBoot > parallelWave,
"pack-boot must be declared after the parallel artifact build"
);
assert.match(
src,
/packArtifactResult[\s\S]*?check:pack-boot/,
"pack-boot must be explicitly sequenced from the package-artifact result"
);
});
// ─── --full-ci gate extraction (P0, v3.8.46 post-mortem) ─────────────────────
const CI_FIXTURE = `
@@ -259,7 +290,11 @@ test("extractCiGates: pulls npm-run gate steps from the ci.yml gate jobs only",
assert.ok(ids.includes("check:docs-all") && ids.includes("check:docs-symbols"), "multi-line run");
// …and NON-gate steps + jobs outside the gate set are ignored.
assert.ok(!ids.includes("build") && !ids.some((i) => i.startsWith("test:")), "no build/test-run");
assert.equal(gates.find((g) => g.job === "test-unit"), undefined, "test-unit job is not scanned");
assert.equal(
gates.find((g) => g.job === "test-unit"),
undefined,
"test-unit job is not scanned"
);
});
test("extractCiGates: preserves `-- <args>` so ratchet flags reach the script", () => {
@@ -272,7 +307,10 @@ test("extractCiGates: preserves `-- <args>` so ratchet flags reach the script",
test("extractCiGates: skips the non-local gates (pr-evidence, codeql-ratchet)", () => {
const ids = extract(CI_FIXTURE).map((g) => g.id);
assert.ok(!ids.includes("check:pr-evidence"), "pr-evidence needs a PR body — skipped");
assert.ok(!ids.includes("check:codeql-ratchet"), "codeql-ratchet is a remote-main check — skipped");
assert.ok(
!ids.includes("check:codeql-ratchet"),
"codeql-ratchet is a remote-main check — skipped"
);
assert.ok(FULL_CI_SKIP.has("check:pr-evidence") && FULL_CI_SKIP.has("check:codeql-ratchet"));
});
@@ -295,10 +333,7 @@ test("extractCiGates: attaches GITHUB_BASE_REF=main env to test-masking + de-dup
test("extractCiGates: the REAL ci.yml yields the base-reds that leaked in v3.8.46", async () => {
const fs = await import("node:fs");
const yaml = fs.readFileSync(
new URL("../../.github/workflows/ci.yml", import.meta.url),
"utf8"
);
const yaml = fs.readFileSync(new URL("../../.github/workflows/ci.yml", import.meta.url), "utf8");
const ids = new Set(extract(yaml).map((g) => g.id));
// The exact gates that leaked to the v3.8.46 release PR because the pre-flight
// never ran them — --full-ci now reproduces every one.