diff --git a/open-sse/executors/default.js b/open-sse/executors/default.js index 8a89d37b..71e35e88 100644 --- a/open-sse/executors/default.js +++ b/open-sse/executors/default.js @@ -61,7 +61,6 @@ export class DefaultExecutor extends BaseExecutor { case "kimi": case "minimax": case "minimax-cn": - return `${this.config.baseUrl}?beta=true`; case "kimi-coding": return `${this.config.baseUrl}?beta=true`; case "gemini": @@ -282,7 +281,7 @@ export class DefaultExecutor extends BaseExecutor { async refreshCline(refreshToken, proxyOptions = null) { console.log('[DEBUG] Refreshing Cline token, refreshToken length:', refreshToken?.length); - const response = await proxyAwareFetch("https://api.cline.bot/api/v1/auth/refresh", { + const response = await proxyAwareFetch(PROVIDERS.cline.refreshUrl, { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ refreshToken, grantType: "refresh_token", clientType: "extension" }) @@ -304,14 +303,14 @@ export class DefaultExecutor extends BaseExecutor { async refreshKimiCoding(refreshToken, proxyOptions = null) { const kimiHeaders = buildKimiHeaders(); - const response = await proxyAwareFetch("https://auth.kimi.com/api/oauth/token", { + const response = await proxyAwareFetch(PROVIDERS["kimi-coding"].refreshUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", ...kimiHeaders }, - body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id: "17e5f671-d194-4dfb-9706-5516cb48c098" }) + body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id: PROVIDERS["kimi-coding"].clientId }) }, proxyOptions); if (!response.ok) return null; const tokens = await response.json(); diff --git a/tests/__baseline__/current.json b/tests/__baseline__/current.json index 9bd474f8..21184027 100644 --- a/tests/__baseline__/current.json +++ b/tests/__baseline__/current.json @@ -1 +1 @@ -{"numTotalTestSuites":222,"numPassedTestSuites":205,"numFailedTestSuites":17,"numPendingTestSuites":0,"numTotalTests":827,"numPassedTests":781,"numFailedTests":26,"numPendingTests":20,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":153,"total":153,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1781356798831,"success":false,"testResults":[{"assertionResults":[{"ancestorTitles":["Antigravity → OpenAI"],"fullName":"Antigravity → OpenAI functionResponse + functionCall in same content keeps both","status":"passed","title":"functionResponse + functionCall in same content keeps both","duration":32.10974999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity → OpenAI"],"fullName":"Antigravity → OpenAI functionCall without id keeps a stable matchable id","status":"passed","title":"functionCall without id keeps a stable matchable id","duration":0.882583000000011,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity → OpenAI"],"fullName":"Antigravity → OpenAI signature-only part does not produce empty text","status":"passed","title":"signature-only part does not produce empty text","duration":0.16162499999998658,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800932,"endTime":1781356800965.1616,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-antigravity.test.js"},{"assertionResults":[{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI system array keeps all text parts","status":"passed","title":"system array keeps all text parts","duration":26.07287500000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI assistant thinking block survives Claude→Claude passthrough","status":"passed","title":"assistant thinking block survives Claude→Claude passthrough","duration":0.35395800000000577,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI redacted_thinking block is not silently dropped","status":"passed","title":"redacted_thinking block is not silently dropped","duration":3.7309160000000077,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI tool_result image block is preserved","status":"passed","title":"tool_result image block is preserved","duration":1.1629999999999825,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800790,"endTime":1781356800822.163,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-claudeCode-context.test.js"},{"assertionResults":[{"ancestorTitles":["Codex CLI Responses → OpenAI"],"fullName":"Codex CLI Responses → OpenAI assistant has no empty tool_calls array when all names are empty","status":"passed","title":"assistant has no empty tool_calls array when all names are empty","duration":27.26075,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex CLI Responses → OpenAI"],"fullName":"Codex CLI Responses → OpenAI function_call arguments end up as a string","status":"passed","title":"function_call arguments end up as a string","duration":2.4727920000000267,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex CLI Responses → OpenAI"],"fullName":"Codex CLI Responses → OpenAI input_image with file_id is not used as a raw url","status":"passed","title":"input_image with file_id is not used as a raw url","duration":0.8660419999999931,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Codex Responses (reverse)"],"fullName":"OpenAI → Codex Responses (reverse) call_id longer than 64 chars is clamped","status":"passed","title":"call_id longer than 64 chars is clamped","duration":0.31729100000001154,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800426,"endTime":1781356800457.3174,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-codexCli-responses.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI → Gemini"],"fullName":"OpenAI → Gemini multiple system messages are all kept","status":"passed","title":"multiple system messages are all kept","duration":35.177625000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Cursor"],"fullName":"OpenAI → Cursor image content is preserved","status":"passed","title":"image content is preserved","duration":1.350500000000011,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Cursor"],"fullName":"OpenAI → Cursor respects client max_tokens","status":"passed","title":"respects client max_tokens","duration":2.4422500000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → CommandCode"],"fullName":"OpenAI → CommandCode malformed tool arguments are not silently emptied","status":"passed","title":"malformed tool arguments are not silently emptied","duration":2.116624999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → CommandCode"],"fullName":"OpenAI → CommandCode image content is preserved","status":"passed","title":"image content is preserved","duration":0.6704160000000172,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801003,"endTime":1781356801045.6704,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-gemini-cursor-commandcode.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI → Kiro"],"fullName":"OpenAI → Kiro malformed tool arguments do not throw the whole request","status":"passed","title":"malformed tool arguments do not throw the whole request","duration":35.62391699999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Kiro"],"fullName":"OpenAI → Kiro respects client max_tokens","status":"passed","title":"respects client max_tokens","duration":3.8848339999999837,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Kiro"],"fullName":"OpenAI → Kiro remote image url is preserved as an image, not text","status":"passed","title":"remote image url is preserved as an image, not text","duration":3.1404579999999953,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800674,"endTime":1781356800716.1404,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-kiro.test.js"},{"assertionResults":[{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss image with source.type=url is preserved (NOT dropped)","status":"passed","title":"image with source.type=url is preserved (NOT dropped)","duration":30.274541,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss thinking block survives round-trip Claude→OpenAI→Claude","status":"passed","title":"thinking block survives round-trip Claude→OpenAI→Claude","duration":0.439707999999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss tool_result with image block is not turned into raw JSON / dropped","status":"passed","title":"tool_result with image block is not turned into raw JSON / dropped","duration":1.381208000000015,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss tool_result is_error flag is preserved","status":"passed","title":"tool_result is_error flag is preserved","duration":0.9095410000000186,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss system array non-text parts are not silently dropped","status":"passed","title":"system array non-text parts are not silently dropped","duration":0.30025000000000546,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: tool_call id stability across bridge"],"fullName":"bug: tool_call id stability across bridge sanitized tool id stays matched between call and result","status":"passed","title":"sanitized tool id stays matched between call and result","duration":0.20020900000000097,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: empty content message handling"],"fullName":"bug: empty content message handling assistant message with only tool_calls is not dropped","status":"passed","title":"assistant message with only tool_calls is not dropped","duration":0.23679099999998243,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800767,"endTime":1781356800801.3003,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-openai-bridge.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping does not inject Claude Code system prompt for compatible providers","status":"passed","title":"does not inject Claude Code system prompt for compatible providers","duration":24.96558299999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping assistant reasoning_content becomes a thinking block","status":"passed","title":"assistant reasoning_content becomes a thinking block","duration":3.0890420000000063,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping tool_choice=none is not turned into auto","status":"passed","title":"tool_choice=none is not turned into auto","duration":0.6057919999999797,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping input_audio content is preserved","status":"passed","title":"input_audio content is preserved","duration":0.6500829999999951,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping remote http image_url is preserved","status":"passed","title":"remote http image_url is preserved","duration":0.4529589999999928,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800456,"endTime":1781356800486.453,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-toClaude-context.test.js"},{"assertionResults":[{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cc': all models OpenAI→target","status":"passed","title":"'cc': all models OpenAI→target","duration":25.44579200000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cx': all models OpenAI→target","status":"passed","title":"'cx': all models OpenAI→target","duration":0.754792000000009,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gc': all models OpenAI→target","status":"passed","title":"'gc': all models OpenAI→target","duration":1.2546670000000404,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'qw': all models OpenAI→target","status":"passed","title":"'qw': all models OpenAI→target","duration":0.3078750000000241,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'if': all models OpenAI→target","status":"passed","title":"'if': all models OpenAI→target","duration":0.35412500000001046,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'ag': all models OpenAI→target","status":"passed","title":"'ag': all models OpenAI→target","duration":1.1622500000000286,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gh': all models OpenAI→target","status":"passed","title":"'gh': all models OpenAI→target","duration":0.31429199999996627,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kr': all models OpenAI→target","status":"passed","title":"'kr': all models OpenAI→target","duration":2.6300000000000523,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'qd': all models OpenAI→target","status":"passed","title":"'qd': all models OpenAI→target","duration":0.5547920000000204,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cu': all models OpenAI→target","status":"passed","title":"'cu': all models OpenAI→target","duration":0.5040830000000369,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kmc': all models OpenAI→target","status":"passed","title":"'kmc': all models OpenAI→target","duration":0.2967500000000314,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kc': all models OpenAI→target","status":"passed","title":"'kc': all models OpenAI→target","duration":3.4495829999999614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'opencode-go': all models OpenAI→target","status":"passed","title":"'opencode-go': all models OpenAI→target","duration":0.182707999999991,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'mmf': all models OpenAI→target","status":"passed","title":"'mmf': all models OpenAI→target","duration":0.04070799999999508,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cl': all models OpenAI→target","status":"passed","title":"'cl': all models OpenAI→target","duration":0.10095800000004829,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openai': all models OpenAI→target","status":"passed","title":"'openai': all models OpenAI→target","duration":0.21683400000000574,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'anthropic': all models OpenAI→target","status":"passed","title":"'anthropic': all models OpenAI→target","duration":0.06375000000002728,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gemini': all models OpenAI→target","status":"passed","title":"'gemini': all models OpenAI→target","duration":0.23212499999999636,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openrouter': all models OpenAI→target","status":"passed","title":"'openrouter': all models OpenAI→target","duration":0.1550420000000372,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'glm': all models OpenAI→target","status":"passed","title":"'glm': all models OpenAI→target","duration":0.07145900000000438,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'glm-cn': all models OpenAI→target","status":"passed","title":"'glm-cn': all models OpenAI→target","duration":0.07766699999996263,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kimi': all models OpenAI→target","status":"passed","title":"'kimi': all models OpenAI→target","duration":0.06270799999998644,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'minimax': all models OpenAI→target","status":"passed","title":"'minimax': all models OpenAI→target","duration":0.06062499999995907,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'blackbox': all models OpenAI→target","status":"passed","title":"'blackbox': all models OpenAI→target","duration":0.2114169999999831,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'minimax-cn': all models OpenAI→target","status":"passed","title":"'minimax-cn': all models OpenAI→target","duration":0.13116700000000492,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'alicode': all models OpenAI→target","status":"passed","title":"'alicode': all models OpenAI→target","duration":0.10466600000000881,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'alicode-intl': all models OpenAI→target","status":"passed","title":"'alicode-intl': all models OpenAI→target","duration":0.10674999999997681,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'volcengine-ark': all models OpenAI→target","status":"passed","title":"'volcengine-ark': all models OpenAI→target","duration":0.11954100000002654,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cloudflare-ai': all models OpenAI→target","status":"passed","title":"'cloudflare-ai': all models OpenAI→target","duration":0.16687500000000455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'byteplus': all models OpenAI→target","status":"passed","title":"'byteplus': all models OpenAI→target","duration":0.07983300000000781,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'deepseek': all models OpenAI→target","status":"passed","title":"'deepseek': all models OpenAI→target","duration":0.06729199999995217,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'commandcode': all models OpenAI→target","status":"passed","title":"'commandcode': all models OpenAI→target","duration":0.7172909999999888,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'groq': all models OpenAI→target","status":"passed","title":"'groq': all models OpenAI→target","duration":0.06541599999997061,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'xai': all models OpenAI→target","status":"passed","title":"'xai': all models OpenAI→target","duration":0.053999999999973625,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'mistral': all models OpenAI→target","status":"passed","title":"'mistral': all models OpenAI→target","duration":0.04291699999998855,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'perplexity': all models OpenAI→target","status":"passed","title":"'perplexity': all models OpenAI→target","duration":0.033833000000015545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'together': all models OpenAI→target","status":"passed","title":"'together': all models OpenAI→target","duration":0.050707999999985987,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'fireworks': all models OpenAI→target","status":"passed","title":"'fireworks': all models OpenAI→target","duration":0.0422500000000241,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cerebras': all models OpenAI→target","status":"passed","title":"'cerebras': all models OpenAI→target","duration":0.12466599999999062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cohere': all models OpenAI→target","status":"passed","title":"'cohere': all models OpenAI→target","duration":0.057458999999994376,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nvidia': all models OpenAI→target","status":"passed","title":"'nvidia': all models OpenAI→target","duration":0.03920900000002803,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nebius': all models OpenAI→target","status":"passed","title":"'nebius': all models OpenAI→target","duration":0.02866599999998698,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'voyage-ai': all models OpenAI→target","status":"passed","title":"'voyage-ai': all models OpenAI→target","duration":0.0751250000000141,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'siliconflow': all models OpenAI→target","status":"passed","title":"'siliconflow': all models OpenAI→target","duration":0.22350000000000136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'xiaomi-mimo': all models OpenAI→target","status":"passed","title":"'xiaomi-mimo': all models OpenAI→target","duration":0.06770899999997937,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'xiaomi-tokenplan': all models OpenAI→target","status":"passed","title":"'xiaomi-tokenplan': all models OpenAI→target","duration":0.11124999999998408,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'hyperbolic': all models OpenAI→target","status":"passed","title":"'hyperbolic': all models OpenAI→target","duration":0.08395899999999301,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'ollama': all models OpenAI→target","status":"passed","title":"'ollama': all models OpenAI→target","duration":0.4534580000000119,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'vertex': all models OpenAI→target","status":"passed","title":"'vertex': all models OpenAI→target","duration":0.14779200000003812,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'vertex-partner': all models OpenAI→target","status":"passed","title":"'vertex-partner': all models OpenAI→target","duration":0.05370799999997189,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'grok-web': all models OpenAI→target","status":"passed","title":"'grok-web': all models OpenAI→target","duration":0.10479200000003175,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'perplexity-web': all models OpenAI→target","status":"passed","title":"'perplexity-web': all models OpenAI→target","duration":0.06675000000001319,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openai-tts-models': all models OpenAI→target","status":"passed","title":"'openai-tts-models': all models OpenAI→target","duration":0.041249999999990905,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openai-tts-voices': all models OpenAI→target","status":"passed","title":"'openai-tts-voices': all models OpenAI→target","duration":0.12400000000002365,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openrouter-tts-models': all models OpenAI→target","status":"passed","title":"'openrouter-tts-models': all models OpenAI→target","duration":0.041542000000049484,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openrouter-tts-voices': all models OpenAI→target","status":"passed","title":"'openrouter-tts-voices': all models OpenAI→target","duration":0.18566700000002356,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'elevenlabs-tts-models': all models OpenAI→target","status":"passed","title":"'elevenlabs-tts-models': all models OpenAI→target","duration":0.0595000000000141,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'edge-tts': all models OpenAI→target","status":"passed","title":"'edge-tts': all models OpenAI→target","duration":0.11033300000002555,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'local-device': all models OpenAI→target","status":"passed","title":"'local-device': all models OpenAI→target","duration":0.025959000000000287,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'google-tts': all models OpenAI→target","status":"passed","title":"'google-tts': all models OpenAI→target","duration":0.59537499999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gemini-tts-models': all models OpenAI→target","status":"passed","title":"'gemini-tts-models': all models OpenAI→target","duration":0.04629099999999653,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gemini-tts-voices': all models OpenAI→target","status":"passed","title":"'gemini-tts-voices': all models OpenAI→target","duration":0.26895800000005465,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nanobanana': all models OpenAI→target","status":"passed","title":"'nanobanana': all models OpenAI→target","duration":0.03433300000000372,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'sdwebui': all models OpenAI→target","status":"passed","title":"'sdwebui': all models OpenAI→target","duration":0.05595799999997553,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'comfyui': all models OpenAI→target","status":"passed","title":"'comfyui': all models OpenAI→target","duration":0.03700000000003456,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'huggingface': all models OpenAI→target","status":"passed","title":"'huggingface': all models OpenAI→target","duration":0.05279200000001083,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'agentrouter': all models OpenAI→target","status":"passed","title":"'agentrouter': all models OpenAI→target","duration":0.07954200000000355,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'aimlapi': all models OpenAI→target","status":"passed","title":"'aimlapi': all models OpenAI→target","duration":0.06095800000002782,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'novita': all models OpenAI→target","status":"passed","title":"'novita': all models OpenAI→target","duration":0.05220800000000736,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'modal': all models OpenAI→target","status":"passed","title":"'modal': all models OpenAI→target","duration":0.02304199999997536,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'reka': all models OpenAI→target","status":"passed","title":"'reka': all models OpenAI→target","duration":0.03595799999999372,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nlpcloud': all models OpenAI→target","status":"passed","title":"'nlpcloud': all models OpenAI→target","duration":0.04162500000001046,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'bazaarlink': all models OpenAI→target","status":"passed","title":"'bazaarlink': all models OpenAI→target","duration":0.03216700000001538,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'completions': all models OpenAI→target","status":"passed","title":"'completions': all models OpenAI→target","duration":0.05099999999998772,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'enally': all models OpenAI→target","status":"passed","title":"'enally': all models OpenAI→target","duration":0.04345899999998437,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'freetheai': all models OpenAI→target","status":"passed","title":"'freetheai': all models OpenAI→target","duration":0.04995800000000372,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'llm7': all models OpenAI→target","status":"passed","title":"'llm7': all models OpenAI→target","duration":0.04304100000001654,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'lepton': all models OpenAI→target","status":"passed","title":"'lepton': all models OpenAI→target","duration":0.051625000000001364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kluster': all models OpenAI→target","status":"passed","title":"'kluster': all models OpenAI→target","duration":0.05041700000003857,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'ai21': all models OpenAI→target","status":"passed","title":"'ai21': all models OpenAI→target","duration":0.03337499999997817,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'inference-net': all models OpenAI→target","status":"passed","title":"'inference-net': all models OpenAI→target","duration":0.042124999999998636,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'predibase': all models OpenAI→target","status":"passed","title":"'predibase': all models OpenAI→target","duration":0.059708999999998014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'bytez': all models OpenAI→target","status":"passed","title":"'bytez': all models OpenAI→target","duration":0.09391699999997627,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'morph': all models OpenAI→target","status":"passed","title":"'morph': all models OpenAI→target","duration":0.04879199999999173,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'longcat': all models OpenAI→target","status":"passed","title":"'longcat': all models OpenAI→target","duration":0.048333000000013726,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'puter': all models OpenAI→target","status":"passed","title":"'puter': all models OpenAI→target","duration":0.07325000000003001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'uncloseai': all models OpenAI→target","status":"passed","title":"'uncloseai': all models OpenAI→target","duration":0.034207999999978256,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'scaleway': all models OpenAI→target","status":"passed","title":"'scaleway': all models OpenAI→target","duration":0.042374999999992724,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'deepinfra': all models OpenAI→target","status":"passed","title":"'deepinfra': all models OpenAI→target","duration":0.04333400000001575,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'sambanova': all models OpenAI→target","status":"passed","title":"'sambanova': all models OpenAI→target","duration":0.042416000000002896,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nscale': all models OpenAI→target","status":"passed","title":"'nscale': all models OpenAI→target","duration":0.11687499999999318,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'baseten': all models OpenAI→target","status":"passed","title":"'baseten': all models OpenAI→target","duration":0.17241599999999835,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'publicai': all models OpenAI→target","status":"passed","title":"'publicai': all models OpenAI→target","duration":0.08108299999997826,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nous-research': all models OpenAI→target","status":"passed","title":"'nous-research': all models OpenAI→target","duration":0.1013749999999618,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'glhf': all models OpenAI→target","status":"passed","title":"'glhf': all models OpenAI→target","duration":0.125458999999978,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'deepgram': all models OpenAI→target","status":"passed","title":"'deepgram': all models OpenAI→target","duration":0.18241699999998673,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'assemblyai': all models OpenAI→target","status":"passed","title":"'assemblyai': all models OpenAI→target","duration":0.11570799999998371,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'fal-ai': all models OpenAI→target","status":"passed","title":"'fal-ai': all models OpenAI→target","duration":0.09966700000001083,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'stability-ai': all models OpenAI→target","status":"passed","title":"'stability-ai': all models OpenAI→target","duration":0.06529199999999946,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'black-forest-labs': all models OpenAI→target","status":"passed","title":"'black-forest-labs': all models OpenAI→target","duration":0.0690829999999778,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'recraft': all models OpenAI→target","status":"passed","title":"'recraft': all models OpenAI→target","duration":0.03591700000004039,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'runwayml': all models OpenAI→target","status":"passed","title":"'runwayml': all models OpenAI→target","duration":0.05262499999997772,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: image-strip models drop image content"],"fullName":"coverage: image-strip models drop image content 'kr'/'deepseek-3.2' strips image when strip=[image]","status":"passed","title":"'kr'/'deepseek-3.2' strips image when strip=[image]","duration":0.19383400000003803,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: image-strip models drop image content"],"fullName":"coverage: image-strip models drop image content 'kr'/'qwen3-coder-next' strips image when strip=[image]","status":"passed","title":"'kr'/'qwen3-coder-next' strips image when strip=[image]","duration":0.05195800000001327,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800346,"endTime":1781356800393.1938,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/coverage-all-models.test.js"},{"assertionResults":[{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI system → system role","status":"passed","title":"system → system role","duration":0.8451670000000036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI tool_use → assistant.tool_calls with matching id","status":"passed","title":"tool_use → assistant.tool_calls with matching id","duration":0.2184169999999881,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI tool_result → tool message with matching id","status":"passed","title":"tool_result → tool message with matching id","duration":0.14262500000000955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI tool arguments are valid JSON string","status":"passed","title":"tool arguments are valid JSON string","duration":0.7839170000000024,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: OpenAI tools → Claude → keeps tool name"],"fullName":"roundtrip: OpenAI tools → Claude → keeps tool name tool name survives openai→claude","status":"passed","title":"tool name survives openai→claude","duration":0.3180420000000197,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: parallel tool calls keep distinct ids"],"fullName":"roundtrip: parallel tool calls keep distinct ids two tool_calls, two distinct ids","status":"passed","title":"two tool_calls, two distinct ids","duration":0.2079169999999806,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: parallel tool calls keep distinct ids"],"fullName":"roundtrip: parallel tool calls keep distinct ids each tool_call has a matching tool result","status":"passed","title":"each tool_call has a matching tool result","duration":0.24966599999999062,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801698,"endTime":1781356801701.318,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/format-roundtrip.test.js"},{"assertionResults":[{"ancestorTitles":["GOLDEN request: OpenAI → Claude"],"fullName":"GOLDEN request: OpenAI → Claude full body (system/image/tool/tool_result)","status":"passed","title":"full body (system/image/tool/tool_result)","duration":27.774707999999976,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN request: OpenAI → Claude"],"fullName":"GOLDEN request: OpenAI → Claude reasoning_effort → thinking budget","status":"passed","title":"reasoning_effort → thinking budget","duration":0.5217920000000049,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN request: OpenAI → Gemini"],"fullName":"GOLDEN request: OpenAI → Gemini full body (system/image/tool/tool_result)","status":"passed","title":"full body (system/image/tool/tool_result)","duration":1.071832999999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN request: OpenAI → Kiro"],"fullName":"GOLDEN request: OpenAI → Kiro full body (image base64 + tool_result)","status":"passed","title":"full body (image base64 + tool_result)","duration":1.9578750000000014,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800406,"endTime":1781356800437.9578,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/golden-request.test.js"},{"assertionResults":[{"ancestorTitles":["GOLDEN response stream: Claude → OpenAI"],"fullName":"GOLDEN response stream: Claude → OpenAI text + thinking + tool_use + usage + finish","status":"passed","title":"text + thinking + tool_use + usage + finish","duration":31.138041999999984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Gemini → OpenAI"],"fullName":"GOLDEN response stream: Gemini → OpenAI text + thought(no-sig) + functionCall + usage + finish","status":"passed","title":"text + thought(no-sig) + functionCall + usage + finish","duration":1.1174589999999966,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Gemini → OpenAI"],"fullName":"GOLDEN response stream: Gemini → OpenAI image output (inlineData → delta.images)","status":"passed","title":"image output (inlineData → delta.images)","duration":0.4451249999999902,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Kiro → OpenAI"],"fullName":"GOLDEN response stream: Kiro → OpenAI text + reasoning + toolUse + usage + stop","status":"passed","title":"text + reasoning + toolUse + usage + stop","duration":0.4130830000000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Ollama → OpenAI"],"fullName":"GOLDEN response stream: Ollama → OpenAI content + thinking + tool_calls + done usage","status":"passed","title":"content + thinking + tool_calls + done usage","duration":0.40850000000000364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: OpenAI-Responses (codex) → OpenAI"],"fullName":"GOLDEN response stream: OpenAI-Responses (codex) → OpenAI text + reasoning + tool_call + completed usage","status":"passed","title":"text + reasoning + tool_call + completed usage","duration":0.46283400000001507,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: OpenAI-Responses (codex) → OpenAI"],"fullName":"GOLDEN response stream: OpenAI-Responses (codex) → OpenAI error event → error chunk (fallback id/created)","status":"passed","title":"error event → error chunk (fallback id/created)","duration":0.1446250000000191,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800525,"endTime":1781356800560.1445,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/golden-response-stream.test.js"},{"assertionResults":[{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) agentrouter → url (stream + non-stream)","status":"passed","title":"agentrouter → url (stream + non-stream)","duration":1.7409999999999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) ai21 → url (stream + non-stream)","status":"passed","title":"ai21 → url (stream + non-stream)","duration":0.679165999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) aimlapi → url (stream + non-stream)","status":"passed","title":"aimlapi → url (stream + non-stream)","duration":0.48883299999999963,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) alicode → url (stream + non-stream)","status":"passed","title":"alicode → url (stream + non-stream)","duration":0.3954999999999984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) alicode-intl → url (stream + non-stream)","status":"passed","title":"alicode-intl → url (stream + non-stream)","duration":0.37462500000000887,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) anthropic → url (stream + non-stream)","status":"passed","title":"anthropic → url (stream + non-stream)","duration":0.22245800000000315,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) assemblyai → url (stream + non-stream)","status":"passed","title":"assemblyai → url (stream + non-stream)","duration":3.597208000000009,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) baseten → url (stream + non-stream)","status":"passed","title":"baseten → url (stream + non-stream)","duration":0.29145900000000324,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) bazaarlink → url (stream + non-stream)","status":"passed","title":"bazaarlink → url (stream + non-stream)","duration":1.6112500000000125,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) blackbox → url (stream + non-stream)","status":"passed","title":"blackbox → url (stream + non-stream)","duration":0.6723340000000064,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) byteplus → url (stream + non-stream)","status":"passed","title":"byteplus → url (stream + non-stream)","duration":0.35675000000000523,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) bytez → url (stream + non-stream)","status":"passed","title":"bytez → url (stream + non-stream)","duration":0.17987499999998136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cerebras → url (stream + non-stream)","status":"passed","title":"cerebras → url (stream + non-stream)","duration":0.0907500000000141,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) chutes → url (stream + non-stream)","status":"passed","title":"chutes → url (stream + non-stream)","duration":0.055292000000008557,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) claude → url (stream + non-stream)","status":"passed","title":"claude → url (stream + non-stream)","duration":0.062124999999980446,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cline → url (stream + non-stream)","status":"passed","title":"cline → url (stream + non-stream)","duration":0.11450000000002092,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cloudflare-ai → url (stream + non-stream)","status":"passed","title":"cloudflare-ai → url (stream + non-stream)","duration":1.469583,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) codebuddy → url (stream + non-stream)","status":"passed","title":"codebuddy → url (stream + non-stream)","duration":0.1073340000000087,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cohere → url (stream + non-stream)","status":"passed","title":"cohere → url (stream + non-stream)","duration":0.05966699999999037,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) completions → url (stream + non-stream)","status":"passed","title":"completions → url (stream + non-stream)","duration":0.048292000000003554,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) deepgram → url (stream + non-stream)","status":"passed","title":"deepgram → url (stream + non-stream)","duration":0.04137499999998795,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) deepinfra → url (stream + non-stream)","status":"passed","title":"deepinfra → url (stream + non-stream)","duration":0.04087499999999977,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) deepseek → url (stream + non-stream)","status":"passed","title":"deepseek → url (stream + non-stream)","duration":0.03737499999999727,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) enally → url (stream + non-stream)","status":"passed","title":"enally → url (stream + non-stream)","duration":0.04245799999998212,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) fireworks → url (stream + non-stream)","status":"passed","title":"fireworks → url (stream + non-stream)","duration":0.03654099999999971,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) freetheai → url (stream + non-stream)","status":"passed","title":"freetheai → url (stream + non-stream)","duration":0.03654099999999971,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) gemini → url (stream + non-stream)","status":"passed","title":"gemini → url (stream + non-stream)","duration":0.03808300000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) gitlab → url (stream + non-stream)","status":"passed","title":"gitlab → url (stream + non-stream)","duration":0.0352500000000191,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) glhf → url (stream + non-stream)","status":"passed","title":"glhf → url (stream + non-stream)","duration":0.03541699999999537,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) glm → url (stream + non-stream)","status":"passed","title":"glm → url (stream + non-stream)","duration":0.03816699999998718,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) glm-cn → url (stream + non-stream)","status":"passed","title":"glm-cn → url (stream + non-stream)","duration":0.03491699999997877,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) groq → url (stream + non-stream)","status":"passed","title":"groq → url (stream + non-stream)","duration":0.03608300000001918,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) hyperbolic → url (stream + non-stream)","status":"passed","title":"hyperbolic → url (stream + non-stream)","duration":0.036458000000010315,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) inference-net → url (stream + non-stream)","status":"passed","title":"inference-net → url (stream + non-stream)","duration":0.09854099999998311,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kilocode → url (stream + non-stream)","status":"passed","title":"kilocode → url (stream + non-stream)","duration":0.05700000000001637,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kimi → url (stream + non-stream)","status":"passed","title":"kimi → url (stream + non-stream)","duration":0.044375000000002274,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kimi-coding → url (stream + non-stream)","status":"passed","title":"kimi-coding → url (stream + non-stream)","duration":0.042833000000001675,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kluster → url (stream + non-stream)","status":"passed","title":"kluster → url (stream + non-stream)","duration":0.05429199999997536,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) lepton → url (stream + non-stream)","status":"passed","title":"lepton → url (stream + non-stream)","duration":0.035959000000019614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) llm7 → url (stream + non-stream)","status":"passed","title":"llm7 → url (stream + non-stream)","duration":0.036791999999991276,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) longcat → url (stream + non-stream)","status":"passed","title":"longcat → url (stream + non-stream)","duration":0.034874999999999545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) minimax → url (stream + non-stream)","status":"passed","title":"minimax → url (stream + non-stream)","duration":0.0387500000000216,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) minimax-cn → url (stream + non-stream)","status":"passed","title":"minimax-cn → url (stream + non-stream)","duration":0.03420900000000415,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) mistral → url (stream + non-stream)","status":"passed","title":"mistral → url (stream + non-stream)","duration":0.0352500000000191,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) mmf → url (stream + non-stream)","status":"passed","title":"mmf → url (stream + non-stream)","duration":0.0418329999999969,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) modal → url (stream + non-stream)","status":"passed","title":"modal → url (stream + non-stream)","duration":0.0363749999999925,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) morph → url (stream + non-stream)","status":"passed","title":"morph → url (stream + non-stream)","duration":0.03662500000001501,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nanobanana → url (stream + non-stream)","status":"passed","title":"nanobanana → url (stream + non-stream)","duration":0.14700000000001978,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nebius → url (stream + non-stream)","status":"passed","title":"nebius → url (stream + non-stream)","duration":0.04400000000001114,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nlpcloud → url (stream + non-stream)","status":"passed","title":"nlpcloud → url (stream + non-stream)","duration":0.03795800000000327,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nous-research → url (stream + non-stream)","status":"passed","title":"nous-research → url (stream + non-stream)","duration":0.03670900000000188,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) novita → url (stream + non-stream)","status":"passed","title":"novita → url (stream + non-stream)","duration":0.03699999999997772,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nscale → url (stream + non-stream)","status":"passed","title":"nscale → url (stream + non-stream)","duration":0.036417000000000144,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nvidia → url (stream + non-stream)","status":"passed","title":"nvidia → url (stream + non-stream)","duration":0.035124999999993634,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) ollama → url (stream + non-stream)","status":"passed","title":"ollama → url (stream + non-stream)","duration":0.03795800000000327,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) openai → url (stream + non-stream)","status":"passed","title":"openai → url (stream + non-stream)","duration":0.035916999999983545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) openrouter → url (stream + non-stream)","status":"passed","title":"openrouter → url (stream + non-stream)","duration":0.03550000000001319,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) perplexity → url (stream + non-stream)","status":"passed","title":"perplexity → url (stream + non-stream)","duration":0.03845900000001734,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) predibase → url (stream + non-stream)","status":"passed","title":"predibase → url (stream + non-stream)","duration":0.03499999999999659,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) publicai → url (stream + non-stream)","status":"passed","title":"publicai → url (stream + non-stream)","duration":0.03533400000000597,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) puter → url (stream + non-stream)","status":"passed","title":"puter → url (stream + non-stream)","duration":0.03483399999998937,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) reka → url (stream + non-stream)","status":"passed","title":"reka → url (stream + non-stream)","duration":0.03499999999999659,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) sambanova → url (stream + non-stream)","status":"passed","title":"sambanova → url (stream + non-stream)","duration":0.03499999999999659,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) scaleway → url (stream + non-stream)","status":"passed","title":"scaleway → url (stream + non-stream)","duration":0.03666699999999423,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) siliconflow → url (stream + non-stream)","status":"passed","title":"siliconflow → url (stream + non-stream)","duration":0.03695799999999849,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) together → url (stream + non-stream)","status":"passed","title":"together → url (stream + non-stream)","duration":0.03483399999998937,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) uncloseai → url (stream + non-stream)","status":"passed","title":"uncloseai → url (stream + non-stream)","duration":0.034707999999994854,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) vercel-ai-gateway → url (stream + non-stream)","status":"passed","title":"vercel-ai-gateway → url (stream + non-stream)","duration":0.03500000000002501,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) volcengine-ark → url (stream + non-stream)","status":"passed","title":"volcengine-ark → url (stream + non-stream)","duration":0.03729199999997945,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) xai → url (stream + non-stream)","status":"passed","title":"xai → url (stream + non-stream)","duration":0.036000000000001364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) xiaomi-mimo → url (stream + non-stream)","status":"passed","title":"xiaomi-mimo → url (stream + non-stream)","duration":0.0347500000000025,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) agentrouter → headers (apiKey / oauth)","status":"passed","title":"agentrouter → headers (apiKey / oauth)","duration":0.5238749999999754,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) ai21 → headers (apiKey / oauth)","status":"passed","title":"ai21 → headers (apiKey / oauth)","duration":0.0903329999999869,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) aimlapi → headers (apiKey / oauth)","status":"passed","title":"aimlapi → headers (apiKey / oauth)","duration":0.18629199999998036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) alicode → headers (apiKey / oauth)","status":"passed","title":"alicode → headers (apiKey / oauth)","duration":0.06962500000000205,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) alicode-intl → headers (apiKey / oauth)","status":"passed","title":"alicode-intl → headers (apiKey / oauth)","duration":0.061833999999976186,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) anthropic → headers (apiKey / oauth)","status":"passed","title":"anthropic → headers (apiKey / oauth)","duration":0.08766700000001038,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) assemblyai → headers (apiKey / oauth)","status":"passed","title":"assemblyai → headers (apiKey / oauth)","duration":0.09850000000000136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) baseten → headers (apiKey / oauth)","status":"passed","title":"baseten → headers (apiKey / oauth)","duration":0.06662499999998772,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) bazaarlink → headers (apiKey / oauth)","status":"passed","title":"bazaarlink → headers (apiKey / oauth)","duration":0.06570800000000077,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) blackbox → headers (apiKey / oauth)","status":"passed","title":"blackbox → headers (apiKey / oauth)","duration":0.06741700000000606,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) byteplus → headers (apiKey / oauth)","status":"passed","title":"byteplus → headers (apiKey / oauth)","duration":1.2695410000000038,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) bytez → headers (apiKey / oauth)","status":"passed","title":"bytez → headers (apiKey / oauth)","duration":0.28358299999999304,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cerebras → headers (apiKey / oauth)","status":"passed","title":"cerebras → headers (apiKey / oauth)","duration":0.18629199999998036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) chutes → headers (apiKey / oauth)","status":"passed","title":"chutes → headers (apiKey / oauth)","duration":0.16362499999999613,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) claude → headers (apiKey / oauth)","status":"passed","title":"claude → headers (apiKey / oauth)","duration":0.3548330000000135,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cline → headers (apiKey / oauth)","status":"passed","title":"cline → headers (apiKey / oauth)","duration":0.21341599999999517,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cloudflare-ai → headers (apiKey / oauth)","status":"passed","title":"cloudflare-ai → headers (apiKey / oauth)","duration":0.06525000000002024,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) codebuddy → headers (apiKey / oauth)","status":"passed","title":"codebuddy → headers (apiKey / oauth)","duration":0.0604590000000087,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cohere → headers (apiKey / oauth)","status":"passed","title":"cohere → headers (apiKey / oauth)","duration":0.05262500000000614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) completions → headers (apiKey / oauth)","status":"passed","title":"completions → headers (apiKey / oauth)","duration":0.05150000000000432,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) deepgram → headers (apiKey / oauth)","status":"passed","title":"deepgram → headers (apiKey / oauth)","duration":0.0503750000000025,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) deepinfra → headers (apiKey / oauth)","status":"passed","title":"deepinfra → headers (apiKey / oauth)","duration":0.04925000000000068,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) deepseek → headers (apiKey / oauth)","status":"passed","title":"deepseek → headers (apiKey / oauth)","duration":0.04954200000000242,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) enally → headers (apiKey / oauth)","status":"passed","title":"enally → headers (apiKey / oauth)","duration":0.05383400000002325,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) fireworks → headers (apiKey / oauth)","status":"passed","title":"fireworks → headers (apiKey / oauth)","duration":0.049000000000006594,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) freetheai → headers (apiKey / oauth)","status":"passed","title":"freetheai → headers (apiKey / oauth)","duration":0.048916999999988775,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) gemini → headers (apiKey / oauth)","status":"passed","title":"gemini → headers (apiKey / oauth)","duration":0.05866699999998559,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) gitlab → headers (apiKey / oauth)","status":"passed","title":"gitlab → headers (apiKey / oauth)","duration":0.049000000000006594,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) glhf → headers (apiKey / oauth)","status":"passed","title":"glhf → headers (apiKey / oauth)","duration":0.0489170000000172,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) glm → headers (apiKey / oauth)","status":"passed","title":"glm → headers (apiKey / oauth)","duration":0.07183399999999551,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) glm-cn → headers (apiKey / oauth)","status":"passed","title":"glm-cn → headers (apiKey / oauth)","duration":0.05020799999999781,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) groq → headers (apiKey / oauth)","status":"passed","title":"groq → headers (apiKey / oauth)","duration":0.04858400000000529,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) hyperbolic → headers (apiKey / oauth)","status":"passed","title":"hyperbolic → headers (apiKey / oauth)","duration":0.04866700000002311,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) inference-net → headers (apiKey / oauth)","status":"passed","title":"inference-net → headers (apiKey / oauth)","duration":0.05000000000001137,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kilocode → headers (apiKey / oauth)","status":"passed","title":"kilocode → headers (apiKey / oauth)","duration":0.05054200000000719,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kimi → headers (apiKey / oauth)","status":"passed","title":"kimi → headers (apiKey / oauth)","duration":0.05700000000001637,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kimi-coding → headers (apiKey / oauth)","status":"passed","title":"kimi-coding → headers (apiKey / oauth)","duration":0.13283299999997666,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kluster → headers (apiKey / oauth)","status":"passed","title":"kluster → headers (apiKey / oauth)","duration":0.06954200000001265,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) lepton → headers (apiKey / oauth)","status":"passed","title":"lepton → headers (apiKey / oauth)","duration":0.24670799999998394,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) llm7 → headers (apiKey / oauth)","status":"passed","title":"llm7 → headers (apiKey / oauth)","duration":0.09637499999999477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) longcat → headers (apiKey / oauth)","status":"passed","title":"longcat → headers (apiKey / oauth)","duration":0.06787499999998658,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) minimax → headers (apiKey / oauth)","status":"passed","title":"minimax → headers (apiKey / oauth)","duration":0.10241600000000517,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) minimax-cn → headers (apiKey / oauth)","status":"passed","title":"minimax-cn → headers (apiKey / oauth)","duration":0.10429200000001515,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) mistral → headers (apiKey / oauth)","status":"passed","title":"mistral → headers (apiKey / oauth)","duration":0.06787499999998658,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) mmf → headers (apiKey / oauth)","status":"passed","title":"mmf → headers (apiKey / oauth)","duration":0.0619999999999834,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) modal → headers (apiKey / oauth)","status":"passed","title":"modal → headers (apiKey / oauth)","duration":0.052957999999989624,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) morph → headers (apiKey / oauth)","status":"passed","title":"morph → headers (apiKey / oauth)","duration":0.05187499999999545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nanobanana → headers (apiKey / oauth)","status":"passed","title":"nanobanana → headers (apiKey / oauth)","duration":0.06691699999998946,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nebius → headers (apiKey / oauth)","status":"passed","title":"nebius → headers (apiKey / oauth)","duration":0.07137500000001751,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nlpcloud → headers (apiKey / oauth)","status":"passed","title":"nlpcloud → headers (apiKey / oauth)","duration":0.060374999999993406,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nous-research → headers (apiKey / oauth)","status":"passed","title":"nous-research → headers (apiKey / oauth)","duration":0.0498749999999859,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) novita → headers (apiKey / oauth)","status":"passed","title":"novita → headers (apiKey / oauth)","duration":0.5615840000000105,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nscale → headers (apiKey / oauth)","status":"passed","title":"nscale → headers (apiKey / oauth)","duration":0.2506670000000213,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nvidia → headers (apiKey / oauth)","status":"passed","title":"nvidia → headers (apiKey / oauth)","duration":0.18287499999999568,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) ollama → headers (apiKey / oauth)","status":"passed","title":"ollama → headers (apiKey / oauth)","duration":0.1672500000000241,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) openai → headers (apiKey / oauth)","status":"passed","title":"openai → headers (apiKey / oauth)","duration":0.16108299999999076,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) openrouter → headers (apiKey / oauth)","status":"passed","title":"openrouter → headers (apiKey / oauth)","duration":0.19849999999999568,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) perplexity → headers (apiKey / oauth)","status":"passed","title":"perplexity → headers (apiKey / oauth)","duration":0.15254199999998264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) predibase → headers (apiKey / oauth)","status":"passed","title":"predibase → headers (apiKey / oauth)","duration":0.1393330000000219,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) publicai → headers (apiKey / oauth)","status":"passed","title":"publicai → headers (apiKey / oauth)","duration":0.13645800000000463,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) puter → headers (apiKey / oauth)","status":"passed","title":"puter → headers (apiKey / oauth)","duration":0.13570799999999394,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) reka → headers (apiKey / oauth)","status":"passed","title":"reka → headers (apiKey / oauth)","duration":0.1339580000000069,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) sambanova → headers (apiKey / oauth)","status":"passed","title":"sambanova → headers (apiKey / oauth)","duration":0.13091700000001083,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) scaleway → headers (apiKey / oauth)","status":"passed","title":"scaleway → headers (apiKey / oauth)","duration":0.13008400000001075,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) siliconflow → headers (apiKey / oauth)","status":"passed","title":"siliconflow → headers (apiKey / oauth)","duration":0.12904199999999832,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) together → headers (apiKey / oauth)","status":"passed","title":"together → headers (apiKey / oauth)","duration":0.12929099999999494,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) uncloseai → headers (apiKey / oauth)","status":"passed","title":"uncloseai → headers (apiKey / oauth)","duration":0.13229200000000674,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) vercel-ai-gateway → headers (apiKey / oauth)","status":"passed","title":"vercel-ai-gateway → headers (apiKey / oauth)","duration":0.1410410000000013,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) volcengine-ark → headers (apiKey / oauth)","status":"passed","title":"volcengine-ark → headers (apiKey / oauth)","duration":0.13045900000000188,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) xai → headers (apiKey / oauth)","status":"passed","title":"xai → headers (apiKey / oauth)","duration":0.13283299999997666,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) xiaomi-mimo → headers (apiKey / oauth)","status":"passed","title":"xiaomi-mimo → headers (apiKey / oauth)","duration":0.1341250000000116,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801215,"endTime":1781356801240.141,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/golden-url-header.test.js"},{"assertionResults":[{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) has at least one active AG connection with refreshToken","status":"skipped","title":"has at least one active AG connection with refreshToken","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) same sessionId → cache hit on repeated call","status":"skipped","title":"same sessionId → cache hit on repeated call","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) different sessionId (same account) → cache still hits (session-independent)","status":"skipped","title":"different sessionId (same account) → cache still hits (session-independent)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) cross-account → cache SHARED (content-based global cache)","status":"skipped","title":"cross-account → cache SHARED (content-based global cache)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) codex-style sessionId vs random sessionId on unique prompt","status":"skipped","title":"codex-style sessionId vs random sessionId on unique prompt","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) unique prompt (never seen) → explore when cache starts hitting","status":"skipped","title":"unique prompt (never seen) → explore when cache starts hitting","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356798831,"endTime":1781356798831,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/antigravity-cache.test.js"},{"assertionResults":[{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling flags the out-of-box agent/Default model mandatory","status":"failed","title":"flags the out-of-box agent/Default model mandatory","duration":3.4038749999999993,"failureMessages":["AssertionError: expected undefined to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/antigravity-mitm.test.js:17:86\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling leaves models not proven auto-sent optional","status":"passed","title":"leaves models not proven auto-sent optional","duration":0.28191699999999287,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling excludes tab-autocomplete model 'tab_jump_flash_lite_preview' from re-routing","status":"passed","title":"excludes tab-autocomplete model 'tab_jump_flash_lite_preview' from re-routing","duration":0.0972500000000025,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling excludes tab-autocomplete model 'tab_flash_lite_preview' from re-routing","status":"passed","title":"excludes tab-autocomplete model 'tab_flash_lite_preview' from re-routing","duration":0.16591700000000742,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling does not exclude real agent models from re-routing","status":"passed","title":"does not exclude real agent models from re-routing","duration":0.13591700000000628,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799208,"endTime":1781356799212.166,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/antigravity-mitm.test.js"},{"assertionResults":[{"ancestorTitles":["PR #1175 - buildOutput filter detection"],"fullName":"PR #1175 - buildOutput filter detection detects npm install output","status":"passed","title":"detects npm install output","duration":1.096790999999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput filter detection"],"fullName":"PR #1175 - buildOutput filter detection detects cargo build output (no longer misdetected as git-status)","status":"passed","title":"detects cargo build output (no longer misdetected as git-status)","duration":0.6052919999999915,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior compresses npm install with deprecations","status":"passed","title":"compresses npm install with deprecations","duration":0.8997909999999933,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior compresses cargo build output","status":"passed","title":"compresses cargo build output","duration":0.2648749999999893,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior keeps cargo errors verbatim","status":"passed","title":"keeps cargo errors verbatim","duration":0.12379099999998289,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior keeps maven BUILD FAILED as error","status":"passed","title":"keeps maven BUILD FAILED as error","duration":0.36379199999998946,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases git status --porcelain workdir-only (space first char) STILL detects as gitStatus (minimal fix preserved old regex)","status":"passed","title":"git status --porcelain workdir-only (space first char) STILL detects as gitStatus (minimal fix preserved old regex)","duration":0.4957080000000076,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases git status --porcelain with staged (status code first char) still detects","status":"passed","title":"git status --porcelain with staged (status code first char) still detects","duration":0.0979159999999979,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases cargo Compiling lines NOT detected as git-status (porcelain false positive fix)","status":"passed","title":"cargo Compiling lines NOT detected as git-status (porcelain false positive fix)","duration":0.5694589999999948,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases long-form git status with 'On branch' always detects","status":"passed","title":"long-form git status with 'On branch' always detects","duration":0.140041999999994,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - false positive risks"],"fullName":"PR #1175 - false positive risks generic app log with 'ERROR:' triggers buildOutput (potential false positive)","status":"passed","title":"generic app log with 'ERROR:' triggers buildOutput (potential false positive)","duration":0.6163329999999974,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - false positive risks"],"fullName":"PR #1175 - false positive risks generic 'Compiling templates' (non-build context) triggers buildOutput","status":"passed","title":"generic 'Compiling templates' (non-build context) triggers buildOutput","duration":0.29854199999999764,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - false positive risks"],"fullName":"PR #1175 - false positive risks plain text with no patterns falls through (no false positive)","status":"passed","title":"plain text with no patterns falls through (no false positive)","duration":0.3789999999999907,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption empty input returns input","status":"passed","title":"empty input returns input","duration":0.3407499999999857,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption input with only errors preserves all errors","status":"passed","title":"input with only errors preserves all errors","duration":0.19133400000001188,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption input with no recognized patterns returns input (fallback)","status":"passed","title":"input with no recognized patterns returns input (fallback)","duration":0.14066700000000765,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption limits warnings to 5 + summary line","status":"passed","title":"limits warnings to 5 + summary line","duration":0.21883300000001782,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801577,"endTime":1781356801584.2188,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/buildOutputFilter.test.js"},{"assertionResults":[{"ancestorTitles":["PR #1175 - priority with overlapping patterns"],"fullName":"PR #1175 - priority with overlapping patterns git-diff wins over buildOutput when both present","status":"passed","title":"git-diff wins over buildOutput when both present","duration":2.2311249999999916,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - priority with overlapping patterns"],"fullName":"PR #1175 - priority with overlapping patterns git-status (long form) wins over buildOutput","status":"passed","title":"git-status (long form) wins over buildOutput","duration":0.3574169999999981,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - DETECT_WINDOW boundary"],"fullName":"PR #1175 - DETECT_WINDOW boundary build pattern beyond DETECT_WINDOW chars: NOT detected","status":"passed","title":"build pattern beyond DETECT_WINDOW chars: NOT detected","duration":0.7953339999999969,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - DETECT_WINDOW boundary"],"fullName":"PR #1175 - DETECT_WINDOW boundary build pattern at very start: detected","status":"passed","title":"build pattern at very start: detected","duration":0.5935000000000059,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - line endings & whitespace"],"fullName":"PR #1175 - line endings & whitespace CRLF line endings still detect","status":"passed","title":"CRLF line endings still detect","duration":0.205916000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - line endings & whitespace"],"fullName":"PR #1175 - line endings & whitespace Tab-prefixed Compiling (real cargo output uses leading spaces, not tab)","status":"passed","title":"Tab-prefixed Compiling (real cargo output uses leading spaces, not tab)","duration":0.15662499999999113,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - line endings & whitespace"],"fullName":"PR #1175 - line endings & whitespace Compiling without leading spaces","status":"passed","title":"Compiling without leading spaces","duration":0.27658400000001393,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - adversarial: user code containing build strings"],"fullName":"PR #1175 - adversarial: user code containing build strings user JS code with console.log('npm warn ...') triggers buildOutput","status":"passed","title":"user JS code with console.log('npm warn ...') triggers buildOutput","duration":1.585583000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - adversarial: user code containing build strings"],"fullName":"PR #1175 - adversarial: user code containing build strings file content with 'BUILD SUCCESS' on its own line triggers buildOutput","status":"passed","title":"file content with 'BUILD SUCCESS' on its own line triggers buildOutput","duration":2.5590830000000153,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - adversarial: user code containing build strings"],"fullName":"PR #1175 - adversarial: user code containing build strings real cargo error spanning multiple lines preserves context","status":"passed","title":"real cargo error spanning multiple lines preserves context","duration":1.4699589999999887,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety input with only progress lines (no errors/warnings/summary) returns input fallback","status":"passed","title":"input with only progress lines (no errors/warnings/summary) returns input fallback","duration":0.477958000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety input with only Downloading lines","status":"passed","title":"input with only Downloading lines","duration":0.18274999999999864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety input with ONLY a single ERROR: line","status":"passed","title":"input with ONLY a single ERROR: line","duration":0.12545800000000895,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety unicode/emoji in deprecation warning preserved (minimal fix keeps first 3 verbatim)","status":"passed","title":"unicode/emoji in deprecation warning preserved (minimal fix keeps first 3 verbatim)","duration":1.0197080000000085,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety more than 3 deprecations: keep first 3 verbatim + count rest","status":"passed","title":"more than 3 deprecations: keep first 3 verbatim + count rest","duration":0.27133399999999597,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety safeApply wraps buildOutput against panics","status":"passed","title":"safeApply wraps buildOutput against panics","duration":0.27454099999999926,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages npm install output above MIN_COMPRESS_SIZE → compressed","status":"passed","title":"npm install output above MIN_COMPRESS_SIZE → compressed","duration":0.7558750000000032,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages input below MIN_COMPRESS_SIZE → NOT compressed","status":"passed","title":"input below MIN_COMPRESS_SIZE → NOT compressed","duration":0.09895800000001032,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages compressed output never grows input (safety guard)","status":"passed","title":"compressed output never grows input (safety guard)","duration":0.09379200000000765,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages tool_result with is_error:true is NOT compressed (preserve error traces)","status":"passed","title":"tool_result with is_error:true is NOT compressed (preserve error traces)","duration":0.14449999999999363,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regression deeper"],"fullName":"PR #1175 - porcelain regression deeper mixed staged + workdir + untracked porcelain → detected (has status code first char)","status":"passed","title":"mixed staged + workdir + untracked porcelain → detected (has status code first char)","duration":0.07824999999999704,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regression deeper"],"fullName":"PR #1175 - porcelain regression deeper 100% workdir-only porcelain → STILL detects gitStatus (minimal fix preserved old regex)","status":"passed","title":"100% workdir-only porcelain → STILL detects gitStatus (minimal fix preserved old regex)","duration":0.05608399999999847,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regression deeper"],"fullName":"PR #1175 - porcelain regression deeper manual gitStatus() call on workdir-only porcelain still parses correctly","status":"passed","title":"manual gitStatus() call on workdir-only porcelain still parses correctly","duration":0.2847500000000025,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological very long single line (no newlines) with build pattern","status":"passed","title":"very long single line (no newlines) with build pattern","duration":0.08816699999999855,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological 10000 Compiling lines don't crash","status":"passed","title":"10000 Compiling lines don't crash","duration":10.926999999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological input with only newlines","status":"passed","title":"input with only newlines","duration":0.0932499999999834,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological null/undefined safety via safeApply","status":"passed","title":"null/undefined safety via safeApply","duration":0.45087499999999636,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801333,"endTime":1781356801360.451,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/buildOutputFilterAdversarial.test.js"},{"assertionResults":[{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools suffixes client tool names and maps them back","status":"passed","title":"suffixes client tool names and maps them back","duration":0.910624999999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools suffixes a forced tool_choice to match the renamed tool","status":"passed","title":"suffixes a forced tool_choice to match the renamed tool","duration":0.3718340000000069,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools suffixes only the chosen tool when several are present","status":"passed","title":"suffixes only the chosen tool when several are present","duration":0.14216600000000312,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools leaves non-forced tool_choice untouched","status":"passed","title":"leaves non-forced tool_choice untouched","duration":0.16241600000000744,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools does not suffix a forced choice that targets a non-client (decoy/built-in) tool","status":"passed","title":"does not suffix a forced choice that targets a non-client (decoy/built-in) tool","duration":0.07850000000000534,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools renames tool_use names in message history","status":"passed","title":"renames tool_use names in message history","duration":0.06624999999999659,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools returns the body unchanged when there are no tools","status":"passed","title":"returns the body unchanged when there are no tools","duration":0.38920799999999645,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801861,"endTime":1781356801863.3892,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/claude-cloaking.test.js"},{"assertionResults":[{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache returns null before any headers are cached (cold start)","status":"passed","title":"returns null before any headers are cached (cold start)","duration":12.434791999999987,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache caches headers when user-agent contains 'claude-code'","status":"passed","title":"caches headers when user-agent contains 'claude-code'","duration":1.389916999999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache caches headers when user-agent contains 'claude-cli'","status":"passed","title":"caches headers when user-agent contains 'claude-cli'","duration":0.4409170000000131,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache caches headers when x-app is 'cli' (regardless of user-agent)","status":"passed","title":"caches headers when x-app is 'cli' (regardless of user-agent)","duration":0.35316700000001333,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache does NOT cache headers for non-Claude clients","status":"passed","title":"does NOT cache headers for non-Claude clients","duration":0.22812500000000568,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache refreshes cache on each matching request","status":"passed","title":"refreshes cache on each matching request","duration":0.30270799999999554,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache ignores calls with null or non-object headers","status":"passed","title":"ignores calls with null or non-object headers","duration":0.37383299999999053,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache only stores keys that are actually present in the headers object","status":"passed","title":"only stores keys that are actually present in the headers object","duration":0.4491249999999809,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider overlays live cached headers over static provider defaults","status":"passed","title":"overlays live cached headers over static provider defaults","duration":138.536,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider removes conflicting Title-Case static keys when cached lowercase keys exist","status":"passed","title":"removes conflicting Title-Case static keys when cached lowercase keys exist","duration":3.6477500000000305,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider sets x-api-key auth when apiKey is provided","status":"passed","title":"sets x-api-key auth when apiKey is provided","duration":4.6749169999999935,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider sets Bearer Authorization when only accessToken is provided","status":"passed","title":"sets Bearer Authorization when only accessToken is provided","duration":2.27883300000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider includes Accept: text/event-stream when stream=true","status":"passed","title":"includes Accept: text/event-stream when stream=true","duration":1.5009580000000255,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider omits Accept: text/event-stream when stream=false","status":"passed","title":"omits Accept: text/event-stream when stream=false","duration":1.3474579999999605,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider cold start (no cache)"],"fullName":"DefaultExecutor.buildHeaders() — claude provider cold start (no cache) falls back to static provider headers when cache is empty","status":"passed","title":"falls back to static provider headers when cache is empty","duration":3.2944590000000176,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider cold start (no cache)"],"fullName":"DefaultExecutor.buildHeaders() — claude provider cold start (no cache) does not throw when cache returns null","status":"passed","title":"does not throw when cache returns null","duration":3.6939590000000067,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping strips x-app and anthropic-dangerous-direct-browser-access for non-Anthropic host","status":"passed","title":"strips x-app and anthropic-dangerous-direct-browser-access for non-Anthropic host","duration":2.4891250000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping removes claude-code-20250219 from anthropic-beta for non-Anthropic host","status":"passed","title":"removes claude-code-20250219 from anthropic-beta for non-Anthropic host","duration":1.248125000000016,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping keeps other beta flags intact after stripping","status":"passed","title":"keeps other beta flags intact after stripping","duration":0.8671659999999974,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping does NOT strip headers when baseUrl is api.anthropic.com","status":"passed","title":"does NOT strip headers when baseUrl is api.anthropic.com","duration":1.1487920000000145,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping does NOT strip headers when baseUrl is empty (defaults to Anthropic)","status":"passed","title":"does NOT strip headers when baseUrl is empty (defaults to Anthropic)","duration":0.9472499999999968,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["proxyAwareFetch — api.anthropic.com routing"],"fullName":"proxyAwareFetch — api.anthropic.com routing routes api.anthropic.com to gotScraping (non-streaming) and returns ok response","status":"failed","title":"routes api.anthropic.com to gotScraping (non-streaming) and returns ok response","duration":434.80629200000004,"failureMessages":["AssertionError: expected \"vi.fn()\" to be called once, but got 0 times\n at /Users/Working/router4/app/tests/unit/claude-header-forwarding.test.js:354:25\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["proxyAwareFetch — api.anthropic.com routing"],"fullName":"proxyAwareFetch — api.anthropic.com routing falls back gracefully when got-scraping throws on non-streaming path","status":"passed","title":"falls back gracefully when got-scraping throws on non-streaming path","duration":3.5036249999999427,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["proxyAwareFetch — api.anthropic.com routing"],"fullName":"proxyAwareFetch — api.anthropic.com routing does NOT route non-Anthropic hosts through gotScraping","status":"passed","title":"does NOT route non-Anthropic hosts through gotScraping","duration":1.1215419999999767,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799197,"endTime":1781356799818.1216,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/claude-header-forwarding.test.js"},{"assertionResults":[{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling fetches 1MB remote image and inlines it as base64 data URI","status":"passed","title":"fetches 1MB remote image and inlines it as base64 data URI","duration":4.015334000000024,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling passes through existing data URIs without calling fetch","status":"passed","title":"passes through existing data URIs without calling fetch","duration":0.4283750000000168,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling falls back to original URL when remote fetch fails","status":"passed","title":"falls back to original URL when remote fetch fails","duration":0.5550839999999937,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling execute() prefetches images before sending to upstream","status":"passed","title":"execute() prefetches images before sending to upstream","duration":25.551582999999994,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800564,"endTime":1781356800594.5515,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/codex-image-fetch.test.js"},{"assertionResults":[{"ancestorTitles":["Codex Refresh Token","refreshCodexToken"],"fullName":"Codex Refresh Token refreshCodexToken should return new refresh_token when server provides one (token rotation)","status":"passed","title":"should return new refresh_token when server provides one (token rotation)","duration":17.935374999999993,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","refreshCodexToken"],"fullName":"Codex Refresh Token refreshCodexToken should keep old refresh_token when server does not return new one","status":"passed","title":"should keep old refresh_token when server does not return new one","duration":2.1492920000000026,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","CodexExecutor credential lifecycle"],"fullName":"Codex Refresh Token CodexExecutor credential lifecycle should refresh Codex credentials and preserve omitted id_token","status":"passed","title":"should refresh Codex credentials and preserve omitted id_token","duration":129.344042,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","CodexExecutor credential lifecycle"],"fullName":"Codex Refresh Token CodexExecutor credential lifecycle should refresh Codex when lastRefreshAt is older than the upstream stale window","status":"passed","title":"should refresh Codex when lastRefreshAt is older than the upstream stale window","duration":24.75150000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","CodexExecutor credential lifecycle"],"fullName":"Codex Refresh Token CodexExecutor credential lifecycle should de-duplicate concurrent refreshes for the same Codex connection","status":"passed","title":"should de-duplicate concurrent refreshes for the same Codex connection","duration":3.8986249999999814,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","getRefreshLeadMs (early refresh config)"],"fullName":"Codex Refresh Token getRefreshLeadMs (early refresh config) should return provider-specific lead time for OAuth providers","status":"passed","title":"should return provider-specific lead time for OAuth providers","duration":2.728666999999973,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","getRefreshLeadMs (early refresh config)"],"fullName":"Codex Refresh Token getRefreshLeadMs (early refresh config) should fallback to default buffer for unknown providers","status":"passed","title":"should fallback to default buffer for unknown providers","duration":1.5658750000000055,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","getRefreshLeadMs (early refresh config)"],"fullName":"Codex Refresh Token getRefreshLeadMs (early refresh config) codex lead should be greater than default buffer","status":"passed","title":"codex lead should be greater than default buffer","duration":1.5772910000000024,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799646,"endTime":1781356799830.5774,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/codex-refresh-token.test.js"},{"assertionResults":[{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing keeps existing one-request round-robin behavior by default","status":"passed","title":"keeps existing one-request round-robin behavior by default","duration":1.2439580000000063,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing sticks to each combo model for the configured number of requests","status":"passed","title":"sticks to each combo model for the configured number of requests","duration":0.25654199999999605,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing tracks sticky rotation independently per combo","status":"passed","title":"tracks sticky rotation independently per combo","duration":0.19370800000000088,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing does not rotate fallback combos","status":"passed","title":"does not rotate fallback combos","duration":0.2149169999999998,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801889,"endTime":1781356801890.2566,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/combo-routing.test.js"},{"assertionResults":[{"ancestorTitles":["commandcode-to-openai — text-delta"],"fullName":"commandcode-to-openai — text-delta emits assistant role on first delta then content-only","status":"passed","title":"emits assistant role on first delta then content-only","duration":1.9541250000000048,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — reasoning-delta"],"fullName":"commandcode-to-openai — reasoning-delta maps reasoning-delta to reasoning_content delta","status":"passed","title":"maps reasoning-delta to reasoning_content delta","duration":0.20025000000001114,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — tool-input-* with id field (live schema)"],"fullName":"commandcode-to-openai — tool-input-* with id field (live schema) registers tool index using event.id (NOT toolCallId)","status":"passed","title":"registers tool index using event.id (NOT toolCallId)","duration":0.5131250000000023,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — tool-input-* with id field (live schema)"],"fullName":"commandcode-to-openai — tool-input-* with id field (live schema) ignores tool-input-delta when id is unknown (no prior start)","status":"passed","title":"ignores tool-input-delta when id is unknown (no prior start)","duration":0.21625000000000227,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — final tool-call event"],"fullName":"commandcode-to-openai — final tool-call event does NOT re-emit tool_calls when tool-input-* deltas already fired","status":"passed","title":"does NOT re-emit tool_calls when tool-input-* deltas already fired","duration":0.39570800000001327,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — final tool-call event"],"fullName":"commandcode-to-openai — final tool-call event emits a consolidated tool_calls when only the final tool-call event arrives","status":"passed","title":"emits a consolidated tool_calls when only the final tool-call event arrives","duration":0.1983330000000194,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — finish"],"fullName":"commandcode-to-openai — finish emits a final chunk with finish_reason=tool_calls when finishReason is tool-calls","status":"passed","title":"emits a final chunk with finish_reason=tool_calls when finishReason is tool-calls","duration":0.17600000000001614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — finish"],"fullName":"commandcode-to-openai — finish includes usage on the final chunk when totalUsage provided","status":"passed","title":"includes usage on the final chunk when totalUsage provided","duration":0.35970899999998096,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — error event"],"fullName":"commandcode-to-openai — error event stringifies object errors so client sees readable message","status":"passed","title":"stringifies object errors so client sees readable message","duration":0.5857919999999979,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801763,"endTime":1781356801768.5857,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/commandcode-to-openai.test.js"},{"assertionResults":[{"ancestorTitles":["compatible provider connections API"],"fullName":"compatible provider connections API creates one API-key connection for an OpenAI-compatible node","status":"passed","title":"creates one API-key connection for an OpenAI-compatible node","duration":178.28779199999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["compatible provider connections API"],"fullName":"compatible provider connections API creates one API-key connection for an Anthropic-compatible node","status":"passed","title":"creates one API-key connection for an Anthropic-compatible node","duration":7.7003330000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["compatible provider connections API"],"fullName":"compatible provider connections API returns 400 for a duplicate connection on the same compatible node","status":"passed","title":"returns 400 for a duplicate connection on the same compatible node","duration":14.230875000000026,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799618,"endTime":1781356799818.231,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/compatible-provider-connections.test.js"},{"assertionResults":[{"ancestorTitles":["CursorExecutor Composer thinking-field responses"],"fullName":"CursorExecutor Composer thinking-field responses uses visible content after for non-streaming Composer responses","status":"passed","title":"uses visible content after for non-streaming Composer responses","duration":12.825167000000022,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CursorExecutor Composer thinking-field responses"],"fullName":"CursorExecutor Composer thinking-field responses streams only visible content after for Composer responses","status":"passed","title":"streams only visible content after for Composer responses","duration":1.0285829999999976,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CursorExecutor Composer thinking-field responses"],"fullName":"CursorExecutor Composer thinking-field responses does not treat thinking as visible output for non-Composer models","status":"passed","title":"does not treat thinking as visible output for non-Composer models","duration":0.46887499999999704,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801403,"endTime":1781356801417.469,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/cursor-composer-thinking.test.js"},{"assertionResults":[{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows loopback public LLM API without API key","status":"passed","title":"allows loopback public LLM API without API key","duration":18.832707999999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access rejects remote rewritten public LLM API without API key","status":"passed","title":"rejects remote rewritten public LLM API without API key","duration":0.43274999999999864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows loopback rewritten public LLM API without API key","status":"passed","title":"allows loopback rewritten public LLM API without API key","duration":0.23170899999999506,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access rejects remote beta public LLM API without API key","status":"passed","title":"rejects remote beta public LLM API without API key","duration":0.2342920000000106,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access rejects remote rewritten beta public LLM API without API key","status":"passed","title":"rejects remote rewritten beta public LLM API without API key","duration":0.30904099999997925,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows remote public LLM API with valid bearer API key","status":"passed","title":"allows remote public LLM API with valid bearer API key","duration":0.6084160000000054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows remote public LLM API with valid x-api-key","status":"passed","title":"allows remote public LLM API with valid x-api-key","duration":0.31416699999999764,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows remote rewritten beta public LLM API with valid API key","status":"passed","title":"allows remote rewritten beta public LLM API with valid API key","duration":0.14520799999999667,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route from non-loopback host without CLI token","status":"passed","title":"rejects local-only route from non-loopback host without CLI token","duration":0.504540999999989,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route on loopback when requireLogin=true and no JWT","status":"passed","title":"rejects local-only route on loopback when requireLogin=true and no JWT","duration":0.9867920000000083,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access allows local-only route on loopback when requireLogin=false","status":"passed","title":"allows local-only route on loopback when requireLogin=false","duration":1.0002079999999864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route from tunnel host even when requireLogin=false","status":"passed","title":"rejects local-only route from tunnel host even when requireLogin=false","duration":0.25162499999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route when Origin is non-loopback (CSRF block)","status":"passed","title":"rejects local-only route when Origin is non-loopback (CSRF block)","duration":0.23133300000000645,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access allows local-only route with valid CLI token","status":"passed","title":"allows local-only route with valid CLI token","duration":0.23108300000001236,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard helpers"],"fullName":"dashboard guard helpers extracts bearer API keys before x-api-key","status":"passed","title":"extracts bearer API keys before x-api-key","duration":0.2259999999999991,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800997,"endTime":1781356801022.2312,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/dashboard-guard.test.js"},{"assertionResults":[{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb INSERT 500 provider connections","status":"passed","title":"INSERT 500 provider connections","duration":1692.953625,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb READ 200 filtered queries","status":"passed","title":"READ 200 filtered queries","duration":636.36825,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb READ 200 by id (point lookup)","status":"passed","title":"READ 200 by id (point lookup)","duration":300.0022920000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb saveRequestUsage 500 entries","status":"passed","title":"saveRequestUsage 500 entries","duration":1273.6661669999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb getUsageStats(24h) repeat 50x","status":"passed","title":"getUsageStats(24h) repeat 50x","duration":565.0549579999997,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799663,"endTime":1781356804131.055,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-benchmark.test.js"},{"assertionResults":[{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety 100 parallel saveRequestUsage → no count loss","status":"passed","title":"100 parallel saveRequestUsage → no count loss","duration":34.98541700000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety 200 parallel saveRequestDetail → all flushed","status":"passed","title":"200 parallel saveRequestDetail → all flushed","duration":6005.190374999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety mixed concurrent: usage + details + connections + aliases","status":"passed","title":"mixed concurrent: usage + details + connections + aliases","duration":16.282750000000306,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety updateSettings parallel → no merge loss","status":"passed","title":"updateSettings parallel → no merge loss","duration":3.3589169999995647,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety OAuth refresh race: parallel updateProviderConnection on same id","status":"passed","title":"OAuth refresh race: parallel updateProviderConnection on same id","duration":2.6997910000000047,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety addCustomModel race: parallel duplicate adds → only 1 inserted","status":"passed","title":"addCustomModel race: parallel duplicate adds → only 1 inserted","duration":1.4490000000005239,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety updatePricing race: parallel adds different models → all merged","status":"passed","title":"updatePricing race: parallel adds different models → all merged","duration":3.7464579999996204,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety daily summary aggregates correctly under parallel writes","status":"passed","title":"daily summary aggregates correctly under parallel writes","duration":14.28662499999973,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799656,"endTime":1781356805739.2866,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-concurrent.test.js"},{"assertionResults":[{"ancestorTitles":["Driver fallback chain"],"fullName":"Driver fallback chain default → picks better-sqlite3 when available","status":"passed","title":"default → picks better-sqlite3 when available","duration":32.36254199999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Driver fallback chain"],"fullName":"Driver fallback chain falls back to node:sqlite when better-sqlite3 unavailable","status":"passed","title":"falls back to node:sqlite when better-sqlite3 unavailable","duration":24.846709000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Driver fallback chain"],"fullName":"Driver fallback chain falls back to sql.js when both native drivers unavailable","status":"passed","title":"falls back to sql.js when both native drivers unavailable","duration":88.728541,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799943,"endTime":1781356800088.7285,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-driver-chain.test.js"},{"assertionResults":[{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations fresh DB → applies migrations & stamps schemaVersion","status":"passed","title":"fresh DB → applies migrations & stamps schemaVersion","duration":44.45,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations existing DB at older schemaVersion → re-applies pending migrations on restart","status":"passed","title":"existing DB at older schemaVersion → re-applies pending migrations on restart","duration":14.366375000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations fresh DB + legacy db.json → imports data automatically","status":"passed","title":"fresh DB + legacy db.json → imports data automatically","duration":8.77154200000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations auto-sync re-creates missing index when DB lacks it","status":"passed","title":"auto-sync re-creates missing index when DB lacks it","duration":11.929000000000002,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799942,"endTime":1781356800020.929,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-migration-chain.test.js"},{"assertionResults":[{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity settings: get → defaults; update → merge","status":"passed","title":"settings: get → defaults; update → merge","duration":3.2154160000000047,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity isCloudEnabled reflects settings","status":"passed","title":"isCloudEnabled reflects settings","duration":0.7914580000000058,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity apiKeys: create/get/validate/delete","status":"passed","title":"apiKeys: create/get/validate/delete","duration":8.553291999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity providerConnections: CRUD + reorder by priority","status":"passed","title":"providerConnections: CRUD + reorder by priority","duration":3.1495000000000175,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity providerConnections: optional fields persisted via JSON column","status":"passed","title":"providerConnections: optional fields persisted via JSON column","duration":0.6158329999999808,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity providerNodes: CRUD","status":"passed","title":"providerNodes: CRUD","duration":1.8409999999999798,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity proxyPools: CRUD with sort by updatedAt desc","status":"passed","title":"proxyPools: CRUD with sort by updatedAt desc","duration":11.809249999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity combos: CRUD","status":"passed","title":"combos: CRUD","duration":1.6538340000000176,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity modelAliases: KV ops","status":"passed","title":"modelAliases: KV ops","duration":0.7480830000000083,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity customModels: add/list/delete with dedupe","status":"passed","title":"customModels: add/list/delete with dedupe","duration":0.5209169999999972,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity mitmAlias: get/set per tool","status":"passed","title":"mitmAlias: get/set per tool","duration":0.29529200000001765,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity disabledModels: add/remove per provider","status":"passed","title":"disabledModels: add/remove per provider","duration":0.5251660000000129,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity usage: saveRequestUsage + getUsageHistory + getUsageStats","status":"passed","title":"usage: saveRequestUsage + getUsageHistory + getUsageStats","duration":12.017667000000017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity usage: pending tracking in-memory","status":"passed","title":"usage: pending tracking in-memory","duration":31.916166999999973,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity requestDetails: save → query with paging","status":"passed","title":"requestDetails: save → query with paging","duration":202.18600000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity exportDb / importDb roundtrip","status":"passed","title":"exportDb / importDb roundtrip","duration":1.5339999999999918,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity pricing: user pricing merged with constants","status":"passed","title":"pricing: user pricing merged with constants","duration":0.5227910000000406,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity getChartData: 24h buckets","status":"passed","title":"getChartData: 24h buckets","duration":1.2370000000000232,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity getChartData: 7d buckets","status":"passed","title":"getChartData: 7d buckets","duration":0.7313330000000065,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799655,"endTime":1781356799939.7314,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-sqlite-vs-lowdb.test.js"},{"assertionResults":[],"startTime":1781356798831,"endTime":1781356798831,"status":"failed","message":"Cannot find module '/cloud/src/handlers/embeddings.js' imported from /Users/Working/router4/app/tests/unit/embeddings.cloud.test.js","name":"/Users/Working/router4/app/tests/unit/embeddings.cloud.test.js"},{"assertionResults":[{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody single string input — includes model and input, default encoding_format=float","status":"passed","title":"single string input — includes model and input, default encoding_format=float","duration":16.965457999999984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody array input — passes array as-is","status":"passed","title":"array input — passes array as-is","duration":1.8279159999999877,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody custom encoding_format is forwarded","status":"passed","title":"custom encoding_format is forwarded","duration":1.203249999999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody no encoding_format in body → defaults to float","status":"passed","title":"no encoding_format in body → defaults to float","duration":0.4003749999999968,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody gemini single input forwards dimensions as outputDimensionality","status":"passed","title":"gemini single input forwards dimensions as outputDimensionality","duration":0.7578750000000127,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody gemini batch input forwards dimensions on each request","status":"passed","title":"gemini batch input forwards dimensions on each request","duration":0.8050000000000068,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai → https://api.openai.com/v1/embeddings","status":"passed","title":"openai → https://api.openai.com/v1/embeddings","duration":0.4294999999999902,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openrouter → https://openrouter.ai/api/v1/embeddings","status":"passed","title":"openrouter → https://openrouter.ai/api/v1/embeddings","duration":0.22295800000000554,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl vercel-ai-gateway → https://ai-gateway.vercel.sh/v1/embeddings","status":"passed","title":"vercel-ai-gateway → https://ai-gateway.vercel.sh/v1/embeddings","duration":2.844957999999991,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai-compatible-* → uses baseUrl from providerSpecificData","status":"passed","title":"openai-compatible-* → uses baseUrl from providerSpecificData","duration":0.3750830000000178,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai-compatible-* strips trailing slash from baseUrl","status":"passed","title":"openai-compatible-* strips trailing slash from baseUrl","duration":0.2684579999999812,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai-compatible-* without baseUrl → falls back to api.openai.com","status":"passed","title":"openai-compatible-* without baseUrl → falls back to api.openai.com","duration":0.1697499999999934,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl unsupported provider (e.g. gemini-cli) → 400 error, no fetch called","status":"passed","title":"unsupported provider (e.g. gemini-cli) → 400 error, no fetch called","duration":0.3177080000000103,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl antigravity (non-openai-compatible, no URL mapping) → 400","status":"passed","title":"antigravity (non-openai-compatible, no URL mapping) → 400","duration":0.12945799999999963,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openai → Authorization: Bearer, Content-Type: application/json","status":"passed","title":"openai → Authorization: Bearer, Content-Type: application/json","duration":0.1872500000000059,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openai — uses accessToken when apiKey is absent","status":"passed","title":"openai — uses accessToken when apiKey is absent","duration":0.2195000000000107,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openrouter → adds HTTP-Referer and X-Title headers","status":"passed","title":"openrouter → adds HTTP-Referer and X-Title headers","duration":0.17025000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openai-compatible-* → Authorization: Bearer only (no extra headers)","status":"passed","title":"openai-compatible-* → Authorization: Bearer only (no extra headers)","duration":0.2337079999999787,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation missing input → 400 Bad Request","status":"passed","title":"missing input → 400 Bad Request","duration":0.18412499999999454,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation input is a number → 400 Bad Request","status":"passed","title":"input is a number → 400 Bad Request","duration":0.16087500000000432,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation input is an object → 400 Bad Request","status":"passed","title":"input is an object → 400 Bad Request","duration":0.18762499999999704,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation input is null → 400 Bad Request","status":"passed","title":"input is null → 400 Bad Request","duration":0.09108299999999758,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation empty string input passes validation","status":"passed","title":"empty string input passes validation","duration":0.11504099999999085,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation empty array input passes validation and reaches provider","status":"passed","title":"empty array input passes validation and reaches provider","duration":0.1647079999999903,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path returns success=true with Response on 200","status":"passed","title":"returns success=true with Response on 200","duration":0.2207909999999913,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path response body is valid OpenAI-format JSON","status":"passed","title":"response body is valid OpenAI-format JSON","duration":0.24104200000002152,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path response includes CORS header Access-Control-Allow-Origin: *","status":"passed","title":"response includes CORS header Access-Control-Allow-Origin: *","duration":0.1896250000000066,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path response Content-Type is application/json","status":"passed","title":"response Content-Type is application/json","duration":0.1872500000000059,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path calls onRequestSuccess callback on success","status":"passed","title":"calls onRequestSuccess callback on success","duration":0.20037500000000819,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path does not call onRequestSuccess on provider error","status":"passed","title":"does not call onRequestSuccess on provider error","duration":0.5050420000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path provider response with non-standard format is passed through as-is","status":"passed","title":"provider response with non-standard format is passed through as-is","duration":1.4942499999999939,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling provider 400 → returns success=false with status 400","status":"passed","title":"provider 400 → returns success=false with status 400","duration":5.194041999999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling provider 429 → returns success=false with status 429","status":"passed","title":"provider 429 → returns success=false with status 429","duration":2.558334000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling provider 500 → returns success=false with status 500","status":"passed","title":"provider 500 → returns success=false with status 500","duration":0.5361669999999776,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling network error (fetch throws) → returns 502 Bad Gateway","status":"passed","title":"network error (fetch throws) → returns 502 Bad Gateway","duration":0.38204099999998675,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling invalid JSON from provider → returns 502","status":"passed","title":"invalid JSON from provider → returns 502","duration":0.6597089999999923,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling error result response has OpenAI-format error body","status":"passed","title":"error result response has OpenAI-format error body","duration":0.19154100000000085,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — token refresh on 401/403"],"fullName":"handleEmbeddingsCore — token refresh on 401/403 on 401, attempts retry after refresh; succeeds if refresh gives new token","status":"passed","title":"on 401, attempts retry after refresh; succeeds if refresh gives new token","duration":0.2499170000000106,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — token refresh on 401/403"],"fullName":"handleEmbeddingsCore — token refresh on 401/403 on 401 with no refresh token, falls back gracefully (no crash)","status":"passed","title":"on 401 with no refresh token, falls back gracefully (no crash)","duration":0.15866700000000833,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800795,"endTime":1781356800838.1587,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/embeddingsCore.test.js"},{"assertionResults":[{"ancestorTitles":["Gemini CLI usage project id resolution"],"fullName":"Gemini CLI usage project id resolution uses the projectId stored on the provider connection","status":"passed","title":"uses the projectId stored on the provider connection","duration":17.006249999999994,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Gemini CLI usage project id resolution"],"fullName":"Gemini CLI usage project id resolution normalizes project objects returned by loadCodeAssist","status":"passed","title":"normalizes project objects returned by loadCodeAssist","duration":1.440084000000013,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Gemini CLI usage project id resolution"],"fullName":"Gemini CLI usage project id resolution returns actionable guidance when no project id is available","status":"passed","title":"returns actionable guidance when no project id is available","duration":0.7893329999999992,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801121,"endTime":1781356801140.7893,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/gemini-usage-projectid.test.js"},{"assertionResults":[{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint excludes Gemini models from the /responses endpoint","status":"passed","title":"excludes Gemini models from the /responses endpoint","duration":1.2137500000000045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint excludes Claude models from the /responses endpoint","status":"passed","title":"excludes Claude models from the /responses endpoint","duration":0.43291600000000585,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint allows OpenAI/codex models on the /responses endpoint","status":"passed","title":"allows OpenAI/codex models on the /responses endpoint","duration":0.2624580000000094,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint is null-safe","status":"passed","title":"is null-safe","duration":0.3533749999999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.execute cached-route guard (#1062)"],"fullName":"GithubExecutor.execute cached-route guard (#1062) does NOT use /responses for a Gemini model even if it was wrongly cached as codex","status":"passed","title":"does NOT use /responses for a Gemini model even if it was wrongly cached as codex","duration":1.5545829999999796,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801743,"endTime":1781356801747.5547,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/github-responses-routing.test.js"},{"assertionResults":[{"ancestorTitles":["HuggingFace model alias parsing"],"fullName":"HuggingFace model alias parsing resolves hf alias to huggingface provider","status":"passed","title":"resolves hf alias to huggingface provider","duration":2.070542000000003,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801882,"endTime":1781356801884.0706,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/hf-model-routing.test.js"},{"assertionResults":[{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore validates required prompt field","status":"passed","title":"validates required prompt field","duration":14.494457999999952,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore rejects unsupported provider","status":"passed","title":"rejects unsupported provider","duration":0.44854099999997743,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with OpenAI format","status":"passed","title":"generates image with OpenAI format","duration":3.412249999999972,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Gemini format","status":"passed","title":"generates image with Gemini format","duration":0.7790410000000065,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Minimax format","status":"passed","title":"generates image with Minimax format","duration":0.4410419999999817,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with NanoBanana format","status":"passed","title":"generates image with NanoBanana format","duration":7.857541000000026,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with SD WebUI format","status":"passed","title":"generates image with SD WebUI format","duration":0.8475409999999783,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles OpenRouter with HTTP-Referer header","status":"passed","title":"handles OpenRouter with HTTP-Referer header","duration":0.41699999999997317,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles Vercel AI Gateway image generation as OpenAI-compatible","status":"passed","title":"handles Vercel AI Gateway image generation as OpenAI-compatible","duration":0.7093330000000151,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles HuggingFace binary response","status":"passed","title":"handles HuggingFace binary response","duration":0.6620829999999955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Codex gpt-5.5-image using current Codex version header","status":"passed","title":"generates image with Codex gpt-5.5-image using current Codex version header","duration":0.9819170000000099,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Cloudflare Workers AI JSON response","status":"passed","title":"generates image with Cloudflare Workers AI JSON response","duration":0.5885000000000105,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore uses multipart form data for Cloudflare FLUX.2 models","status":"passed","title":"uses multipart form data for Cloudflare FLUX.2 models","duration":0.6228340000000117,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore resolves Cloudflare img2img and inpainting URL inputs before sending","status":"passed","title":"resolves Cloudflare img2img and inpainting URL inputs before sending","duration":0.46775000000002365,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles provider error responses","status":"passed","title":"handles provider error responses","duration":0.24349999999998317,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles network errors","status":"passed","title":"handles network errors","duration":0.2765829999999596,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore calls onRequestSuccess callback on success","status":"passed","title":"calls onRequestSuccess callback on success","duration":0.17500000000001137,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800819,"endTime":1781356800852.2766,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/image-generation.test.js"},{"assertionResults":[{"ancestorTitles":["Kiro MITM model slots"],"fullName":"Kiro MITM model slots exposes the kiro mitm tool","status":"passed","title":"exposes the kiro mitm tool","duration":1.9183329999999899,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro MITM model slots"],"fullName":"Kiro MITM model slots offers a mappable slot for the agent default model id 'auto'","status":"failed","title":"offers a mappable slot for the agent default model id 'auto'","duration":3.0987499999999955,"failureMessages":["AssertionError: expected undefined to be truthy\n at /Users/Working/router4/app/tests/unit/kiro-model-slots.test.js:21:18\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["Kiro MITM model slots"],"fullName":"Kiro MITM model slots offers a mappable slot for the background sub-task model id 'simple-task'","status":"passed","title":"offers a mappable slot for the background sub-task model id 'simple-task'","duration":0.13312500000000682,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799205,"endTime":1781356799210.133,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/kiro-model-slots.test.js"},{"assertionResults":[{"ancestorTitles":["generateSessionId"],"fullName":"generateSessionId uses the ses_ prefix and a 24-char random suffix","status":"passed","title":"uses the ses_ prefix and a 24-char random suffix","duration":1.7648750000000177,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateSessionId"],"fullName":"generateSessionId only emits lowercase alphanumeric characters in the suffix","status":"passed","title":"only emits lowercase alphanumeric characters in the suffix","duration":0.32991699999996627,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateSessionId"],"fullName":"generateSessionId produces a fresh id on each call","status":"passed","title":"produces a fresh id on each call","duration":0.42695900000001075,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateFingerprint"],"fullName":"generateFingerprint returns a 64-char hex sha256 digest","status":"passed","title":"returns a 64-char hex sha256 digest","duration":3.0297919999999863,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateFingerprint"],"fullName":"generateFingerprint is stable per machine (deterministic across calls)","status":"passed","title":"is stable per machine (deterministic across calls)","duration":0.8487079999999878,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseJwtExp"],"fullName":"parseJwtExp derives the expiry from the JWT exp claim (ms)","status":"passed","title":"derives the expiry from the JWT exp claim (ms)","duration":1.063916000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseJwtExp"],"fullName":"parseJwtExp falls back to a future timestamp when the JWT is unparseable","status":"passed","title":"falls back to a future timestamp when the JWT is unparseable","duration":0.5268750000000182,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker prepends a system message with the marker when none is present","status":"passed","title":"prepends a system message with the marker when none is present","duration":0.6341669999999908,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker preserves the original user message after injection","status":"passed","title":"preserves the original user message after injection","duration":0.8278329999999983,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker keeps a caller-provided system prompt alongside the marker","status":"passed","title":"keeps a caller-provided system prompt alongside the marker","duration":0.3058749999999577,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker does not duplicate the marker when already present","status":"passed","title":"does not duplicate the marker when already present","duration":0.31979100000000926,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker leaves a body without a messages array untouched","status":"passed","title":"leaves a body without a messages array untouched","duration":0.13850000000002183,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt returns the jwt from the bootstrap response","status":"passed","title":"returns the jwt from the bootstrap response","duration":0.4875830000000292,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt sends the machine fingerprint as the bootstrap client","status":"passed","title":"sends the machine fingerprint as the bootstrap client","duration":0.23399999999998045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt caches the jwt and does not re-fetch while still valid","status":"passed","title":"caches the jwt and does not re-fetch while still valid","duration":0.17925000000002456,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt re-fetches once the cached jwt is within the expiry buffer","status":"passed","title":"re-fetches once the cached jwt is within the expiry buffer","duration":0.16408400000000256,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt throws when the bootstrap response is not ok","status":"passed","title":"throws when the bootstrap response is not ok","duration":0.8416669999999726,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt throws when the bootstrap response has no jwt","status":"passed","title":"throws when the bootstrap response has no jwt","duration":0.2314169999999649,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor buildUrl returns the free-ai chat endpoint","status":"passed","title":"buildUrl returns the free-ai chat endpoint","duration":0.07712500000002365,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor buildHeaders includes the MiMo source and session affinity","status":"passed","title":"buildHeaders includes the MiMo source and session affinity","duration":0.10816599999998289,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor transformRequest injects the system marker","status":"passed","title":"transformRequest injects the system marker","duration":0.05995799999999463,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor execute injects the marker and sends a Bearer JWT to the chat endpoint","status":"passed","title":"execute injects the marker and sends a Bearer JWT to the chat endpoint","duration":0.38620800000001054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor re-bootstraps and retries once on a 403 from the chat endpoint","status":"passed","title":"re-bootstraps and retries once on a 403 from the chat endpoint","duration":0.24620800000002419,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration registers a specialized executor for mimo-free and the mmf alias","status":"passed","title":"registers a specialized executor for mimo-free and the mmf alias","duration":0.19129099999997834,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration registers mimo-free as a no-auth provider in open-sse config","status":"passed","title":"registers mimo-free as a no-auth provider in open-sse config","duration":0.05983299999996916,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration exposes only mimo-auto (the sole free-channel model)","status":"passed","title":"exposes only mimo-auto (the sole free-channel model)","duration":0.12645899999995436,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration maps the mimo-free alias to mmf","status":"passed","title":"maps the mimo-free alias to mmf","duration":0.0438750000000141,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration lists mimo-free in the dashboard FREE_PROVIDERS catalog","status":"passed","title":"lists mimo-free in the dashboard FREE_PROVIDERS catalog","duration":0.060334000000011656,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801345,"endTime":1781356801360.1914,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/mimo-free.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax TTS"],"fullName":"MiniMax TTS sends MiniMax T2A payload and converts hex audio to base64 JSON","status":"passed","title":"sends MiniMax T2A payload and converts hex audio to base64 JSON","duration":30.42512499999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax TTS"],"fullName":"MiniMax TTS uses the default MiniMax voice when no voice is provided","status":"passed","title":"uses the default MiniMax voice when no voice is provided","duration":1.4973329999999976,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax TTS"],"fullName":"MiniMax TTS surfaces MiniMax base_resp errors","status":"passed","title":"surfaces MiniMax base_resp errors","duration":1.968999999999994,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801039,"endTime":1781356801072.969,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/minimax-tts.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage parses token-plan TTS quota counts as used counts","status":"passed","title":"parses token-plan TTS quota counts as used counts","duration":16.57550000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage parses coding-plan TTS quota counts as remaining counts","status":"passed","title":"parses coding-plan TTS quota counts as remaining counts","duration":0.6620829999999955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage keeps non-TTS MiniMax quota rows instead of filtering to text only","status":"passed","title":"keeps non-TTS MiniMax quota rows instead of filtering to text only","duration":0.5277080000000183,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage includes M-series percent-only buckets that have no count totals","status":"passed","title":"includes M-series percent-only buckets that have no count totals","duration":0.9946659999999952,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage normalizes M-series percent-only buckets on the coding_plan (countMeansRemaining) endpoint too","status":"passed","title":"normalizes M-series percent-only buckets on the coding_plan (countMeansRemaining) endpoint too","duration":0.9211659999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage renders the M3-era MiniMax-M* wildcard as a friendly series label","status":"passed","title":"renders the M3-era MiniMax-M* wildcard as a friendly series label","duration":0.5519160000000056,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage prefers the upstream-provided remaining percent when counts are also present","status":"passed","title":"prefers the upstream-provided remaining percent when counts are also present","duration":0.25433299999997416,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801145,"endTime":1781356801166.2544,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/minimax-usage.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax voices API"],"fullName":"MiniMax voices API fetches global MiniMax voices with stored API key","status":"passed","title":"fetches global MiniMax voices with stored API key","duration":17.424207999999993,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax voices API"],"fullName":"MiniMax voices API fetches China MiniMax voices when provider=minimax-cn","status":"passed","title":"fetches China MiniMax voices when provider=minimax-cn","duration":1.1905000000000143,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801221,"endTime":1781356801240.1904,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/minimax-voices.test.js"},{"assertionResults":[{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing routes image model tests to /api/v1/images/generations","status":"passed","title":"routes image model tests to /api/v1/images/generations","duration":91.40625,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing routes embedding model tests to /api/v1/embeddings","status":"passed","title":"routes embedding model tests to /api/v1/embeddings","duration":4.518582999999978,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing fails embedding model tests when provider returns no embedding data","status":"passed","title":"fails embedding model tests when provider returns no embedding data","duration":3.055000000000007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing routes stt model tests to /api/v1/audio/transcriptions","status":"passed","title":"routes stt model tests to /api/v1/audio/transcriptions","duration":2.5833330000000103,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing returns formatted HTTP errors for non-2xx embedding responses","status":"passed","title":"returns formatted HTTP errors for non-2xx embedding responses","duration":0.5256250000000193,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799933,"endTime":1781356800035.5256,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/model-test-routing.test.js"},{"assertionResults":[{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import returns not-found when no macOS cursor db paths are accessible","status":"failed","title":"returns not-found when no macOS cursor db paths are accessible","duration":30.727666999999997,"failureMessages":["AssertionError: expected 'Cursor database not found. Checked lo…' to contain 'Cursor database not found in known ma…'\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:74:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import returns descriptive error if macOS db file exists but cannot be opened","status":"failed","title":"returns descriptive error if macOS db file exists but cannot be opened","duration":62.91262500000002,"failureMessages":["AssertionError: the given combination of arguments (undefined and string) is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a string\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1319:15)\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1156:15)\n at Proxy.methodWrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/chai/index.js:1700:25)\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:84:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import extracts tokens using exact keys","status":"failed","title":"extracts tokens using exact keys","duration":48.10733299999998,"failureMessages":["AssertionError: expected false to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:101:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import unwraps JSON-encoded string values","status":"failed","title":"unwraps JSON-encoded string values","duration":39.08933400000001,"failureMessages":["AssertionError: expected false to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:118:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import falls back to fuzzy key matching on macOS when exact keys are missing","status":"failed","title":"falls back to fuzzy key matching on macOS when exact keys are missing","duration":31.985833999999954,"failureMessages":["AssertionError: expected false to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:142:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import returns login-prompt error when tokens are missing even after fallback","status":"failed","title":"returns login-prompt error when tokens are missing even after fallback","duration":53.87287500000002,"failureMessages":["AssertionError: the given combination of arguments (undefined and string) is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a string\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1319:15)\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1156:15)\n at Proxy.methodWrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/chai/index.js:1700:25)\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:156:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import linux uses single hardcoded path and original error message","status":"failed","title":"linux uses single hardcoded path and original error message","duration":2.7124580000000265,"failureMessages":["AssertionError: expected 'Cursor database not found. Checked lo…' to be 'Cursor database not found. Make sure …' // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:169:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import unsupported platform returns 400","status":"failed","title":"unsupported platform returns 400","duration":0.93425000000002,"failureMessages":["AssertionError: expected 200 to be 400 // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:181:29\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]}],"startTime":1781356799202,"endTime":1781356799471.9343,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI Responses streaming termination"],"fullName":"OpenAI Responses streaming termination emits a response.failed event when a Responses stream closes before a terminal event","status":"passed","title":"emits a response.failed event when a Responses stream closes before a terminal event","duration":42.262208000000015,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI Responses streaming termination"],"fullName":"OpenAI Responses streaming termination does not add response.failed when a Responses stream already completed","status":"passed","title":"does not add response.failed when a Responses stream already completed","duration":1.0845829999999808,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI Responses streaming termination"],"fullName":"OpenAI Responses streaming termination emits response.failed before DONE when a Responses stream sends DONE without a terminal event","status":"passed","title":"emits response.failed before DONE when a Responses stream sends DONE without a terminal event","duration":1.0282499999999857,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800237,"endTime":1781356800281.0283,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-responses-terminal-event.test.js"},{"assertionResults":[{"ancestorTitles":["openaiToClaudeResponse tool argument sanitization"],"fullName":"openaiToClaudeResponse tool argument sanitization drops invalid Read pages and clamps numeric bounds","status":"passed","title":"drops invalid Read pages and clamps numeric bounds","duration":1.389792,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeResponse tool argument sanitization"],"fullName":"openaiToClaudeResponse tool argument sanitization keeps valid PDF pages","status":"passed","title":"keeps valid PDF pages","duration":0.5323329999999942,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801847,"endTime":1781356801848.5322,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-claude-response-tools.test.js"},{"assertionResults":[{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should inject JSON schema instructions for json_schema type","status":"passed","title":"should inject JSON schema instructions for json_schema type","duration":2.3603329999999687,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should inject basic JSON instructions for json_object type","status":"passed","title":"should inject basic JSON instructions for json_object type","duration":0.25950000000000273,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should not modify system prompt when response_format is missing","status":"passed","title":"should not modify system prompt when response_format is missing","duration":0.13787500000000819,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should preserve existing system messages when adding response_format","status":"passed","title":"should preserve existing system messages when adding response_format","duration":0.10741600000000062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling converts OpenAI forced tool ({type:'function'}) to Claude {type:'tool'}","status":"passed","title":"converts OpenAI forced tool ({type:'function'}) to Claude {type:'tool'}","duration":0.36487499999998363,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling maps string tool_choice values","status":"passed","title":"maps string tool_choice values","duration":0.4224169999999958,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling passes through Claude-native tool_choice objects unchanged","status":"passed","title":"passes through Claude-native tool_choice objects unchanged","duration":0.3142920000000231,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling never leaks an invalid type (falls back to auto)","status":"passed","title":"never leaks an invalid type (falls back to auto)","duration":0.15329200000002174,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling omits tool_choice entirely when the request has none","status":"passed","title":"omits tool_choice entirely when the request has none","duration":0.34583400000002484,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeResponse"],"fullName":"openaiToClaudeResponse omits empty Read pages tool argument before emitting Claude input deltas","status":"failed","title":"omits empty Read pages tool argument before emitting Claude input deltas","duration":4.197458999999981,"failureMessages":["AssertionError: expected undefined to be defined\n at /Users/Working/router4/app/tests/unit/openai-to-claude.test.js:199:24\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]}],"startTime":1781356799425,"endTime":1781356799434.1975,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-claude.test.js"},{"assertionResults":[{"ancestorTitles":["openaiToCommandCode — basic envelope"],"fullName":"openaiToCommandCode — basic envelope returns the expected top-level envelope shape","status":"passed","title":"returns the expected top-level envelope shape","duration":3.8273750000000177,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — system handling"],"fullName":"openaiToCommandCode — system handling hoists system messages to params.system (string), not messages[]","status":"passed","title":"hoists system messages to params.system (string), not messages[]","duration":1.4215420000000165,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — system handling"],"fullName":"openaiToCommandCode — system handling joins multiple system messages with blank line","status":"passed","title":"joins multiple system messages with blank line","duration":0.13991699999999696,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — system handling"],"fullName":"openaiToCommandCode — system handling omits params.system when no system messages","status":"passed","title":"omits params.system when no system messages","duration":0.3329999999999984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — content shape"],"fullName":"openaiToCommandCode — content shape MUST always emit content as Array (never string) for user","status":"passed","title":"MUST always emit content as Array (never string) for user","duration":0.42799999999999727,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — content shape"],"fullName":"openaiToCommandCode — content shape MUST always emit content as Array for assistant","status":"passed","title":"MUST always emit content as Array for assistant","duration":0.19191700000001788,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tool role / tool-result (AI SDK)"],"fullName":"openaiToCommandCode — tool role / tool-result (AI SDK) converts role:\"tool\" to role:\"tool\" with tool-result block; output is {type:\"text\",value}","status":"passed","title":"converts role:\"tool\" to role:\"tool\" with tool-result block; output is {type:\"text\",value}","duration":0.1832499999999868,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — assistant tool_calls / tool-call"],"fullName":"openaiToCommandCode — assistant tool_calls / tool-call converts assistant.tool_calls[] into content blocks of type tool-call","status":"passed","title":"converts assistant.tool_calls[] into content blocks of type tool-call","duration":0.14183299999999122,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tools schema conversion"],"fullName":"openaiToCommandCode — tools schema conversion converts OpenAI {type:\"function\", function:{...}} to Anthropic plain {name, input_schema}","status":"passed","title":"converts OpenAI {type:\"function\", function:{...}} to Anthropic plain {name, input_schema}","duration":0.4386250000000018,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tools schema conversion"],"fullName":"openaiToCommandCode — tools schema conversion preserves description on converted tool","status":"passed","title":"preserves description on converted tool","duration":0.10779199999998923,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tools schema conversion"],"fullName":"openaiToCommandCode — tools schema conversion does not include tools field when input has none","status":"passed","title":"does not include tools field when input has none","duration":0.11216699999999946,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801599,"endTime":1781356801607.4387,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-commandcode.test.js"},{"assertionResults":[{"ancestorTitles":["buildKiroPayload","basic message conversion"],"fullName":"buildKiroPayload basic message conversion should convert a simple text message","status":"passed","title":"should convert a simple text message","duration":2.4217079999999953,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","basic message conversion"],"fullName":"buildKiroPayload basic message conversion should not include images field when no images are present","status":"passed","title":"should not include images field when no images are present","duration":0.13570900000001984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should forward base64 image from image_url content part","status":"passed","title":"should forward base64 image from image_url content part","duration":0.5957499999999811,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should forward multiple base64 images","status":"passed","title":"should forward multiple base64 images","duration":0.320083000000011,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should not include images field when images array is empty","status":"passed","title":"should not include images field when images array is empty","duration":0.1703329999999994,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should include both images and text content together","status":"passed","title":"should include both images and text content together","duration":0.17883299999999736,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should treat http image URLs as text fallback (Kiro only supports base64)","status":"passed","title":"should treat http image URLs as text fallback (Kiro only supports base64)","duration":0.09454099999999244,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should flatten OpenAI tool_calls + tool result into history text with no tools array","status":"passed","title":"should flatten OpenAI tool_calls + tool result into history text with no tools array","duration":0.25004099999998175,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should flatten Claude tool_use / tool_result blocks with no tools array","status":"passed","title":"should flatten Claude tool_use / tool_result blocks with no tools array","duration":0.5637920000000065,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should keep structured tools when the client DOES provide a tools array","status":"passed","title":"should keep structured tools when the client DOES provide a tools array","duration":0.29504200000002356,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should salvage orphaned tool_result content as text instead of discarding it","status":"passed","title":"should salvage orphaned tool_result content as text instead of discarding it","duration":0.18529100000000653,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801558,"endTime":1781356801564.1853,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-kiro.test.js"},{"assertionResults":[{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages extracts system + history + current msg","status":"passed","title":"extracts system + history + current msg","duration":2.130167,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages treats developer role as system","status":"passed","title":"treats developer role as system","duration":0.21179200000000264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages handles multi-part content (array of text blocks)","status":"passed","title":"handles multi-part content (array of text blocks)","duration":0.1739170000000172,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages skips empty content messages","status":"passed","title":"skips empty content messages","duration":0.9939579999999921,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery first turn: returns JSON with instructions + query","status":"passed","title":"first turn: returns JSON with instructions + query","duration":1.3560830000000124,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery follow-up (with backendUuid): returns plain currentMsg, no JSON","status":"passed","title":"follow-up (with backendUuid): returns plain currentMsg, no JSON","duration":0.27037500000000136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery includes history when present on first turn","status":"passed","title":"includes history when present on first turn","duration":0.3538340000000062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery injects tools into instructions on first turn","status":"passed","title":"injects tools into instructions on first turn","duration":0.30266699999998536,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery ignores tools on follow-up turn (uses session)","status":"passed","title":"ignores tools on follow-up turn (uses session)","duration":0.5393329999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery truncates query if JSON exceeds 96000 chars","status":"passed","title":"truncates query if JSON exceeds 96000 chars","duration":0.41745800000001054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint returns empty string for no tools","status":"passed","title":"returns empty string for no tools","duration":0.15116599999998925,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint handles OpenAI tool schema (function wrapper)","status":"passed","title":"handles OpenAI tool schema (function wrapper)","duration":0.061082999999996446,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint handles flat tool schema","status":"passed","title":"handles flat tool schema","duration":0.04445799999999167,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint truncates long descriptions to first line, max 200 chars","status":"passed","title":"truncates long descriptions to first line, max 200 chars","duration":0.08708400000000438,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildPplxRequestBody"],"fullName":"buildPplxRequestBody sets query_str at both top-level AND params (required by upstream API)","status":"passed","title":"sets query_str at both top-level AND params (required by upstream API)","duration":15.784917000000007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildPplxRequestBody"],"fullName":"buildPplxRequestBody includes required params","status":"passed","title":"includes required params","duration":0.34045800000001236,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute maps pplx-auto → mode=concise, pref=pplx_pro","status":"passed","title":"maps pplx-auto → mode=concise, pref=pplx_pro","duration":27.52962500000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute applies THINKING_MAP when reasoning_effort is set","status":"passed","title":"applies THINKING_MAP when reasoning_effort is set","duration":1.1832499999999868,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute sends Cookie header when credentials.apiKey provided","status":"passed","title":"sends Cookie header when credentials.apiKey provided","duration":0.5586250000000064,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute sends Bearer header when credentials.accessToken provided","status":"passed","title":"sends Bearer header when credentials.accessToken provided","duration":0.43274999999999864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute injects body.tools into query_str instructions","status":"passed","title":"injects body.tools into query_str instructions","duration":0.8878749999999513,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute returns 400 on missing messages","status":"passed","title":"returns 400 on missing messages","duration":0.20045900000002348,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute surfaces upstream 401 with friendly auth message","status":"passed","title":"surfaces upstream 401 with friendly auth message","duration":0.6057910000000106,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute surfaces 429 with rate-limit message","status":"passed","title":"surfaces 429 with rate-limit message","duration":0.4333340000000021,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800178,"endTime":1781356800233.6057,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/perplexity-web.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration includes MiniMax-M3 in PROVIDER_MODELS.minimax","status":"passed","title":"includes MiniMax-M3 in PROVIDER_MODELS.minimax","duration":2.8015410000000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration includes MiniMax-M3 in PROVIDER_MODELS['minimax-cn']","status":"passed","title":"includes MiniMax-M3 in PROVIDER_MODELS['minimax-cn']","duration":0.7843749999999972,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration exposes MiniMax-M3 through getModelsByProviderId for both provider IDs","status":"passed","title":"exposes MiniMax-M3 through getModelsByProviderId for both provider IDs","duration":0.3537500000000051,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration does not regress the existing M2.7 / M2.5 / M2.1 entries","status":"passed","title":"does not regress the existing M2.7 / M2.5 / M2.1 entries","duration":1.2181250000000006,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801701,"endTime":1781356801707.218,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-models-minimax-m3.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing includes MiniMax-M3 in MODEL_PRICING","status":"passed","title":"includes MiniMax-M3 in MODEL_PRICING","duration":1.0351250000000078,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 pricing has numeric shape (input, output, cached)","status":"passed","title":"MiniMax-M3 pricing has numeric shape (input, output, cached)","duration":0.6558339999999987,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 input price matches the design spec (0.30)","status":"passed","title":"MiniMax-M3 input price matches the design spec (0.30)","duration":0.12433299999999292,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 output price matches the design spec (1.20)","status":"passed","title":"MiniMax-M3 output price matches the design spec (1.20)","duration":0.11637499999999079,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 cached price matches the design spec (0.06)","status":"passed","title":"MiniMax-M3 cached price matches the design spec (0.06)","duration":0.06550000000000011,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801771,"endTime":1781356801773.1243,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-pricing-minimax-m3.test.js"},{"assertionResults":[{"ancestorTitles":["provider test-models route kind routing"],"fullName":"provider test-models route kind routing routes huggingface image models to /api/v1/images/generations","status":"passed","title":"routes huggingface image models to /api/v1/images/generations","duration":54.167584000000005,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800211,"endTime":1781356800265.1675,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-test-models-routing.test.js"},{"assertionResults":[{"ancestorTitles":["Provider Validation API","OpenAI Compatible"],"fullName":"Provider Validation API OpenAI Compatible should return valid:true when /models succeeds","status":"passed","title":"should return valid:true when /models succeeds","duration":2.671208000000007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","OpenAI Compatible"],"fullName":"Provider Validation API OpenAI Compatible should fallback to chat/completions when /models fails and modelId provided","status":"passed","title":"should fallback to chat/completions when /models fails and modelId provided","duration":0.32895899999999756,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","OpenAI Compatible"],"fullName":"Provider Validation API OpenAI Compatible should return error when /models fails and no modelId","status":"passed","title":"should return error when /models fails and no modelId","duration":0.2908329999999921,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Anthropic Compatible"],"fullName":"Provider Validation API Anthropic Compatible should normalize URL by removing /messages suffix","status":"passed","title":"should normalize URL by removing /messages suffix","duration":0.14858299999998792,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Anthropic Compatible"],"fullName":"Provider Validation API Anthropic Compatible should send correct headers for Anthropic API","status":"passed","title":"should send correct headers for Anthropic API","duration":0.8448340000000059,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map ECONNREFUSED to user-friendly message","status":"passed","title":"should map ECONNREFUSED to user-friendly message","duration":0.2719579999999979,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map ENOTFOUND to user-friendly message","status":"passed","title":"should map ENOTFOUND to user-friendly message","duration":0.2722920000000073,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map timeout to user-friendly message","status":"passed","title":"should map timeout to user-friendly message","duration":0.1699170000000123,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map CERT_HAS_EXPIRED to user-friendly message","status":"passed","title":"should map CERT_HAS_EXPIRED to user-friendly message","duration":0.6913749999999936,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","URL Validation"],"fullName":"Provider Validation API URL Validation should validate correct URL format","status":"passed","title":"should validate correct URL format","duration":0.40066699999999855,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return auth error for 401","status":"passed","title":"should return auth error for 401","duration":0.2989169999999888,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return auth error for 403","status":"passed","title":"should return auth error for 403","duration":0.11962500000001342,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return not found for 404","status":"passed","title":"should return not found for 404","duration":0.10158300000000509,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return server error for 500","status":"passed","title":"should return server error for 500","duration":0.09475000000000477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return server error for 502","status":"passed","title":"should return server error for 502","duration":0.09183399999999153,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return unexpected for other codes","status":"passed","title":"should return unexpected for other codes","duration":0.25250000000001194,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return auth error for 401","status":"passed","title":"should return auth error for 401","duration":0.1377909999999929,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return invalid model for 400","status":"passed","title":"should return invalid model for 400","duration":0.09808300000000258,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return not found for 404","status":"passed","title":"should return not found for 404","duration":0.09133299999999167,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return server error for 503","status":"passed","title":"should return server error for 503","duration":0.11225000000000307,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return failed for other codes","status":"passed","title":"should return failed for other codes","duration":0.09579200000000299,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Response Format"],"fullName":"Provider Validation API Response Format should return correct format for success via /models","status":"passed","title":"should return correct format for success via /models","duration":0.15237500000000637,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Response Format"],"fullName":"Provider Validation API Response Format should return correct format for success via chat","status":"passed","title":"should return correct format for success via chat","duration":0.09266599999999414,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Response Format"],"fullName":"Provider Validation API Response Format should return correct format for failure with error","status":"passed","title":"should return correct format for failure with error","duration":0.06350000000000477,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801653,"endTime":1781356801662.1523,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-validation.test.js"},{"assertionResults":[{"ancestorTitles":["QODER_MODEL_MAP"],"fullName":"QODER_MODEL_MAP allows Qoder's latest model key","status":"passed","title":"allows Qoder's latest model key","duration":0.9338750000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["QODER_MODEL_MAP"],"fullName":"QODER_MODEL_MAP exposes Qoder's latest model in the static provider catalog","status":"passed","title":"exposes Qoder's latest model in the static provider catalog","duration":0.16200000000000614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody preserves base64 length (input length divisible by 3)","status":"passed","title":"preserves base64 length (input length divisible by 3)","duration":0.141666999999984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody preserves base64 length (input length not divisible by 3)","status":"passed","title":"preserves base64 length (input length not divisible by 3)","duration":0.1320829999999944,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody handles empty input without throwing","status":"passed","title":"handles empty input without throwing","duration":0.06874999999999432,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody accepts string and Buffer inputs equivalently","status":"passed","title":"accepts string and Buffer inputs equivalently","duration":0.12325000000001296,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody only emits characters from the custom alphabet","status":"passed","title":"only emits characters from the custom alphabet","duration":0.7812089999999898,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody is deterministic for identical input","status":"passed","title":"is deterministic for identical input","duration":0.1437090000000012,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody produces different output for different input","status":"passed","title":"produces different output for different input","duration":0.6603750000000161,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generatePkcePair"],"fullName":"generatePkcePair produces base64url-safe verifier and challenge of the right length","status":"passed","title":"produces base64url-safe verifier and challenge of the right length","duration":0.6782079999999837,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generatePkcePair"],"fullName":"generatePkcePair verifier and challenge are different (challenge is sha256 of verifier)","status":"passed","title":"verifier and challenge are different (challenge is sha256 of verifier)","duration":0.24912499999999227,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generatePkcePair"],"fullName":"generatePkcePair returns codeVerifier (not verifier) on the higher-level helper","status":"passed","title":"returns codeVerifier (not verifier) on the higher-level helper","duration":0.5955830000000049,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["initiateDeviceFlow"],"fullName":"initiateDeviceFlow produces a verification URL pointing at qoder.com/device/selectAccounts","status":"passed","title":"produces a verification URL pointing at qoder.com/device/selectAccounts","duration":0.4949579999999969,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["initiateDeviceFlow"],"fullName":"initiateDeviceFlow returns nonce and machineId as UUIDs","status":"passed","title":"returns nonce and machineId as UUIDs","duration":0.34858400000001666,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders produces all required Cosy-* headers","status":"passed","title":"produces all required Cosy-* headers","duration":1.9002079999999921,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Authorization is a Bearer COSY token with payload+sig","status":"passed","title":"Authorization is a Bearer COSY token with payload+sig","duration":0.30624999999997726,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Sigpath strips the leading /algo prefix","status":"passed","title":"Cosy-Sigpath strips the leading /algo prefix","duration":0.14533400000001961,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Sigpath also handles the encoded chat URL","status":"passed","title":"Cosy-Sigpath also handles the encoded chat URL","duration":0.1818749999999909,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Bodyhash is the MD5 of the request body, Cosy-Bodylength is the length","status":"passed","title":"Cosy-Bodyhash is the MD5 of the request body, Cosy-Bodylength is the length","duration":0.1377080000000035,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders empty body produces the canonical empty-MD5 hash","status":"passed","title":"empty body produces the canonical empty-MD5 hash","duration":0.14074999999999704,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Machineid + Cosy-Machinetoken match the supplied machineId","status":"passed","title":"Cosy-Machineid + Cosy-Machinetoken match the supplied machineId","duration":0.11345900000000597,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders auto-generates a machineId when none is supplied","status":"passed","title":"auto-generates a machineId when none is supplied","duration":0.11566700000000196,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders throws when userId is missing","status":"passed","title":"throws when userId is missing","duration":0.5553329999999903,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders throws when authToken is missing","status":"passed","title":"throws when authToken is missing","duration":0.13554099999998925,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-User reflects the supplied userId verbatim","status":"passed","title":"Cosy-User reflects the supplied userId verbatim","duration":0.5965000000000202,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders two calls with identical inputs differ only in fields that include fresh randomness","status":"passed","title":"two calls with identical inputs differ only in fields that include fresh randomness","duration":0.30262500000000614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry accepts ms-epoch as a JSON number","status":"passed","title":"accepts ms-epoch as a JSON number","duration":0.07733299999998167,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry accepts ms-epoch as a numeric string","status":"passed","title":"accepts ms-epoch as a numeric string","duration":0.05579099999999926,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry accepts RFC3339 strings","status":"passed","title":"accepts RFC3339 strings","duration":0.05016699999998764,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry does not interpret short numeric strings as a year","status":"passed","title":"does not interpret short numeric strings as a year","duration":0.034707999999994854,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry falls back to expiresInSeconds when expiresAt is missing","status":"passed","title":"falls back to expiresInSeconds when expiresAt is missing","duration":0.08429100000000744,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry treats expires_in: 0 as already expired (now), not 30-day fallback","status":"passed","title":"treats expires_in: 0 as already expired (now), not 30-day fallback","duration":0.04574999999999818,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry falls back to ~30 days when both inputs are missing","status":"passed","title":"falls back to ~30 days when both inputs are missing","duration":0.05750000000000455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry falls back to ~30 days when both inputs are unparseable","status":"passed","title":"falls back to ~30 days when both inputs are unparseable","duration":0.04654099999999062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages hoists role:system out of messages into systemText","status":"passed","title":"hoists role:system out of messages into systemText","duration":0.3879999999999768,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages flattens multipart text content into a string","status":"passed","title":"flattens multipart text content into a string","duration":0.04187500000000455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages joins multiple system messages with a blank line","status":"passed","title":"joins multiple system messages with a blank line","duration":0.035375000000016144,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages returns empty results for empty input","status":"passed","title":"returns empty results for empty input","duration":0.0901659999999822,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE forwards an OpenAI envelope chunk and emits [DONE] in flush","status":"passed","title":"forwards an OpenAI envelope chunk and emits [DONE] in flush","duration":16.97720799999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE drains a trailing partial line without a newline in flush()","status":"passed","title":"drains a trailing partial line without a newline in flush()","duration":0.43779200000000174,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE does not forward chunks after [DONE] has been emitted","status":"passed","title":"does not forward chunks after [DONE] has been emitted","duration":0.5033750000000055,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE strips embedded newlines from inner body before forwarding","status":"passed","title":"strips embedded newlines from inner body before forwarding","duration":0.3385419999999897,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE upstream error envelope produces an error chunk + [DONE]","status":"passed","title":"upstream error envelope produces an error chunk + [DONE]","duration":0.6441250000000025,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE non-ok responses are returned unchanged (no transform)","status":"passed","title":"non-ok responses are returned unchanged (no transform)","duration":0.23316700000000878,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800599,"endTime":1781356800630.2332,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/qoder.test.js"},{"assertionResults":[{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip injects reasoning_content on a deepseek- assistant message that lacks it","status":"passed","title":"injects reasoning_content on a deepseek- assistant message that lacks it","duration":1.0338749999999948,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip preserves an existing reasoning_content instead of overwriting it","status":"passed","title":"preserves an existing reasoning_content instead of overwriting it","duration":0.19445900000002325,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip applies provider-level rule for provider 'deepseek' (scope all)","status":"passed","title":"applies provider-level rule for provider 'deepseek' (scope all)","duration":0.09241600000001426,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip matches deepseek model id case-insensitively for custom providers (#1543)","status":"passed","title":"matches deepseek model id case-insensitively for custom providers (#1543)","duration":0.12095800000000168,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip does not touch non-deepseek providers/models","status":"passed","title":"does not touch non-deepseek providers/models","duration":0.07775000000000887,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip maps deepseek-v4-pro-none alias to disabled thinking and strips reasoning_effort","status":"passed","title":"maps deepseek-v4-pro-none alias to disabled thinking and strips reasoning_effort","duration":0.1430830000000185,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip injects reasoning_content on a minimax assistant message that lacks it","status":"passed","title":"injects reasoning_content on a minimax assistant message that lacks it","duration":0.12649999999999295,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip injects reasoning_content on minimax assistant message with tool_calls but no reasoning_content","status":"passed","title":"injects reasoning_content on minimax assistant message with tool_calls but no reasoning_content","duration":0.1392500000000041,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip applies provider-level rule for provider 'minimax-cn' (scope all)","status":"passed","title":"applies provider-level rule for provider 'minimax-cn' (scope all)","duration":0.33858399999999733,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip preserves an existing reasoning_content on minimax instead of overwriting","status":"passed","title":"preserves an existing reasoning_content on minimax instead of overwriting","duration":0.09395899999998392,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip DefaultExecutor transformRequest runs the injector for minimax","status":"passed","title":"DefaultExecutor transformRequest runs the injector for minimax","duration":10.748041999999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenCodeExecutor — issue #1543 regression"],"fullName":"OpenCodeExecutor — issue #1543 regression runs the injector so deepseek-v4-flash-free round-trips reasoning_content","status":"passed","title":"runs the injector so deepseek-v4-flash-free round-trips reasoning_content","duration":0.5094580000000235,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801444,"endTime":1781356801457.5095,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/reasoningContentInjector.test.js"},{"assertionResults":[{"ancestorTitles":["Responses abort terminal synthesis"],"fullName":"Responses abort terminal synthesis emits response.failed + [DONE] when upstream errors (abort/stall)","status":"passed","title":"emits response.failed + [DONE] when upstream errors (abort/stall)","duration":3.3995419999999967,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Responses abort terminal synthesis"],"fullName":"Responses abort terminal synthesis does not synthesize terminal for non-Responses streams (callback null)","status":"passed","title":"does not synthesize terminal for non-Responses streams (callback null)","duration":0.34045799999999815,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801834,"endTime":1781356801837.3997,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/responses-abort-terminal.test.js"},{"assertionResults":[{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end server is reachable","status":"skipped","title":"server is reachable","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end rtkEnabled flag is true (user must enable via dashboard)","status":"skipped","title":"rtkEnabled flag is true (user must enable via dashboard)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end compresses git diff tool_result and writes [RTK] savings to log","status":"skipped","title":"compresses git diff tool_result and writes [RTK] savings to log","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end compresses grep-style tool_result","status":"skipped","title":"compresses grep-style tool_result","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356798831,"endTime":1781356798831,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/rtk.e2e.test.js"},{"assertionResults":[{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E server reachable and rtkEnabled=true","status":"skipped","title":"server reachable and rtkEnabled=true","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for claude (cc/* → openai→claude)","status":"skipped","title":"compresses git diff for claude (cc/* → openai→claude)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for codex (cx/* → openai→openai-responses)","status":"skipped","title":"compresses git diff for codex (cx/* → openai→openai-responses)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for antigravity (ag/* → openai→antigravity)","status":"skipped","title":"compresses git diff for antigravity (ag/* → openai→antigravity)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for cursor (cu/* → openai→cursor)","status":"skipped","title":"compresses git diff for cursor (cu/* → openai→cursor)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for kiro (kr/* → openai→kiro)","status":"skipped","title":"compresses git diff for kiro (kr/* → openai→kiro)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for gemini (gemini/* → openai→gemini)","status":"skipped","title":"compresses git diff for gemini (gemini/* → openai→gemini)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for deepseek (deepseek/* → openai, passthrough)","status":"skipped","title":"compresses git diff for deepseek (deepseek/* → openai, passthrough)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for ollama (ollama/* → openai→ollama)","status":"skipped","title":"compresses git diff for ollama (ollama/* → openai→ollama)","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356798831,"endTime":1781356798831,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/rtk.multi-provider.e2e.test.js"},{"assertionResults":[{"ancestorTitles":["RTK flag"],"fullName":"RTK flag default off, toggle works","status":"failed","title":"default off, toggle works","duration":4.451999999999998,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:58:18\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters gitDiff truncates hunks beyond 100 lines and preserves file header","status":"passed","title":"gitDiff truncates hunks beyond 100 lines and preserves file header","duration":0.6585000000000036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters gitStatus groups by kind and produces compact output (Rust format)","status":"passed","title":"gitStatus groups by kind and produces compact output (Rust format)","duration":0.39466700000002675,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters grep groups matches by file and caps per-file lines (Rust format)","status":"passed","title":"grep groups matches by file and caps per-file lines (Rust format)","duration":0.5125409999999988,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters find groups paths by parent dir, shows basenames (Rust format)","status":"passed","title":"find groups paths by parent dir, shows basenames (Rust format)","duration":0.30054199999995035,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters dedupLog collapses consecutive duplicates","status":"passed","title":"dedupLog collapses consecutive duplicates","duration":0.21387499999997317,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects git diff","status":"passed","title":"detects git diff","duration":0.1907080000000292,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects git status","status":"passed","title":"detects git status","duration":0.1190000000000282,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects grep","status":"passed","title":"detects grep","duration":0.5750409999999988,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects find","status":"passed","title":"detects find","duration":0.2289580000000342,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter falls back to dedupLog for generic text","status":"passed","title":"falls back to dedupLog for generic text","duration":0.1825420000000122,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) ls: compact_ls strips perms/owner, keeps name + size","status":"passed","title":"ls: compact_ls strips perms/owner, keeps name + size","duration":0.7777500000000259,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) ls: filters noise dirs","status":"passed","title":"ls: filters noise dirs","duration":1.352374999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) tree: removes summary, keeps structure","status":"passed","title":"tree: removes summary, keeps structure","duration":0.3450409999999806,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) smartTruncate: keeps head+tail, drops middle","status":"passed","title":"smartTruncate: keeps head+tail, drops middle","duration":0.18549999999999045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) smartTruncate: passes through small input","status":"passed","title":"smartTruncate: passes through small input","duration":0.22433300000000145,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) readNumbered: compacts very long line-numbered dump","status":"passed","title":"readNumbered: compacts very long line-numbered dump","duration":0.5433749999999691,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) searchList: groups Cursor Glob output by parent dir","status":"passed","title":"searchList: groups Cursor Glob output by parent dir","duration":0.8502500000000168,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter (extras)"],"fullName":"autoDetectFilter (extras) detects tree via box-drawing glyphs","status":"passed","title":"detects tree via box-drawing glyphs","duration":0.8904580000000237,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter (extras)"],"fullName":"autoDetectFilter (extras) detects ls via total + perms rows","status":"passed","title":"detects ls via total + perms rows","duration":0.6634999999999991,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter (extras)"],"fullName":"autoDetectFilter (extras) detects Cursor search list","status":"passed","title":"detects Cursor search list","duration":0.1408749999999941,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["safeApply"],"fullName":"safeApply returns input if filter throws","status":"passed","title":"returns input if filter throws","duration":0.6297500000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["safeApply"],"fullName":"safeApply returns input if filter returns non-string","status":"passed","title":"returns input if filter returns non-string","duration":0.060625000000015916,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (disabled)"],"fullName":"compressMessages (disabled) returns null when disabled","status":"failed","title":"returns null when disabled","duration":0.4418749999999818,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:248:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) compresses OpenAI tool message (string content)","status":"failed","title":"compresses OpenAI tool message (string content)","duration":0.12620800000001964,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) compresses Claude string-form tool_result","status":"failed","title":"compresses Claude string-form tool_result","duration":0.1709170000000313,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) compresses Claude array-form tool_result text parts","status":"failed","title":"compresses Claude array-form tool_result text parts","duration":0.17429200000003675,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) skips is_error tool_result","status":"failed","title":"skips is_error tool_result","duration":0.09562499999998408,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) skips below MIN_COMPRESS_SIZE (<500 bytes)","status":"failed","title":"skips below MIN_COMPRESS_SIZE (<500 bytes)","duration":0.09345799999999826,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) never produces empty content (R14 guard)","status":"failed","title":"never produces empty content (R14 guard)","duration":0.264541999999949,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) skips when body has no messages","status":"failed","title":"skips when body has no messages","duration":0.19062500000001137,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) handles mix of messages without crashing","status":"failed","title":"handles mix of messages without crashing","duration":0.1623339999999871,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["formatRtkLog"],"fullName":"formatRtkLog returns null when no hits","status":"passed","title":"returns null when no hits","duration":0.09441699999996445,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatRtkLog"],"fullName":"formatRtkLog formats savings line with percentage","status":"passed","title":"formats savings line with percentage","duration":0.07287500000001046,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799344,"endTime":1781356799361.1907,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/rtk.test.js"},{"assertionResults":[{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support compresses tool results in Kiro conversationState.currentMessage","status":"passed","title":"compresses tool results in Kiro conversationState.currentMessage","duration":3.5519580000000133,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support compresses tool results in Kiro conversationState.history","status":"passed","title":"compresses tool results in Kiro conversationState.history","duration":0.8020410000000027,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support handles multiple tool results across history and currentMessage","status":"passed","title":"handles multiple tool results across history and currentMessage","duration":0.8254999999999768,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support preserves error tool results without compression","status":"passed","title":"preserves error tool results without compression","duration":0.7464159999999822,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support returns null when RTK is disabled","status":"passed","title":"returns null when RTK is disabled","duration":0.11299999999999955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support handles Kiro body with no tool results gracefully","status":"passed","title":"handles Kiro body with no tool results gracefully","duration":0.11562499999999432,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support handles malformed Kiro body without crashing","status":"passed","title":"handles malformed Kiro body without crashing","duration":0.1460830000000044,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801524,"endTime":1781356801530.146,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/rtkKiro.test.js"},{"assertionResults":[{"ancestorTitles":["request normalization"],"fullName":"request normalization claudeToOpenAIRequest flattens text-only content arrays into string","status":"failed","title":"claudeToOpenAIRequest flattens text-only content arrays into string","duration":7.344042000000002,"failureMessages":["AssertionError: expected [ { type: 'text', text: 'hi' }, …(1) ] to be 'hi\\nthere' // Object.is equality\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:24:40\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization claudeToOpenAIRequest preserves multimodal arrays","status":"passed","title":"claudeToOpenAIRequest preserves multimodal arrays","duration":0.30383399999999483,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization filterToOpenAIFormat flattens text-only arrays to string","status":"failed","title":"filterToOpenAIFormat flattens text-only arrays to string","duration":2.376082999999994,"failureMessages":["AssertionError: expected [ { type: 'text', text: 'a' }, …(1) ] to be 'a\\nb' // Object.is equality\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:65:40\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization translateRequest keeps /v1/messages Claude->OpenAI text payloads string-safe","status":"failed","title":"translateRequest keeps /v1/messages Claude->OpenAI text payloads string-safe","duration":40.260500000000036,"failureMessages":["AssertionError: expected 'object' to be 'string' // Object.is equality\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:95:40\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization translateRequest strips unsupported Anthropic output_config for MiniMax Claude-compatible endpoints","status":"passed","title":"translateRequest strips unsupported Anthropic output_config for MiniMax Claude-compatible endpoints","duration":0.4136249999999677,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization translateRequest preserves output_config for Anthropic Claude","status":"passed","title":"translateRequest preserves output_config for Anthropic Claude","duration":0.24629200000003948,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization parseSSELine supports provider raw NDJSON stream lines","status":"failed","title":"parseSSELine supports provider raw NDJSON stream lines","duration":0.4944580000000087,"failureMessages":["AssertionError: expected null to deeply equal { model: 'gpt-oss:120b', …(2) }\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:175:20\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization parseSSELine still supports SSE data lines","status":"passed","title":"parseSSELine still supports SSE data lines","duration":0.07141699999999673,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799433,"endTime":1781356799485.0715,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/translator-request-normalization.test.js"},{"assertionResults":[{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:true when response is 200","status":"passed","title":"should return valid:true when response is 200","duration":2.5124169999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:true when response is 400 (auth accepted but bad body)","status":"passed","title":"should return valid:true when response is 400 (auth accepted but bad body)","duration":0.24529200000000628,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:true when response is 429 (rate limited but auth ok)","status":"passed","title":"should return valid:true when response is 429 (rate limited but auth ok)","duration":0.3081250000000182,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:false with error when response is 401","status":"passed","title":"should return valid:false with error when response is 401","duration":0.18649999999999523,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:false with error when response is 403","status":"passed","title":"should return valid:false with error when response is 403","duration":0.18787500000001955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should strip sso= prefix from apiKey","status":"passed","title":"should strip sso= prefix from apiKey","duration":0.1552910000000054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should accept raw token without sso= prefix","status":"passed","title":"should accept raw token without sso= prefix","duration":0.145417000000009,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should POST to /rest/app-chat/conversations/new","status":"passed","title":"should POST to /rest/app-chat/conversations/new","duration":1.6416250000000048,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should send Cloudflare-bypass headers","status":"passed","title":"should send Cloudflare-bypass headers","duration":1.891791000000012,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should return valid:true when response is 200","status":"passed","title":"should return valid:true when response is 200","duration":0.5435829999999839,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should return valid:false when response is 401","status":"passed","title":"should return valid:false when response is 401","duration":0.5766660000000172,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should return valid:false when response is 403","status":"passed","title":"should return valid:false when response is 403","duration":0.20641699999998764,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should strip __Secure-next-auth.session-token= prefix","status":"passed","title":"should strip __Secure-next-auth.session-token= prefix","duration":0.16387499999999022,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should accept raw token without prefix","status":"passed","title":"should accept raw token without prefix","duration":0.22720800000001873,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should POST to /rest/sse/perplexity_ask","status":"passed","title":"should POST to /rest/sse/perplexity_ask","duration":0.5820410000000038,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356801409,"endTime":1781356801419.582,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/web-cookie-validation.test.js"},{"assertionResults":[{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service validates discovered endpoints are https x.ai URLs","status":"passed","title":"validates discovered endpoints are https x.ai URLs","duration":154.07000000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service discovers endpoints without custom user-agent headers","status":"passed","title":"discovers endpoints without custom user-agent headers","duration":6.984916999999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service builds authorize URLs with CLIProxyAPI query extras","status":"passed","title":"builds authorize URLs with CLIProxyAPI query extras","duration":1.8532500000000027,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service generates dashboard auth data with CLIProxyAPI PKCE size and discovered endpoints","status":"passed","title":"generates dashboard auth data with CLIProxyAPI PKCE size and discovered endpoints","duration":588.251959,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service exchanges dashboard codes against the discovered xAI token endpoint","status":"passed","title":"exchanges dashboard codes against the discovered xAI token endpoint","duration":32.743124999999964,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356799549,"endTime":1781356800333.7432,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/xai-oauth-service.test.js"},{"assertionResults":[{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper refreshXaiToken module loads without throwing","status":"passed","title":"refreshXaiToken module loads without throwing","duration":14.776667000000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper formatProviderCredentials returns Bearer-shape for xai","status":"passed","title":"formatProviderCredentials returns Bearer-shape for xai","duration":0.4364579999999876,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper refreshTokenByProvider returns null when refreshToken missing","status":"passed","title":"refreshTokenByProvider returns null when refreshToken missing","duration":0.13912500000000705,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper refreshTokenByProvider returns expiresIn for refreshed xai tokens","status":"passed","title":"refreshTokenByProvider returns expiresIn for refreshed xai tokens","duration":5.131249999999994,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356800984,"endTime":1781356801004.1313,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/xai-tokenRefresh.test.js"},{"assertionResults":[{"ancestorTitles":["REAL provider smoke"],"fullName":"REAL provider smoke has active providers in DB","status":"skipped","title":"has active providers in DB","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781356798831,"endTime":1781356798831,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/real/smoke-providers.real.test.js"}]} \ No newline at end of file +{"numTotalTestSuites":222,"numPassedTestSuites":205,"numFailedTestSuites":17,"numPendingTestSuites":0,"numTotalTests":827,"numPassedTests":781,"numFailedTests":26,"numPendingTests":20,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":153,"total":153,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1781357417485,"success":false,"testResults":[{"assertionResults":[{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) has at least one active AG connection with refreshToken","status":"skipped","title":"has at least one active AG connection with refreshToken","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) same sessionId → cache hit on repeated call","status":"skipped","title":"same sessionId → cache hit on repeated call","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) different sessionId (same account) → cache still hits (session-independent)","status":"skipped","title":"different sessionId (same account) → cache still hits (session-independent)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) cross-account → cache SHARED (content-based global cache)","status":"skipped","title":"cross-account → cache SHARED (content-based global cache)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) codex-style sessionId vs random sessionId on unique prompt","status":"skipped","title":"codex-style sessionId vs random sessionId on unique prompt","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity cache behavior (real API)"],"fullName":"Antigravity cache behavior (real API) unique prompt (never seen) → explore when cache starts hitting","status":"skipped","title":"unique prompt (never seen) → explore when cache starts hitting","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417485,"endTime":1781357417485,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/antigravity-cache.test.js"},{"assertionResults":[{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling flags the out-of-box agent/Default model mandatory","status":"failed","title":"flags the out-of-box agent/Default model mandatory","duration":8.089791999999989,"failureMessages":["AssertionError: expected undefined to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/antigravity-mitm.test.js:17:86\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling leaves models not proven auto-sent optional","status":"passed","title":"leaves models not proven auto-sent optional","duration":0.37358299999999645,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling excludes tab-autocomplete model 'tab_jump_flash_lite_preview' from re-routing","status":"passed","title":"excludes tab-autocomplete model 'tab_jump_flash_lite_preview' from re-routing","duration":0.12108299999999872,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling excludes tab-autocomplete model 'tab_flash_lite_preview' from re-routing","status":"passed","title":"excludes tab-autocomplete model 'tab_flash_lite_preview' from re-routing","duration":0.20266699999999105,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity MITM model handling"],"fullName":"Antigravity MITM model handling does not exclude real agent models from re-routing","status":"passed","title":"does not exclude real agent models from re-routing","duration":0.15329100000002427,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417857,"endTime":1781357417866.1533,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/antigravity-mitm.test.js"},{"assertionResults":[{"ancestorTitles":["PR #1175 - buildOutput filter detection"],"fullName":"PR #1175 - buildOutput filter detection detects npm install output","status":"passed","title":"detects npm install output","duration":2.4481250000000045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput filter detection"],"fullName":"PR #1175 - buildOutput filter detection detects cargo build output (no longer misdetected as git-status)","status":"passed","title":"detects cargo build output (no longer misdetected as git-status)","duration":0.9372499999999775,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior compresses npm install with deprecations","status":"passed","title":"compresses npm install with deprecations","duration":0.9440830000000062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior compresses cargo build output","status":"passed","title":"compresses cargo build output","duration":0.2654160000000161,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior keeps cargo errors verbatim","status":"passed","title":"keeps cargo errors verbatim","duration":0.12666600000000017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - buildOutput compression behavior"],"fullName":"PR #1175 - buildOutput compression behavior keeps maven BUILD FAILED as error","status":"passed","title":"keeps maven BUILD FAILED as error","duration":0.15366699999998445,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases git status --porcelain workdir-only (space first char) STILL detects as gitStatus (minimal fix preserved old regex)","status":"passed","title":"git status --porcelain workdir-only (space first char) STILL detects as gitStatus (minimal fix preserved old regex)","duration":0.16345799999999144,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases git status --porcelain with staged (status code first char) still detects","status":"passed","title":"git status --porcelain with staged (status code first char) still detects","duration":0.06350000000000477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases cargo Compiling lines NOT detected as git-status (porcelain false positive fix)","status":"passed","title":"cargo Compiling lines NOT detected as git-status (porcelain false positive fix)","duration":0.3637080000000026,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regex fix edge cases"],"fullName":"PR #1175 - porcelain regex fix edge cases long-form git status with 'On branch' always detects","status":"passed","title":"long-form git status with 'On branch' always detects","duration":0.08474999999998545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - false positive risks"],"fullName":"PR #1175 - false positive risks generic app log with 'ERROR:' triggers buildOutput (potential false positive)","status":"passed","title":"generic app log with 'ERROR:' triggers buildOutput (potential false positive)","duration":1.4143339999999966,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - false positive risks"],"fullName":"PR #1175 - false positive risks generic 'Compiling templates' (non-build context) triggers buildOutput","status":"passed","title":"generic 'Compiling templates' (non-build context) triggers buildOutput","duration":0.6015830000000051,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - false positive risks"],"fullName":"PR #1175 - false positive risks plain text with no patterns falls through (no false positive)","status":"passed","title":"plain text with no patterns falls through (no false positive)","duration":0.415458000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption empty input returns input","status":"passed","title":"empty input returns input","duration":0.13749999999998863,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption input with only errors preserves all errors","status":"passed","title":"input with only errors preserves all errors","duration":0.07520900000000097,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption input with no recognized patterns returns input (fallback)","status":"passed","title":"input with no recognized patterns returns input (fallback)","duration":0.05520899999999074,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - safety: no data corruption"],"fullName":"PR #1175 - safety: no data corruption limits warnings to 5 + summary line","status":"passed","title":"limits warnings to 5 + summary line","duration":0.08683400000001029,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421123,"endTime":1781357421132.087,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/buildOutputFilter.test.js"},{"assertionResults":[{"ancestorTitles":["PR #1175 - priority with overlapping patterns"],"fullName":"PR #1175 - priority with overlapping patterns git-diff wins over buildOutput when both present","status":"passed","title":"git-diff wins over buildOutput when both present","duration":0.9620000000000175,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - priority with overlapping patterns"],"fullName":"PR #1175 - priority with overlapping patterns git-status (long form) wins over buildOutput","status":"passed","title":"git-status (long form) wins over buildOutput","duration":0.2286670000000015,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - DETECT_WINDOW boundary"],"fullName":"PR #1175 - DETECT_WINDOW boundary build pattern beyond DETECT_WINDOW chars: NOT detected","status":"passed","title":"build pattern beyond DETECT_WINDOW chars: NOT detected","duration":0.8360000000000127,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - DETECT_WINDOW boundary"],"fullName":"PR #1175 - DETECT_WINDOW boundary build pattern at very start: detected","status":"passed","title":"build pattern at very start: detected","duration":0.15541600000000244,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - line endings & whitespace"],"fullName":"PR #1175 - line endings & whitespace CRLF line endings still detect","status":"passed","title":"CRLF line endings still detect","duration":0.25320800000000077,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - line endings & whitespace"],"fullName":"PR #1175 - line endings & whitespace Tab-prefixed Compiling (real cargo output uses leading spaces, not tab)","status":"passed","title":"Tab-prefixed Compiling (real cargo output uses leading spaces, not tab)","duration":0.18445800000000645,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - line endings & whitespace"],"fullName":"PR #1175 - line endings & whitespace Compiling without leading spaces","status":"passed","title":"Compiling without leading spaces","duration":0.16287499999998545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - adversarial: user code containing build strings"],"fullName":"PR #1175 - adversarial: user code containing build strings user JS code with console.log('npm warn ...') triggers buildOutput","status":"passed","title":"user JS code with console.log('npm warn ...') triggers buildOutput","duration":0.6599170000000072,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - adversarial: user code containing build strings"],"fullName":"PR #1175 - adversarial: user code containing build strings file content with 'BUILD SUCCESS' on its own line triggers buildOutput","status":"passed","title":"file content with 'BUILD SUCCESS' on its own line triggers buildOutput","duration":1.7092910000000074,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - adversarial: user code containing build strings"],"fullName":"PR #1175 - adversarial: user code containing build strings real cargo error spanning multiple lines preserves context","status":"passed","title":"real cargo error spanning multiple lines preserves context","duration":0.307042000000024,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety input with only progress lines (no errors/warnings/summary) returns input fallback","status":"passed","title":"input with only progress lines (no errors/warnings/summary) returns input fallback","duration":0.1687080000000094,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety input with only Downloading lines","status":"passed","title":"input with only Downloading lines","duration":0.053415999999998576,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety input with ONLY a single ERROR: line","status":"passed","title":"input with ONLY a single ERROR: line","duration":0.04425000000000523,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety unicode/emoji in deprecation warning preserved (minimal fix keeps first 3 verbatim)","status":"passed","title":"unicode/emoji in deprecation warning preserved (minimal fix keeps first 3 verbatim)","duration":0.44174999999998477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety more than 3 deprecations: keep first 3 verbatim + count rest","status":"passed","title":"more than 3 deprecations: keep first 3 verbatim + count rest","duration":0.10054199999999014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - corruption safety"],"fullName":"PR #1175 - corruption safety safeApply wraps buildOutput against panics","status":"passed","title":"safeApply wraps buildOutput against panics","duration":0.06183400000000461,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages npm install output above MIN_COMPRESS_SIZE → compressed","status":"passed","title":"npm install output above MIN_COMPRESS_SIZE → compressed","duration":0.2585000000000264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages input below MIN_COMPRESS_SIZE → NOT compressed","status":"passed","title":"input below MIN_COMPRESS_SIZE → NOT compressed","duration":0.06279099999997584,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages compressed output never grows input (safety guard)","status":"passed","title":"compressed output never grows input (safety guard)","duration":0.46504199999998264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - integration with compressMessages"],"fullName":"PR #1175 - integration with compressMessages tool_result with is_error:true is NOT compressed (preserve error traces)","status":"passed","title":"tool_result with is_error:true is NOT compressed (preserve error traces)","duration":0.4326250000000016,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regression deeper"],"fullName":"PR #1175 - porcelain regression deeper mixed staged + workdir + untracked porcelain → detected (has status code first char)","status":"passed","title":"mixed staged + workdir + untracked porcelain → detected (has status code first char)","duration":0.8638750000000073,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regression deeper"],"fullName":"PR #1175 - porcelain regression deeper 100% workdir-only porcelain → STILL detects gitStatus (minimal fix preserved old regex)","status":"passed","title":"100% workdir-only porcelain → STILL detects gitStatus (minimal fix preserved old regex)","duration":0.0665830000000085,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - porcelain regression deeper"],"fullName":"PR #1175 - porcelain regression deeper manual gitStatus() call on workdir-only porcelain still parses correctly","status":"passed","title":"manual gitStatus() call on workdir-only porcelain still parses correctly","duration":0.23312500000000114,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological very long single line (no newlines) with build pattern","status":"passed","title":"very long single line (no newlines) with build pattern","duration":0.07179099999999039,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological 10000 Compiling lines don't crash","status":"passed","title":"10000 Compiling lines don't crash","duration":22.953167000000008,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological input with only newlines","status":"passed","title":"input with only newlines","duration":0.2443749999999909,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PR #1175 - pathological"],"fullName":"PR #1175 - pathological null/undefined safety via safeApply","status":"passed","title":"null/undefined safety via safeApply","duration":0.6207919999999945,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420476,"endTime":1781357420509.6208,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/buildOutputFilterAdversarial.test.js"},{"assertionResults":[{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools suffixes client tool names and maps them back","status":"passed","title":"suffixes client tool names and maps them back","duration":2.867750000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools suffixes a forced tool_choice to match the renamed tool","status":"passed","title":"suffixes a forced tool_choice to match the renamed tool","duration":0.9967080000000124,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools suffixes only the chosen tool when several are present","status":"passed","title":"suffixes only the chosen tool when several are present","duration":0.4573750000000132,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools leaves non-forced tool_choice untouched","status":"passed","title":"leaves non-forced tool_choice untouched","duration":0.39554200000000606,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools does not suffix a forced choice that targets a non-client (decoy/built-in) tool","status":"passed","title":"does not suffix a forced choice that targets a non-client (decoy/built-in) tool","duration":0.3477090000000089,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools renames tool_use names in message history","status":"passed","title":"renames tool_use names in message history","duration":0.19779199999999264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["cloakClaudeTools"],"fullName":"cloakClaudeTools returns the body unchanged when there are no tools","status":"passed","title":"returns the body unchanged when there are no tools","duration":0.48579200000000355,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421417,"endTime":1781357421423.4858,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/claude-cloaking.test.js"},{"assertionResults":[{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache returns null before any headers are cached (cold start)","status":"passed","title":"returns null before any headers are cached (cold start)","duration":15.452583000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache caches headers when user-agent contains 'claude-code'","status":"passed","title":"caches headers when user-agent contains 'claude-code'","duration":2.304333000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache caches headers when user-agent contains 'claude-cli'","status":"passed","title":"caches headers when user-agent contains 'claude-cli'","duration":0.7795839999999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache caches headers when x-app is 'cli' (regardless of user-agent)","status":"passed","title":"caches headers when x-app is 'cli' (regardless of user-agent)","duration":0.4025829999999928,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache does NOT cache headers for non-Claude clients","status":"passed","title":"does NOT cache headers for non-Claude clients","duration":0.2778329999999869,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache refreshes cache on each matching request","status":"passed","title":"refreshes cache on each matching request","duration":0.9784999999999968,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache ignores calls with null or non-object headers","status":"passed","title":"ignores calls with null or non-object headers","duration":1.0442500000000052,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["claudeHeaderCache"],"fullName":"claudeHeaderCache only stores keys that are actually present in the headers object","status":"passed","title":"only stores keys that are actually present in the headers object","duration":1.75079199999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider overlays live cached headers over static provider defaults","status":"passed","title":"overlays live cached headers over static provider defaults","duration":177.91774999999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider removes conflicting Title-Case static keys when cached lowercase keys exist","status":"passed","title":"removes conflicting Title-Case static keys when cached lowercase keys exist","duration":2.987542000000019,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider sets x-api-key auth when apiKey is provided","status":"passed","title":"sets x-api-key auth when apiKey is provided","duration":6.411875000000009,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider sets Bearer Authorization when only accessToken is provided","status":"passed","title":"sets Bearer Authorization when only accessToken is provided","duration":2.7771250000000123,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider includes Accept: text/event-stream when stream=true","status":"passed","title":"includes Accept: text/event-stream when stream=true","duration":1.6304999999999836,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider"],"fullName":"DefaultExecutor.buildHeaders() — claude provider omits Accept: text/event-stream when stream=false","status":"passed","title":"omits Accept: text/event-stream when stream=false","duration":1.8604579999999942,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider cold start (no cache)"],"fullName":"DefaultExecutor.buildHeaders() — claude provider cold start (no cache) falls back to static provider headers when cache is empty","status":"passed","title":"falls back to static provider headers when cache is empty","duration":1.9919999999999618,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — claude provider cold start (no cache)"],"fullName":"DefaultExecutor.buildHeaders() — claude provider cold start (no cache) does not throw when cache returns null","status":"passed","title":"does not throw when cache returns null","duration":1.9149170000000026,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping strips x-app and anthropic-dangerous-direct-browser-access for non-Anthropic host","status":"passed","title":"strips x-app and anthropic-dangerous-direct-browser-access for non-Anthropic host","duration":6.32525000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping removes claude-code-20250219 from anthropic-beta for non-Anthropic host","status":"passed","title":"removes claude-code-20250219 from anthropic-beta for non-Anthropic host","duration":2.3522500000000264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping keeps other beta flags intact after stripping","status":"passed","title":"keeps other beta flags intact after stripping","duration":1.4284159999999702,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping does NOT strip headers when baseUrl is api.anthropic.com","status":"passed","title":"does NOT strip headers when baseUrl is api.anthropic.com","duration":0.9217499999999745,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DefaultExecutor.buildHeaders() — anthropic-compatible stripping"],"fullName":"DefaultExecutor.buildHeaders() — anthropic-compatible stripping does NOT strip headers when baseUrl is empty (defaults to Anthropic)","status":"passed","title":"does NOT strip headers when baseUrl is empty (defaults to Anthropic)","duration":1.4770409999999856,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["proxyAwareFetch — api.anthropic.com routing"],"fullName":"proxyAwareFetch — api.anthropic.com routing routes api.anthropic.com to gotScraping (non-streaming) and returns ok response","status":"failed","title":"routes api.anthropic.com to gotScraping (non-streaming) and returns ok response","duration":580.832167,"failureMessages":["AssertionError: expected \"vi.fn()\" to be called once, but got 0 times\n at /Users/Working/router4/app/tests/unit/claude-header-forwarding.test.js:354:25\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["proxyAwareFetch — api.anthropic.com routing"],"fullName":"proxyAwareFetch — api.anthropic.com routing falls back gracefully when got-scraping throws on non-streaming path","status":"passed","title":"falls back gracefully when got-scraping throws on non-streaming path","duration":6.704959000000144,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["proxyAwareFetch — api.anthropic.com routing"],"fullName":"proxyAwareFetch — api.anthropic.com routing does NOT route non-Anthropic hosts through gotScraping","status":"passed","title":"does NOT route non-Anthropic hosts through gotScraping","duration":6.22116700000015,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417845,"endTime":1781357418672.2212,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/claude-header-forwarding.test.js"},{"assertionResults":[{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling fetches 1MB remote image and inlines it as base64 data URI","status":"passed","title":"fetches 1MB remote image and inlines it as base64 data URI","duration":7.475291999999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling passes through existing data URIs without calling fetch","status":"passed","title":"passes through existing data URIs without calling fetch","duration":1.7367500000000007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling falls back to original URL when remote fetch fails","status":"passed","title":"falls back to original URL when remote fetch fails","duration":0.36025000000000773,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CodexExecutor image handling"],"fullName":"CodexExecutor image handling execute() prefetches images before sending to upstream","status":"passed","title":"execute() prefetches images before sending to upstream","duration":35.04924999999997,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420481,"endTime":1781357420526.0493,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/codex-image-fetch.test.js"},{"assertionResults":[{"ancestorTitles":["Codex Refresh Token","refreshCodexToken"],"fullName":"Codex Refresh Token refreshCodexToken should return new refresh_token when server provides one (token rotation)","status":"passed","title":"should return new refresh_token when server provides one (token rotation)","duration":18.453625000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","refreshCodexToken"],"fullName":"Codex Refresh Token refreshCodexToken should keep old refresh_token when server does not return new one","status":"passed","title":"should keep old refresh_token when server does not return new one","duration":3.417874999999981,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","CodexExecutor credential lifecycle"],"fullName":"Codex Refresh Token CodexExecutor credential lifecycle should refresh Codex credentials and preserve omitted id_token","status":"passed","title":"should refresh Codex credentials and preserve omitted id_token","duration":289.07166600000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","CodexExecutor credential lifecycle"],"fullName":"Codex Refresh Token CodexExecutor credential lifecycle should refresh Codex when lastRefreshAt is older than the upstream stale window","status":"passed","title":"should refresh Codex when lastRefreshAt is older than the upstream stale window","duration":35.112458000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","CodexExecutor credential lifecycle"],"fullName":"Codex Refresh Token CodexExecutor credential lifecycle should de-duplicate concurrent refreshes for the same Codex connection","status":"passed","title":"should de-duplicate concurrent refreshes for the same Codex connection","duration":1.4764169999999694,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","getRefreshLeadMs (early refresh config)"],"fullName":"Codex Refresh Token getRefreshLeadMs (early refresh config) should return provider-specific lead time for OAuth providers","status":"passed","title":"should return provider-specific lead time for OAuth providers","duration":2.552874999999972,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","getRefreshLeadMs (early refresh config)"],"fullName":"Codex Refresh Token getRefreshLeadMs (early refresh config) should fallback to default buffer for unknown providers","status":"passed","title":"should fallback to default buffer for unknown providers","duration":3.087249999999983,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex Refresh Token","getRefreshLeadMs (early refresh config)"],"fullName":"Codex Refresh Token getRefreshLeadMs (early refresh config) codex lead should be greater than default buffer","status":"passed","title":"codex lead should be greater than default buffer","duration":0.8295420000000036,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418400,"endTime":1781357418753.8296,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/codex-refresh-token.test.js"},{"assertionResults":[{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing keeps existing one-request round-robin behavior by default","status":"passed","title":"keeps existing one-request round-robin behavior by default","duration":1.6048749999999927,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing sticks to each combo model for the configured number of requests","status":"passed","title":"sticks to each combo model for the configured number of requests","duration":0.301415999999989,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing tracks sticky rotation independently per combo","status":"passed","title":"tracks sticky rotation independently per combo","duration":0.19779099999999517,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["combo round-robin routing"],"fullName":"combo round-robin routing does not rotate fallback combos","status":"passed","title":"does not rotate fallback combos","duration":0.25012499999999704,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421478,"endTime":1781357421480.3015,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/combo-routing.test.js"},{"assertionResults":[{"ancestorTitles":["commandcode-to-openai — text-delta"],"fullName":"commandcode-to-openai — text-delta emits assistant role on first delta then content-only","status":"passed","title":"emits assistant role on first delta then content-only","duration":1.312250000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — reasoning-delta"],"fullName":"commandcode-to-openai — reasoning-delta maps reasoning-delta to reasoning_content delta","status":"passed","title":"maps reasoning-delta to reasoning_content delta","duration":0.22383400000001075,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — tool-input-* with id field (live schema)"],"fullName":"commandcode-to-openai — tool-input-* with id field (live schema) registers tool index using event.id (NOT toolCallId)","status":"passed","title":"registers tool index using event.id (NOT toolCallId)","duration":0.209541999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — tool-input-* with id field (live schema)"],"fullName":"commandcode-to-openai — tool-input-* with id field (live schema) ignores tool-input-delta when id is unknown (no prior start)","status":"passed","title":"ignores tool-input-delta when id is unknown (no prior start)","duration":0.07158400000000142,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — final tool-call event"],"fullName":"commandcode-to-openai — final tool-call event does NOT re-emit tool_calls when tool-input-* deltas already fired","status":"passed","title":"does NOT re-emit tool_calls when tool-input-* deltas already fired","duration":0.19520800000000804,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — final tool-call event"],"fullName":"commandcode-to-openai — final tool-call event emits a consolidated tool_calls when only the final tool-call event arrives","status":"passed","title":"emits a consolidated tool_calls when only the final tool-call event arrives","duration":0.15429100000000062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — finish"],"fullName":"commandcode-to-openai — finish emits a final chunk with finish_reason=tool_calls when finishReason is tool-calls","status":"passed","title":"emits a final chunk with finish_reason=tool_calls when finishReason is tool-calls","duration":0.14404199999998468,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — finish"],"fullName":"commandcode-to-openai — finish includes usage on the final chunk when totalUsage provided","status":"passed","title":"includes usage on the final chunk when totalUsage provided","duration":0.3198329999999885,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["commandcode-to-openai — error event"],"fullName":"commandcode-to-openai — error event stringifies object errors so client sees readable message","status":"passed","title":"stringifies object errors so client sees readable message","duration":1.049999999999983,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421264,"endTime":1781357421268.05,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/commandcode-to-openai.test.js"},{"assertionResults":[{"ancestorTitles":["compatible provider connections API"],"fullName":"compatible provider connections API creates one API-key connection for an OpenAI-compatible node","status":"passed","title":"creates one API-key connection for an OpenAI-compatible node","duration":372.833709,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["compatible provider connections API"],"fullName":"compatible provider connections API creates one API-key connection for an Anthropic-compatible node","status":"passed","title":"creates one API-key connection for an Anthropic-compatible node","duration":7.636709000000053,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["compatible provider connections API"],"fullName":"compatible provider connections API returns 400 for a duplicate connection on the same compatible node","status":"passed","title":"returns 400 for a duplicate connection on the same compatible node","duration":21.679374999999993,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418343,"endTime":1781357418745.6794,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/compatible-provider-connections.test.js"},{"assertionResults":[{"ancestorTitles":["CursorExecutor Composer thinking-field responses"],"fullName":"CursorExecutor Composer thinking-field responses uses visible content after for non-streaming Composer responses","status":"passed","title":"uses visible content after for non-streaming Composer responses","duration":17.529500000000013,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CursorExecutor Composer thinking-field responses"],"fullName":"CursorExecutor Composer thinking-field responses streams only visible content after for Composer responses","status":"passed","title":"streams only visible content after for Composer responses","duration":3.177084000000008,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["CursorExecutor Composer thinking-field responses"],"fullName":"CursorExecutor Composer thinking-field responses does not treat thinking as visible output for non-Composer models","status":"passed","title":"does not treat thinking as visible output for non-Composer models","duration":1.7895840000000192,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420944,"endTime":1781357420966.7896,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/cursor-composer-thinking.test.js"},{"assertionResults":[{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows loopback public LLM API without API key","status":"passed","title":"allows loopback public LLM API without API key","duration":34.693917,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access rejects remote rewritten public LLM API without API key","status":"passed","title":"rejects remote rewritten public LLM API without API key","duration":0.4840419999999881,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows loopback rewritten public LLM API without API key","status":"passed","title":"allows loopback rewritten public LLM API without API key","duration":0.23112500000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access rejects remote beta public LLM API without API key","status":"passed","title":"rejects remote beta public LLM API without API key","duration":0.2409579999999778,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access rejects remote rewritten beta public LLM API without API key","status":"passed","title":"rejects remote rewritten beta public LLM API without API key","duration":0.2485409999999888,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows remote public LLM API with valid bearer API key","status":"passed","title":"allows remote public LLM API with valid bearer API key","duration":0.6851660000000095,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows remote public LLM API with valid x-api-key","status":"passed","title":"allows remote public LLM API with valid x-api-key","duration":0.32908299999999713,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard public LLM API access"],"fullName":"dashboard guard public LLM API access allows remote rewritten beta public LLM API with valid API key","status":"passed","title":"allows remote rewritten beta public LLM API with valid API key","duration":0.1517910000000029,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route from non-loopback host without CLI token","status":"passed","title":"rejects local-only route from non-loopback host without CLI token","duration":0.39224999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route on loopback when requireLogin=true and no JWT","status":"passed","title":"rejects local-only route on loopback when requireLogin=true and no JWT","duration":0.2400000000000091,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access allows local-only route on loopback when requireLogin=false","status":"passed","title":"allows local-only route on loopback when requireLogin=false","duration":0.21062499999999318,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route from tunnel host even when requireLogin=false","status":"passed","title":"rejects local-only route from tunnel host even when requireLogin=false","duration":0.07574999999999932,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access rejects local-only route when Origin is non-loopback (CSRF block)","status":"passed","title":"rejects local-only route when Origin is non-loopback (CSRF block)","duration":0.07816700000000765,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard local-only access"],"fullName":"dashboard guard local-only access allows local-only route with valid CLI token","status":"passed","title":"allows local-only route with valid CLI token","duration":0.08354199999999423,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["dashboard guard helpers"],"fullName":"dashboard guard helpers extracts bearer API keys before x-api-key","status":"passed","title":"extracts bearer API keys before x-api-key","duration":0.06320800000000304,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420485,"endTime":1781357420524.0632,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/dashboard-guard.test.js"},{"assertionResults":[{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb INSERT 500 provider connections","status":"passed","title":"INSERT 500 provider connections","duration":2680.5245419999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb READ 200 filtered queries","status":"passed","title":"READ 200 filtered queries","duration":643.7427079999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb READ 200 by id (point lookup)","status":"passed","title":"READ 200 by id (point lookup)","duration":338.7682080000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb saveRequestUsage 500 entries","status":"passed","title":"saveRequestUsage 500 entries","duration":1357.8541249999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Benchmark — SQLite vs Lowdb"],"fullName":"DB Benchmark — SQLite vs Lowdb getUsageStats(24h) repeat 50x","status":"passed","title":"getUsageStats(24h) repeat 50x","duration":633.1149169999999,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418445,"endTime":1781357424100.115,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-benchmark.test.js"},{"assertionResults":[{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety 100 parallel saveRequestUsage → no count loss","status":"passed","title":"100 parallel saveRequestUsage → no count loss","duration":44.05499999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety 200 parallel saveRequestDetail → all flushed","status":"passed","title":"200 parallel saveRequestDetail → all flushed","duration":6005.767292,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety mixed concurrent: usage + details + connections + aliases","status":"passed","title":"mixed concurrent: usage + details + connections + aliases","duration":22.304040999999415,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety updateSettings parallel → no merge loss","status":"passed","title":"updateSettings parallel → no merge loss","duration":2.6380840000001626,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety OAuth refresh race: parallel updateProviderConnection on same id","status":"passed","title":"OAuth refresh race: parallel updateProviderConnection on same id","duration":2.2373749999997017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety addCustomModel race: parallel duplicate adds → only 1 inserted","status":"passed","title":"addCustomModel race: parallel duplicate adds → only 1 inserted","duration":0.5585840000003373,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety updatePricing race: parallel adds different models → all merged","status":"passed","title":"updatePricing race: parallel adds different models → all merged","duration":2.5964169999997466,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB Concurrency — atomic safety"],"fullName":"DB Concurrency — atomic safety daily summary aggregates correctly under parallel writes","status":"passed","title":"daily summary aggregates correctly under parallel writes","duration":10.326249999999163,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418432,"endTime":1781357424522.3262,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-concurrent.test.js"},{"assertionResults":[{"ancestorTitles":["Driver fallback chain"],"fullName":"Driver fallback chain default → picks better-sqlite3 when available","status":"passed","title":"default → picks better-sqlite3 when available","duration":33.193292000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Driver fallback chain"],"fullName":"Driver fallback chain falls back to node:sqlite when better-sqlite3 unavailable","status":"passed","title":"falls back to node:sqlite when better-sqlite3 unavailable","duration":21.504291000000023,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Driver fallback chain"],"fullName":"Driver fallback chain falls back to sql.js when both native drivers unavailable","status":"passed","title":"falls back to sql.js when both native drivers unavailable","duration":69.319625,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418838,"endTime":1781357418962.3196,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-driver-chain.test.js"},{"assertionResults":[{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations fresh DB → applies migrations & stamps schemaVersion","status":"passed","title":"fresh DB → applies migrations & stamps schemaVersion","duration":36.79304099999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations existing DB at older schemaVersion → re-applies pending migrations on restart","status":"passed","title":"existing DB at older schemaVersion → re-applies pending migrations on restart","duration":19.420417000000015,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations fresh DB + legacy db.json → imports data automatically","status":"passed","title":"fresh DB + legacy db.json → imports data automatically","duration":12.434124999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Schema migrations"],"fullName":"Schema migrations auto-sync re-creates missing index when DB lacks it","status":"passed","title":"auto-sync re-creates missing index when DB lacks it","duration":8.052167000000026,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418873,"endTime":1781357418950.0522,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-migration-chain.test.js"},{"assertionResults":[{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity settings: get → defaults; update → merge","status":"passed","title":"settings: get → defaults; update → merge","duration":4.258250000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity isCloudEnabled reflects settings","status":"passed","title":"isCloudEnabled reflects settings","duration":0.8368750000000205,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity apiKeys: create/get/validate/delete","status":"passed","title":"apiKeys: create/get/validate/delete","duration":13.399750000000012,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity providerConnections: CRUD + reorder by priority","status":"passed","title":"providerConnections: CRUD + reorder by priority","duration":3.5686249999999973,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity providerConnections: optional fields persisted via JSON column","status":"passed","title":"providerConnections: optional fields persisted via JSON column","duration":1.3319580000000144,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity providerNodes: CRUD","status":"passed","title":"providerNodes: CRUD","duration":0.7840000000000202,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity proxyPools: CRUD with sort by updatedAt desc","status":"passed","title":"proxyPools: CRUD with sort by updatedAt desc","duration":12.256957999999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity combos: CRUD","status":"passed","title":"combos: CRUD","duration":1.8947499999999877,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity modelAliases: KV ops","status":"passed","title":"modelAliases: KV ops","duration":0.686916999999994,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity customModels: add/list/delete with dedupe","status":"passed","title":"customModels: add/list/delete with dedupe","duration":0.4842919999999822,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity mitmAlias: get/set per tool","status":"passed","title":"mitmAlias: get/set per tool","duration":0.3398339999999962,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity disabledModels: add/remove per provider","status":"passed","title":"disabledModels: add/remove per provider","duration":0.4987090000000194,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity usage: saveRequestUsage + getUsageHistory + getUsageStats","status":"passed","title":"usage: saveRequestUsage + getUsageHistory + getUsageStats","duration":4.28366699999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity usage: pending tracking in-memory","status":"passed","title":"usage: pending tracking in-memory","duration":17.337959000000012,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity requestDetails: save → query with paging","status":"passed","title":"requestDetails: save → query with paging","duration":202.350666,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity exportDb / importDb roundtrip","status":"passed","title":"exportDb / importDb roundtrip","duration":1.2697500000000446,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity pricing: user pricing merged with constants","status":"passed","title":"pricing: user pricing merged with constants","duration":0.5868749999999636,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity getChartData: 24h buckets","status":"passed","title":"getChartData: 24h buckets","duration":2.5362499999999955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["DB SQLite layer — public API parity"],"fullName":"DB SQLite layer — public API parity getChartData: 7d buckets","status":"passed","title":"getChartData: 7d buckets","duration":0.5326670000000036,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418433,"endTime":1781357418702.5327,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/db-sqlite-vs-lowdb.test.js"},{"assertionResults":[],"startTime":1781357417485,"endTime":1781357417485,"status":"failed","message":"Cannot find module '/cloud/src/handlers/embeddings.js' imported from /Users/Working/router4/app/tests/unit/embeddings.cloud.test.js","name":"/Users/Working/router4/app/tests/unit/embeddings.cloud.test.js"},{"assertionResults":[{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody single string input — includes model and input, default encoding_format=float","status":"passed","title":"single string input — includes model and input, default encoding_format=float","duration":21.304332999999986,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody array input — passes array as-is","status":"passed","title":"array input — passes array as-is","duration":2.1191670000000045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody custom encoding_format is forwarded","status":"passed","title":"custom encoding_format is forwarded","duration":1.2447090000000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody no encoding_format in body → defaults to float","status":"passed","title":"no encoding_format in body → defaults to float","duration":0.4679999999999893,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody gemini single input forwards dimensions as outputDimensionality","status":"passed","title":"gemini single input forwards dimensions as outputDimensionality","duration":0.8660000000000139,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsBody"],"fullName":"buildEmbeddingsBody gemini batch input forwards dimensions on each request","status":"passed","title":"gemini batch input forwards dimensions on each request","duration":1.8588340000000017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai → https://api.openai.com/v1/embeddings","status":"passed","title":"openai → https://api.openai.com/v1/embeddings","duration":0.478416999999979,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openrouter → https://openrouter.ai/api/v1/embeddings","status":"passed","title":"openrouter → https://openrouter.ai/api/v1/embeddings","duration":0.3029170000000079,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl vercel-ai-gateway → https://ai-gateway.vercel.sh/v1/embeddings","status":"passed","title":"vercel-ai-gateway → https://ai-gateway.vercel.sh/v1/embeddings","duration":2.0606249999999875,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai-compatible-* → uses baseUrl from providerSpecificData","status":"passed","title":"openai-compatible-* → uses baseUrl from providerSpecificData","duration":0.5601669999999785,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai-compatible-* strips trailing slash from baseUrl","status":"passed","title":"openai-compatible-* strips trailing slash from baseUrl","duration":0.49220900000000256,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl openai-compatible-* without baseUrl → falls back to api.openai.com","status":"passed","title":"openai-compatible-* without baseUrl → falls back to api.openai.com","duration":0.2525420000000054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl unsupported provider (e.g. gemini-cli) → 400 error, no fetch called","status":"passed","title":"unsupported provider (e.g. gemini-cli) → 400 error, no fetch called","duration":0.6479580000000169,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsUrl"],"fullName":"buildEmbeddingsUrl antigravity (non-openai-compatible, no URL mapping) → 400","status":"passed","title":"antigravity (non-openai-compatible, no URL mapping) → 400","duration":1.0545000000000186,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openai → Authorization: Bearer, Content-Type: application/json","status":"passed","title":"openai → Authorization: Bearer, Content-Type: application/json","duration":0.3937919999999906,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openai — uses accessToken when apiKey is absent","status":"passed","title":"openai — uses accessToken when apiKey is absent","duration":0.4096669999999847,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openrouter → adds HTTP-Referer and X-Title headers","status":"passed","title":"openrouter → adds HTTP-Referer and X-Title headers","duration":0.29154200000002106,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildEmbeddingsHeaders"],"fullName":"buildEmbeddingsHeaders openai-compatible-* → Authorization: Bearer only (no extra headers)","status":"passed","title":"openai-compatible-* → Authorization: Bearer only (no extra headers)","duration":0.2354580000000226,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation missing input → 400 Bad Request","status":"passed","title":"missing input → 400 Bad Request","duration":0.20737499999998477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation input is a number → 400 Bad Request","status":"passed","title":"input is a number → 400 Bad Request","duration":0.16766599999999698,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation input is an object → 400 Bad Request","status":"passed","title":"input is an object → 400 Bad Request","duration":0.16033299999998007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation input is null → 400 Bad Request","status":"passed","title":"input is null → 400 Bad Request","duration":0.11941600000000108,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation empty string input passes validation","status":"passed","title":"empty string input passes validation","duration":0.18091699999999378,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — input validation"],"fullName":"handleEmbeddingsCore — input validation empty array input passes validation and reaches provider","status":"passed","title":"empty array input passes validation and reaches provider","duration":0.19745900000000915,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path returns success=true with Response on 200","status":"passed","title":"returns success=true with Response on 200","duration":0.2577500000000157,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path response body is valid OpenAI-format JSON","status":"passed","title":"response body is valid OpenAI-format JSON","duration":0.5650420000000054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path response includes CORS header Access-Control-Allow-Origin: *","status":"passed","title":"response includes CORS header Access-Control-Allow-Origin: *","duration":0.9092500000000143,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path response Content-Type is application/json","status":"passed","title":"response Content-Type is application/json","duration":0.3509999999999991,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path calls onRequestSuccess callback on success","status":"passed","title":"calls onRequestSuccess callback on success","duration":0.237166000000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path does not call onRequestSuccess on provider error","status":"passed","title":"does not call onRequestSuccess on provider error","duration":0.7856669999999895,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — success path"],"fullName":"handleEmbeddingsCore — success path provider response with non-standard format is passed through as-is","status":"passed","title":"provider response with non-standard format is passed through as-is","duration":0.3237919999999974,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling provider 400 → returns success=false with status 400","status":"passed","title":"provider 400 → returns success=false with status 400","duration":2.0309589999999957,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling provider 429 → returns success=false with status 429","status":"passed","title":"provider 429 → returns success=false with status 429","duration":0.36654199999998127,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling provider 500 → returns success=false with status 500","status":"passed","title":"provider 500 → returns success=false with status 500","duration":0.24916600000000244,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling network error (fetch throws) → returns 502 Bad Gateway","status":"passed","title":"network error (fetch throws) → returns 502 Bad Gateway","duration":0.2177910000000054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling invalid JSON from provider → returns 502","status":"passed","title":"invalid JSON from provider → returns 502","duration":0.23537500000000477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — provider error handling"],"fullName":"handleEmbeddingsCore — provider error handling error result response has OpenAI-format error body","status":"passed","title":"error result response has OpenAI-format error body","duration":0.22520799999998076,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — token refresh on 401/403"],"fullName":"handleEmbeddingsCore — token refresh on 401/403 on 401, attempts retry after refresh; succeeds if refresh gives new token","status":"passed","title":"on 401, attempts retry after refresh; succeeds if refresh gives new token","duration":0.28104199999998514,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleEmbeddingsCore — token refresh on 401/403"],"fullName":"handleEmbeddingsCore — token refresh on 401/403 on 401 with no refresh token, falls back gracefully (no crash)","status":"passed","title":"on 401 with no refresh token, falls back gracefully (no crash)","duration":0.1903329999999812,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419478,"endTime":1781357419524.281,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/embeddingsCore.test.js"},{"assertionResults":[{"ancestorTitles":["Gemini CLI usage project id resolution"],"fullName":"Gemini CLI usage project id resolution uses the projectId stored on the provider connection","status":"passed","title":"uses the projectId stored on the provider connection","duration":34.287834000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Gemini CLI usage project id resolution"],"fullName":"Gemini CLI usage project id resolution normalizes project objects returned by loadCodeAssist","status":"passed","title":"normalizes project objects returned by loadCodeAssist","duration":0.8128340000000094,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Gemini CLI usage project id resolution"],"fullName":"Gemini CLI usage project id resolution returns actionable guidance when no project id is available","status":"passed","title":"returns actionable guidance when no project id is available","duration":0.34133299999999167,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420731,"endTime":1781357420766.3413,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/gemini-usage-projectid.test.js"},{"assertionResults":[{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint excludes Gemini models from the /responses endpoint","status":"passed","title":"excludes Gemini models from the /responses endpoint","duration":0.914874999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint excludes Claude models from the /responses endpoint","status":"passed","title":"excludes Claude models from the /responses endpoint","duration":0.17625000000001023,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint allows OpenAI/codex models on the /responses endpoint","status":"passed","title":"allows OpenAI/codex models on the /responses endpoint","duration":0.0992920000000197,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.supportsResponsesEndpoint"],"fullName":"GithubExecutor.supportsResponsesEndpoint is null-safe","status":"passed","title":"is null-safe","duration":0.14854099999999448,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GithubExecutor.execute cached-route guard (#1062)"],"fullName":"GithubExecutor.execute cached-route guard (#1062) does NOT use /responses for a Gemini model even if it was wrongly cached as codex","status":"passed","title":"does NOT use /responses for a Gemini model even if it was wrongly cached as codex","duration":0.711749999999995,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421342,"endTime":1781357421343.7117,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/github-responses-routing.test.js"},{"assertionResults":[{"ancestorTitles":["HuggingFace model alias parsing"],"fullName":"HuggingFace model alias parsing resolves hf alias to huggingface provider","status":"passed","title":"resolves hf alias to huggingface provider","duration":1.2177499999999952,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421406,"endTime":1781357421407.2178,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/hf-model-routing.test.js"},{"assertionResults":[{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore validates required prompt field","status":"passed","title":"validates required prompt field","duration":13.296124999999961,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore rejects unsupported provider","status":"passed","title":"rejects unsupported provider","duration":0.7383749999999054,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with OpenAI format","status":"passed","title":"generates image with OpenAI format","duration":5.879000000000019,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Gemini format","status":"passed","title":"generates image with Gemini format","duration":2.3796670000000404,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Minimax format","status":"passed","title":"generates image with Minimax format","duration":1.153791999999953,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with NanoBanana format","status":"passed","title":"generates image with NanoBanana format","duration":10.073708999999894,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with SD WebUI format","status":"passed","title":"generates image with SD WebUI format","duration":3.045749999999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles OpenRouter with HTTP-Referer header","status":"passed","title":"handles OpenRouter with HTTP-Referer header","duration":1.0019170000000486,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles Vercel AI Gateway image generation as OpenAI-compatible","status":"passed","title":"handles Vercel AI Gateway image generation as OpenAI-compatible","duration":1.4751659999999447,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles HuggingFace binary response","status":"passed","title":"handles HuggingFace binary response","duration":1.4880840000000717,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Codex gpt-5.5-image using current Codex version header","status":"passed","title":"generates image with Codex gpt-5.5-image using current Codex version header","duration":2.0773340000000644,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore generates image with Cloudflare Workers AI JSON response","status":"passed","title":"generates image with Cloudflare Workers AI JSON response","duration":0.7605829999999969,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore uses multipart form data for Cloudflare FLUX.2 models","status":"passed","title":"uses multipart form data for Cloudflare FLUX.2 models","duration":2.2607080000000224,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore resolves Cloudflare img2img and inpainting URL inputs before sending","status":"passed","title":"resolves Cloudflare img2img and inpainting URL inputs before sending","duration":0.9809589999999844,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles provider error responses","status":"passed","title":"handles provider error responses","duration":0.30491700000004585,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore handles network errors","status":"passed","title":"handles network errors","duration":0.31604200000003857,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["handleImageGenerationCore"],"fullName":"handleImageGenerationCore calls onRequestSuccess callback on success","status":"passed","title":"calls onRequestSuccess callback on success","duration":0.1955840000000535,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420198,"endTime":1781357420246.3162,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/image-generation.test.js"},{"assertionResults":[{"ancestorTitles":["Kiro MITM model slots"],"fullName":"Kiro MITM model slots exposes the kiro mitm tool","status":"passed","title":"exposes the kiro mitm tool","duration":1.1074579999999798,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro MITM model slots"],"fullName":"Kiro MITM model slots offers a mappable slot for the agent default model id 'auto'","status":"failed","title":"offers a mappable slot for the agent default model id 'auto'","duration":5.517666999999989,"failureMessages":["AssertionError: expected undefined to be truthy\n at /Users/Working/router4/app/tests/unit/kiro-model-slots.test.js:21:18\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["Kiro MITM model slots"],"fullName":"Kiro MITM model slots offers a mappable slot for the background sub-task model id 'simple-task'","status":"passed","title":"offers a mappable slot for the background sub-task model id 'simple-task'","duration":0.2138750000000016,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417857,"endTime":1781357417863.5176,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/kiro-model-slots.test.js"},{"assertionResults":[{"ancestorTitles":["generateSessionId"],"fullName":"generateSessionId uses the ses_ prefix and a 24-char random suffix","status":"passed","title":"uses the ses_ prefix and a 24-char random suffix","duration":2.7115830000000187,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateSessionId"],"fullName":"generateSessionId only emits lowercase alphanumeric characters in the suffix","status":"passed","title":"only emits lowercase alphanumeric characters in the suffix","duration":0.23991700000004812,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateSessionId"],"fullName":"generateSessionId produces a fresh id on each call","status":"passed","title":"produces a fresh id on each call","duration":0.6865000000000236,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateFingerprint"],"fullName":"generateFingerprint returns a 64-char hex sha256 digest","status":"passed","title":"returns a 64-char hex sha256 digest","duration":2.648707999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generateFingerprint"],"fullName":"generateFingerprint is stable per machine (deterministic across calls)","status":"passed","title":"is stable per machine (deterministic across calls)","duration":0.2539160000000038,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseJwtExp"],"fullName":"parseJwtExp derives the expiry from the JWT exp claim (ms)","status":"passed","title":"derives the expiry from the JWT exp claim (ms)","duration":0.24545800000004192,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseJwtExp"],"fullName":"parseJwtExp falls back to a future timestamp when the JWT is unparseable","status":"passed","title":"falls back to a future timestamp when the JWT is unparseable","duration":0.22325000000000728,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker prepends a system message with the marker when none is present","status":"passed","title":"prepends a system message with the marker when none is present","duration":0.4127500000000168,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker preserves the original user message after injection","status":"passed","title":"preserves the original user message after injection","duration":3.44241599999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker keeps a caller-provided system prompt alongside the marker","status":"passed","title":"keeps a caller-provided system prompt alongside the marker","duration":0.15274999999996908,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker does not duplicate the marker when already present","status":"passed","title":"does not duplicate the marker when already present","duration":0.15516700000000583,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectSystemMarker"],"fullName":"injectSystemMarker leaves a body without a messages array untouched","status":"passed","title":"leaves a body without a messages array untouched","duration":0.37199999999995725,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt returns the jwt from the bootstrap response","status":"passed","title":"returns the jwt from the bootstrap response","duration":0.5945839999999976,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt sends the machine fingerprint as the bootstrap client","status":"passed","title":"sends the machine fingerprint as the bootstrap client","duration":0.25058400000000347,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt caches the jwt and does not re-fetch while still valid","status":"passed","title":"caches the jwt and does not re-fetch while still valid","duration":0.18558300000000827,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt re-fetches once the cached jwt is within the expiry buffer","status":"passed","title":"re-fetches once the cached jwt is within the expiry buffer","duration":0.35533399999997073,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt throws when the bootstrap response is not ok","status":"passed","title":"throws when the bootstrap response is not ok","duration":1.5482079999999883,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bootstrapJwt"],"fullName":"bootstrapJwt throws when the bootstrap response has no jwt","status":"passed","title":"throws when the bootstrap response has no jwt","duration":0.33654099999995424,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor buildUrl returns the free-ai chat endpoint","status":"passed","title":"buildUrl returns the free-ai chat endpoint","duration":0.06499999999999773,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor buildHeaders includes the MiMo source and session affinity","status":"passed","title":"buildHeaders includes the MiMo source and session affinity","duration":0.09437500000001364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor transformRequest injects the system marker","status":"passed","title":"transformRequest injects the system marker","duration":0.054209000000014385,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor execute injects the marker and sends a Bearer JWT to the chat endpoint","status":"passed","title":"execute injects the marker and sends a Bearer JWT to the chat endpoint","duration":0.36700000000001864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MimoFreeExecutor"],"fullName":"MimoFreeExecutor re-bootstraps and retries once on a 403 from the chat endpoint","status":"passed","title":"re-bootstraps and retries once on a 403 from the chat endpoint","duration":0.9151659999999993,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration registers a specialized executor for mimo-free and the mmf alias","status":"passed","title":"registers a specialized executor for mimo-free and the mmf alias","duration":0.3262079999999514,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration registers mimo-free as a no-auth provider in open-sse config","status":"passed","title":"registers mimo-free as a no-auth provider in open-sse config","duration":0.062334000000021206,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration exposes only mimo-auto (the sole free-channel model)","status":"passed","title":"exposes only mimo-auto (the sole free-channel model)","duration":0.13291700000002038,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration maps the mimo-free alias to mmf","status":"passed","title":"maps the mimo-free alias to mmf","duration":0.042374999999992724,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiMo Free provider registration"],"fullName":"MiMo Free provider registration lists mimo-free in the dashboard FREE_PROVIDERS catalog","status":"passed","title":"lists mimo-free in the dashboard FREE_PROVIDERS catalog","duration":0.05508399999996527,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421058,"endTime":1781357421076.1328,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/mimo-free.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax TTS"],"fullName":"MiniMax TTS sends MiniMax T2A payload and converts hex audio to base64 JSON","status":"passed","title":"sends MiniMax T2A payload and converts hex audio to base64 JSON","duration":32.88412499999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax TTS"],"fullName":"MiniMax TTS uses the default MiniMax voice when no voice is provided","status":"passed","title":"uses the default MiniMax voice when no voice is provided","duration":0.7262920000000008,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax TTS"],"fullName":"MiniMax TTS surfaces MiniMax base_resp errors","status":"passed","title":"surfaces MiniMax base_resp errors","duration":0.7303339999999707,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419815,"endTime":1781357419849.7302,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/minimax-tts.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage parses token-plan TTS quota counts as used counts","status":"passed","title":"parses token-plan TTS quota counts as used counts","duration":25.868832999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage parses coding-plan TTS quota counts as remaining counts","status":"passed","title":"parses coding-plan TTS quota counts as remaining counts","duration":0.6673749999999927,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage keeps non-TTS MiniMax quota rows instead of filtering to text only","status":"passed","title":"keeps non-TTS MiniMax quota rows instead of filtering to text only","duration":0.5047090000000196,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage includes M-series percent-only buckets that have no count totals","status":"passed","title":"includes M-series percent-only buckets that have no count totals","duration":0.425707999999986,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage normalizes M-series percent-only buckets on the coding_plan (countMeansRemaining) endpoint too","status":"passed","title":"normalizes M-series percent-only buckets on the coding_plan (countMeansRemaining) endpoint too","duration":2.3685000000000116,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage renders the M3-era MiniMax-M* wildcard as a friendly series label","status":"passed","title":"renders the M3-era MiniMax-M* wildcard as a friendly series label","duration":0.6421660000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax usage"],"fullName":"MiniMax usage prefers the upstream-provided remaining percent when counts are also present","status":"passed","title":"prefers the upstream-provided remaining percent when counts are also present","duration":0.31929199999999014,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420605,"endTime":1781357420636.3193,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/minimax-usage.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax voices API"],"fullName":"MiniMax voices API fetches global MiniMax voices with stored API key","status":"passed","title":"fetches global MiniMax voices with stored API key","duration":19.643374999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax voices API"],"fullName":"MiniMax voices API fetches China MiniMax voices when provider=minimax-cn","status":"passed","title":"fetches China MiniMax voices when provider=minimax-cn","duration":1.7086249999999836,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420833,"endTime":1781357420854.7087,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/minimax-voices.test.js"},{"assertionResults":[{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing routes image model tests to /api/v1/images/generations","status":"passed","title":"routes image model tests to /api/v1/images/generations","duration":72.7635,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing routes embedding model tests to /api/v1/embeddings","status":"passed","title":"routes embedding model tests to /api/v1/embeddings","duration":1.1668750000000045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing fails embedding model tests when provider returns no embedding data","status":"passed","title":"fails embedding model tests when provider returns no embedding data","duration":3.160708999999997,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing routes stt model tests to /api/v1/audio/transcriptions","status":"passed","title":"routes stt model tests to /api/v1/audio/transcriptions","duration":3.773750000000007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["model test route kind routing"],"fullName":"model test route kind routing returns formatted HTTP errors for non-2xx embedding responses","status":"passed","title":"returns formatted HTTP errors for non-2xx embedding responses","duration":1.521708000000018,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418871,"endTime":1781357418954.5217,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/model-test-routing.test.js"},{"assertionResults":[{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import returns not-found when no macOS cursor db paths are accessible","status":"failed","title":"returns not-found when no macOS cursor db paths are accessible","duration":50.390874999999994,"failureMessages":["AssertionError: expected 'Cursor database not found. Checked lo…' to contain 'Cursor database not found in known ma…'\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:74:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import returns descriptive error if macOS db file exists but cannot be opened","status":"failed","title":"returns descriptive error if macOS db file exists but cannot be opened","duration":77.42283299999997,"failureMessages":["AssertionError: the given combination of arguments (undefined and string) is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a string\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1319:15)\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1156:15)\n at Proxy.methodWrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/chai/index.js:1700:25)\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:84:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import extracts tokens using exact keys","status":"failed","title":"extracts tokens using exact keys","duration":53.627791,"failureMessages":["AssertionError: expected false to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:101:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import unwraps JSON-encoded string values","status":"failed","title":"unwraps JSON-encoded string values","duration":46.89875000000001,"failureMessages":["AssertionError: expected false to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:118:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import falls back to fuzzy key matching on macOS when exact keys are missing","status":"failed","title":"falls back to fuzzy key matching on macOS when exact keys are missing","duration":80.67616699999996,"failureMessages":["AssertionError: expected false to be true // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:142:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import returns login-prompt error when tokens are missing even after fallback","status":"failed","title":"returns login-prompt error when tokens are missing even after fallback","duration":54.17337500000002,"failureMessages":["AssertionError: the given combination of arguments (undefined and string) is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a string\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1319:15)\n at Proxy. (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/expect/dist/index.js:1156:15)\n at Proxy.methodWrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/chai/index.js:1700:25)\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:156:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import linux uses single hardcoded path and original error message","status":"failed","title":"linux uses single hardcoded path and original error message","duration":4.376250000000027,"failureMessages":["AssertionError: expected 'Cursor database not found. Checked lo…' to be 'Cursor database not found. Make sure …' // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:169:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]},{"ancestorTitles":["GET /api/oauth/cursor/auto-import"],"fullName":"GET /api/oauth/cursor/auto-import unsupported platform returns 400","status":"failed","title":"unsupported platform returns 400","duration":0.8785000000000309,"failureMessages":["AssertionError: expected 200 to be 400 // Object.is equality\n at /Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js:181:29\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"],"meta":{},"tags":[]}],"startTime":1781357417812,"endTime":1781357418180.8784,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/oauth-cursor-auto-import.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI Responses streaming termination"],"fullName":"OpenAI Responses streaming termination emits a response.failed event when a Responses stream closes before a terminal event","status":"passed","title":"emits a response.failed event when a Responses stream closes before a terminal event","duration":58.59308300000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI Responses streaming termination"],"fullName":"OpenAI Responses streaming termination does not add response.failed when a Responses stream already completed","status":"passed","title":"does not add response.failed when a Responses stream already completed","duration":1.1179160000000365,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI Responses streaming termination"],"fullName":"OpenAI Responses streaming termination emits response.failed before DONE when a Responses stream sends DONE without a terminal event","status":"passed","title":"emits response.failed before DONE when a Responses stream sends DONE without a terminal event","duration":1.4634590000000003,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419188,"endTime":1781357419249.4634,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-responses-terminal-event.test.js"},{"assertionResults":[{"ancestorTitles":["openaiToClaudeResponse tool argument sanitization"],"fullName":"openaiToClaudeResponse tool argument sanitization drops invalid Read pages and clamps numeric bounds","status":"passed","title":"drops invalid Read pages and clamps numeric bounds","duration":3.1680000000000064,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeResponse tool argument sanitization"],"fullName":"openaiToClaudeResponse tool argument sanitization keeps valid PDF pages","status":"passed","title":"keeps valid PDF pages","duration":0.9100420000000042,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421544,"endTime":1781357421547.9102,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-claude-response-tools.test.js"},{"assertionResults":[{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should inject JSON schema instructions for json_schema type","status":"passed","title":"should inject JSON schema instructions for json_schema type","duration":2.302583000000027,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should inject basic JSON instructions for json_object type","status":"passed","title":"should inject basic JSON instructions for json_object type","duration":0.487041999999974,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should not modify system prompt when response_format is missing","status":"passed","title":"should not modify system prompt when response_format is missing","duration":0.3230829999999969,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","response_format handling"],"fullName":"openaiToClaudeRequest response_format handling should preserve existing system messages when adding response_format","status":"passed","title":"should preserve existing system messages when adding response_format","duration":0.32912500000009004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling converts OpenAI forced tool ({type:'function'}) to Claude {type:'tool'}","status":"passed","title":"converts OpenAI forced tool ({type:'function'}) to Claude {type:'tool'}","duration":0.8989170000000968,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling maps string tool_choice values","status":"passed","title":"maps string tool_choice values","duration":0.5432080000000497,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling passes through Claude-native tool_choice objects unchanged","status":"passed","title":"passes through Claude-native tool_choice objects unchanged","duration":0.31158400000003894,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling never leaks an invalid type (falls back to auto)","status":"passed","title":"never leaks an invalid type (falls back to auto)","duration":0.15708299999994324,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeRequest","tool_choice handling"],"fullName":"openaiToClaudeRequest tool_choice handling omits tool_choice entirely when the request has none","status":"passed","title":"omits tool_choice entirely when the request has none","duration":0.36524999999994634,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToClaudeResponse"],"fullName":"openaiToClaudeResponse omits empty Read pages tool argument before emitting Claude input deltas","status":"failed","title":"omits empty Read pages tool argument before emitting Claude input deltas","duration":4.936833999999976,"failureMessages":["AssertionError: expected undefined to be defined\n at /Users/Working/router4/app/tests/unit/openai-to-claude.test.js:199:24\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]}],"startTime":1781357418188,"endTime":1781357418199.9368,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-claude.test.js"},{"assertionResults":[{"ancestorTitles":["openaiToCommandCode — basic envelope"],"fullName":"openaiToCommandCode — basic envelope returns the expected top-level envelope shape","status":"passed","title":"returns the expected top-level envelope shape","duration":3.559750000000008,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — system handling"],"fullName":"openaiToCommandCode — system handling hoists system messages to params.system (string), not messages[]","status":"passed","title":"hoists system messages to params.system (string), not messages[]","duration":0.7528749999999889,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — system handling"],"fullName":"openaiToCommandCode — system handling joins multiple system messages with blank line","status":"passed","title":"joins multiple system messages with blank line","duration":0.10412500000001046,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — system handling"],"fullName":"openaiToCommandCode — system handling omits params.system when no system messages","status":"passed","title":"omits params.system when no system messages","duration":0.1564999999999941,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — content shape"],"fullName":"openaiToCommandCode — content shape MUST always emit content as Array (never string) for user","status":"passed","title":"MUST always emit content as Array (never string) for user","duration":0.33220899999997755,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — content shape"],"fullName":"openaiToCommandCode — content shape MUST always emit content as Array for assistant","status":"passed","title":"MUST always emit content as Array for assistant","duration":0.155208000000016,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tool role / tool-result (AI SDK)"],"fullName":"openaiToCommandCode — tool role / tool-result (AI SDK) converts role:\"tool\" to role:\"tool\" with tool-result block; output is {type:\"text\",value}","status":"passed","title":"converts role:\"tool\" to role:\"tool\" with tool-result block; output is {type:\"text\",value}","duration":0.16516600000002768,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — assistant tool_calls / tool-call"],"fullName":"openaiToCommandCode — assistant tool_calls / tool-call converts assistant.tool_calls[] into content blocks of type tool-call","status":"passed","title":"converts assistant.tool_calls[] into content blocks of type tool-call","duration":0.13016600000000267,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tools schema conversion"],"fullName":"openaiToCommandCode — tools schema conversion converts OpenAI {type:\"function\", function:{...}} to Anthropic plain {name, input_schema}","status":"passed","title":"converts OpenAI {type:\"function\", function:{...}} to Anthropic plain {name, input_schema}","duration":0.4272499999999866,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tools schema conversion"],"fullName":"openaiToCommandCode — tools schema conversion preserves description on converted tool","status":"passed","title":"preserves description on converted tool","duration":0.10395900000000324,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["openaiToCommandCode — tools schema conversion"],"fullName":"openaiToCommandCode — tools schema conversion does not include tools field when input has none","status":"passed","title":"does not include tools field when input has none","duration":0.11383299999999963,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421149,"endTime":1781357421155.1138,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-commandcode.test.js"},{"assertionResults":[{"ancestorTitles":["buildKiroPayload","basic message conversion"],"fullName":"buildKiroPayload basic message conversion should convert a simple text message","status":"passed","title":"should convert a simple text message","duration":3.1436669999999935,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","basic message conversion"],"fullName":"buildKiroPayload basic message conversion should not include images field when no images are present","status":"passed","title":"should not include images field when no images are present","duration":0.1431660000000079,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should forward base64 image from image_url content part","status":"passed","title":"should forward base64 image from image_url content part","duration":0.5795420000000036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should forward multiple base64 images","status":"passed","title":"should forward multiple base64 images","duration":0.33670900000001325,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should not include images field when images array is empty","status":"passed","title":"should not include images field when images array is empty","duration":0.178875000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should include both images and text content together","status":"passed","title":"should include both images and text content together","duration":0.18924999999998704,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","image forwarding"],"fullName":"buildKiroPayload image forwarding should treat http image URLs as text fallback (Kiro only supports base64)","status":"passed","title":"should treat http image URLs as text fallback (Kiro only supports base64)","duration":0.09783399999997755,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should flatten OpenAI tool_calls + tool result into history text with no tools array","status":"passed","title":"should flatten OpenAI tool_calls + tool result into history text with no tools array","duration":0.24895899999998505,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should flatten Claude tool_use / tool_result blocks with no tools array","status":"passed","title":"should flatten Claude tool_use / tool_result blocks with no tools array","duration":0.5827919999999835,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should keep structured tools when the client DOES provide a tools array","status":"passed","title":"should keep structured tools when the client DOES provide a tools array","duration":0.2857500000000073,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildKiroPayload","tool interaction without client-provided tools"],"fullName":"buildKiroPayload tool interaction without client-provided tools should salvage orphaned tool_result content as text instead of discarding it","status":"passed","title":"should salvage orphaned tool_result content as text instead of discarding it","duration":0.18199999999998795,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421202,"endTime":1781357421208.2856,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/openai-to-kiro.test.js"},{"assertionResults":[{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages extracts system + history + current msg","status":"passed","title":"extracts system + history + current msg","duration":2.6446249999999907,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages treats developer role as system","status":"passed","title":"treats developer role as system","duration":0.5209169999999972,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages handles multi-part content (array of text blocks)","status":"passed","title":"handles multi-part content (array of text blocks)","duration":0.4175830000000076,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseOpenAIMessages"],"fullName":"parseOpenAIMessages skips empty content messages","status":"passed","title":"skips empty content messages","duration":0.317292000000009,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery first turn: returns JSON with instructions + query","status":"passed","title":"first turn: returns JSON with instructions + query","duration":1.42108300000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery follow-up (with backendUuid): returns plain currentMsg, no JSON","status":"passed","title":"follow-up (with backendUuid): returns plain currentMsg, no JSON","duration":0.13416599999999335,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery includes history when present on first turn","status":"passed","title":"includes history when present on first turn","duration":0.1683749999999975,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery injects tools into instructions on first turn","status":"passed","title":"injects tools into instructions on first turn","duration":0.1408749999999941,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery ignores tools on follow-up turn (uses session)","status":"passed","title":"ignores tools on follow-up turn (uses session)","duration":0.359375,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildQuery"],"fullName":"buildQuery truncates query if JSON exceeds 96000 chars","status":"passed","title":"truncates query if JSON exceeds 96000 chars","duration":0.3580829999999935,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint returns empty string for no tools","status":"passed","title":"returns empty string for no tools","duration":0.11812500000002046,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint handles OpenAI tool schema (function wrapper)","status":"passed","title":"handles OpenAI tool schema (function wrapper)","duration":0.04862499999998704,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint handles flat tool schema","status":"passed","title":"handles flat tool schema","duration":0.03925000000000978,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatToolsHint"],"fullName":"formatToolsHint truncates long descriptions to first line, max 200 chars","status":"passed","title":"truncates long descriptions to first line, max 200 chars","duration":0.08033299999999599,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildPplxRequestBody"],"fullName":"buildPplxRequestBody sets query_str at both top-level AND params (required by upstream API)","status":"passed","title":"sets query_str at both top-level AND params (required by upstream API)","duration":18.692791,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildPplxRequestBody"],"fullName":"buildPplxRequestBody includes required params","status":"passed","title":"includes required params","duration":0.3545830000000194,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute maps pplx-auto → mode=concise, pref=pplx_pro","status":"passed","title":"maps pplx-auto → mode=concise, pref=pplx_pro","duration":33.49604199999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute applies THINKING_MAP when reasoning_effort is set","status":"passed","title":"applies THINKING_MAP when reasoning_effort is set","duration":0.7520000000000095,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute sends Cookie header when credentials.apiKey provided","status":"passed","title":"sends Cookie header when credentials.apiKey provided","duration":0.36666600000000926,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute sends Bearer header when credentials.accessToken provided","status":"passed","title":"sends Bearer header when credentials.accessToken provided","duration":0.3388750000000016,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute injects body.tools into query_str instructions","status":"passed","title":"injects body.tools into query_str instructions","duration":1.7242499999999836,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute returns 400 on missing messages","status":"passed","title":"returns 400 on missing messages","duration":0.9418749999999818,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute surfaces upstream 401 with friendly auth message","status":"passed","title":"surfaces upstream 401 with friendly auth message","duration":1.796750000000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["PerplexityWebExecutor.execute"],"fullName":"PerplexityWebExecutor.execute surfaces 429 with rate-limit message","status":"passed","title":"surfaces 429 with rate-limit message","duration":2.0695840000000203,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418915,"endTime":1781357418983.0696,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/perplexity-web.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration includes MiniMax-M3 in PROVIDER_MODELS.minimax","status":"passed","title":"includes MiniMax-M3 in PROVIDER_MODELS.minimax","duration":1.2350840000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration includes MiniMax-M3 in PROVIDER_MODELS['minimax-cn']","status":"passed","title":"includes MiniMax-M3 in PROVIDER_MODELS['minimax-cn']","duration":0.2505419999999958,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration exposes MiniMax-M3 through getModelsByProviderId for both provider IDs","status":"passed","title":"exposes MiniMax-M3 through getModelsByProviderId for both provider IDs","duration":0.14870799999999917,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 model registration"],"fullName":"MiniMax-M3 model registration does not regress the existing M2.7 / M2.5 / M2.1 entries","status":"passed","title":"does not regress the existing M2.7 / M2.5 / M2.1 entries","duration":0.721082999999993,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421270,"endTime":1781357421271.7212,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-models-minimax-m3.test.js"},{"assertionResults":[{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing includes MiniMax-M3 in MODEL_PRICING","status":"passed","title":"includes MiniMax-M3 in MODEL_PRICING","duration":0.850750000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 pricing has numeric shape (input, output, cached)","status":"passed","title":"MiniMax-M3 pricing has numeric shape (input, output, cached)","duration":0.6175420000000145,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 input price matches the design spec (0.30)","status":"passed","title":"MiniMax-M3 input price matches the design spec (0.30)","duration":0.17745899999999892,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 output price matches the design spec (1.20)","status":"passed","title":"MiniMax-M3 output price matches the design spec (1.20)","duration":0.14279200000001424,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["MiniMax-M3 pricing"],"fullName":"MiniMax-M3 pricing MiniMax-M3 cached price matches the design spec (0.06)","status":"passed","title":"MiniMax-M3 cached price matches the design spec (0.06)","duration":0.0726669999999956,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421560,"endTime":1781357421562.1775,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-pricing-minimax-m3.test.js"},{"assertionResults":[{"ancestorTitles":["provider test-models route kind routing"],"fullName":"provider test-models route kind routing routes huggingface image models to /api/v1/images/generations","status":"passed","title":"routes huggingface image models to /api/v1/images/generations","duration":58.30220800000001,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419113,"endTime":1781357419171.3022,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-test-models-routing.test.js"},{"assertionResults":[{"ancestorTitles":["Provider Validation API","OpenAI Compatible"],"fullName":"Provider Validation API OpenAI Compatible should return valid:true when /models succeeds","status":"passed","title":"should return valid:true when /models succeeds","duration":2.4042910000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","OpenAI Compatible"],"fullName":"Provider Validation API OpenAI Compatible should fallback to chat/completions when /models fails and modelId provided","status":"passed","title":"should fallback to chat/completions when /models fails and modelId provided","duration":0.2398329999999902,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","OpenAI Compatible"],"fullName":"Provider Validation API OpenAI Compatible should return error when /models fails and no modelId","status":"passed","title":"should return error when /models fails and no modelId","duration":0.6879169999999988,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Anthropic Compatible"],"fullName":"Provider Validation API Anthropic Compatible should normalize URL by removing /messages suffix","status":"passed","title":"should normalize URL by removing /messages suffix","duration":0.2971249999999941,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Anthropic Compatible"],"fullName":"Provider Validation API Anthropic Compatible should send correct headers for Anthropic API","status":"passed","title":"should send correct headers for Anthropic API","duration":0.8692080000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map ECONNREFUSED to user-friendly message","status":"passed","title":"should map ECONNREFUSED to user-friendly message","duration":0.11941699999999855,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map ENOTFOUND to user-friendly message","status":"passed","title":"should map ENOTFOUND to user-friendly message","duration":0.12033300000000224,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map timeout to user-friendly message","status":"passed","title":"should map timeout to user-friendly message","duration":0.07174999999999443,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - Network"],"fullName":"Provider Validation API Error Messages - Network should map CERT_HAS_EXPIRED to user-friendly message","status":"passed","title":"should map CERT_HAS_EXPIRED to user-friendly message","duration":0.37000000000000455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","URL Validation"],"fullName":"Provider Validation API URL Validation should validate correct URL format","status":"passed","title":"should validate correct URL format","duration":0.17329199999998934,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return auth error for 401","status":"passed","title":"should return auth error for 401","duration":0.12862499999999955,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return auth error for 403","status":"passed","title":"should return auth error for 403","duration":0.047416999999995824,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return not found for 404","status":"passed","title":"should return not found for 404","duration":0.04200000000000159,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return server error for 500","status":"passed","title":"should return server error for 500","duration":0.0362920000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return server error for 502","status":"passed","title":"should return server error for 502","duration":0.034834000000003584,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /models Status Codes"],"fullName":"Provider Validation API Error Messages - /models Status Codes should return unexpected for other codes","status":"passed","title":"should return unexpected for other codes","duration":0.11491600000000801,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return auth error for 401","status":"passed","title":"should return auth error for 401","duration":0.30450000000000443,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return invalid model for 400","status":"passed","title":"should return invalid model for 400","duration":0.14133300000000304,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return not found for 404","status":"passed","title":"should return not found for 404","duration":0.18258400000000563,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return server error for 503","status":"passed","title":"should return server error for 503","duration":0.39158299999999713,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Error Messages - /chat/completions Status Codes"],"fullName":"Provider Validation API Error Messages - /chat/completions Status Codes should return failed for other codes","status":"passed","title":"should return failed for other codes","duration":0.5248339999999985,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Response Format"],"fullName":"Provider Validation API Response Format should return correct format for success via /models","status":"passed","title":"should return correct format for success via /models","duration":0.3342920000000049,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Response Format"],"fullName":"Provider Validation API Response Format should return correct format for success via chat","status":"passed","title":"should return correct format for success via chat","duration":0.24245800000001339,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Provider Validation API","Response Format"],"fullName":"Provider Validation API Response Format should return correct format for failure with error","status":"passed","title":"should return correct format for failure with error","duration":0.17145800000000122,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420994,"endTime":1781357421003.1714,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/provider-validation.test.js"},{"assertionResults":[{"ancestorTitles":["QODER_MODEL_MAP"],"fullName":"QODER_MODEL_MAP allows Qoder's latest model key","status":"passed","title":"allows Qoder's latest model key","duration":2.810791999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["QODER_MODEL_MAP"],"fullName":"QODER_MODEL_MAP exposes Qoder's latest model in the static provider catalog","status":"passed","title":"exposes Qoder's latest model in the static provider catalog","duration":0.39937499999999204,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody preserves base64 length (input length divisible by 3)","status":"passed","title":"preserves base64 length (input length divisible by 3)","duration":0.22262499999999363,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody preserves base64 length (input length not divisible by 3)","status":"passed","title":"preserves base64 length (input length not divisible by 3)","duration":0.3365000000000009,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody handles empty input without throwing","status":"passed","title":"handles empty input without throwing","duration":0.2150000000000034,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody accepts string and Buffer inputs equivalently","status":"passed","title":"accepts string and Buffer inputs equivalently","duration":0.3170829999999967,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody only emits characters from the custom alphabet","status":"passed","title":"only emits characters from the custom alphabet","duration":1.7017079999999964,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody is deterministic for identical input","status":"passed","title":"is deterministic for identical input","duration":0.18387500000000045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["qoderEncodeBody"],"fullName":"qoderEncodeBody produces different output for different input","status":"passed","title":"produces different output for different input","duration":1.0354579999999771,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generatePkcePair"],"fullName":"generatePkcePair produces base64url-safe verifier and challenge of the right length","status":"passed","title":"produces base64url-safe verifier and challenge of the right length","duration":0.8382080000000087,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generatePkcePair"],"fullName":"generatePkcePair verifier and challenge are different (challenge is sha256 of verifier)","status":"passed","title":"verifier and challenge are different (challenge is sha256 of verifier)","duration":0.20599999999998886,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["generatePkcePair"],"fullName":"generatePkcePair returns codeVerifier (not verifier) on the higher-level helper","status":"passed","title":"returns codeVerifier (not verifier) on the higher-level helper","duration":0.36345900000000597,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["initiateDeviceFlow"],"fullName":"initiateDeviceFlow produces a verification URL pointing at qoder.com/device/selectAccounts","status":"passed","title":"produces a verification URL pointing at qoder.com/device/selectAccounts","duration":0.5432920000000081,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["initiateDeviceFlow"],"fullName":"initiateDeviceFlow returns nonce and machineId as UUIDs","status":"passed","title":"returns nonce and machineId as UUIDs","duration":0.4035419999999874,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders produces all required Cosy-* headers","status":"passed","title":"produces all required Cosy-* headers","duration":2.0795420000000036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Authorization is a Bearer COSY token with payload+sig","status":"passed","title":"Authorization is a Bearer COSY token with payload+sig","duration":0.3371669999999938,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Sigpath strips the leading /algo prefix","status":"passed","title":"Cosy-Sigpath strips the leading /algo prefix","duration":0.14866599999999153,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Sigpath also handles the encoded chat URL","status":"passed","title":"Cosy-Sigpath also handles the encoded chat URL","duration":0.1876670000000047,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Bodyhash is the MD5 of the request body, Cosy-Bodylength is the length","status":"passed","title":"Cosy-Bodyhash is the MD5 of the request body, Cosy-Bodylength is the length","duration":0.13554200000001515,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders empty body produces the canonical empty-MD5 hash","status":"passed","title":"empty body produces the canonical empty-MD5 hash","duration":0.14537500000000136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-Machineid + Cosy-Machinetoken match the supplied machineId","status":"passed","title":"Cosy-Machineid + Cosy-Machinetoken match the supplied machineId","duration":0.118583000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders auto-generates a machineId when none is supplied","status":"passed","title":"auto-generates a machineId when none is supplied","duration":0.12145799999998985,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders throws when userId is missing","status":"passed","title":"throws when userId is missing","duration":0.38887499999998454,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders throws when authToken is missing","status":"passed","title":"throws when authToken is missing","duration":0.08966599999999403,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders Cosy-User reflects the supplied userId verbatim","status":"passed","title":"Cosy-User reflects the supplied userId verbatim","duration":0.9228329999999971,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["buildCosyHeaders"],"fullName":"buildCosyHeaders two calls with identical inputs differ only in fields that include fresh randomness","status":"passed","title":"two calls with identical inputs differ only in fields that include fresh randomness","duration":0.8997909999999933,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry accepts ms-epoch as a JSON number","status":"passed","title":"accepts ms-epoch as a JSON number","duration":0.11050000000000182,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry accepts ms-epoch as a numeric string","status":"passed","title":"accepts ms-epoch as a numeric string","duration":0.06470799999999599,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry accepts RFC3339 strings","status":"passed","title":"accepts RFC3339 strings","duration":0.3162089999999864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry does not interpret short numeric strings as a year","status":"passed","title":"does not interpret short numeric strings as a year","duration":0.1442079999999919,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry falls back to expiresInSeconds when expiresAt is missing","status":"passed","title":"falls back to expiresInSeconds when expiresAt is missing","duration":0.43054200000000264,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry treats expires_in: 0 as already expired (now), not 30-day fallback","status":"passed","title":"treats expires_in: 0 as already expired (now), not 30-day fallback","duration":0.1926249999999925,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry falls back to ~30 days when both inputs are missing","status":"passed","title":"falls back to ~30 days when both inputs are missing","duration":0.06016699999997854,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["parseExpiry"],"fullName":"parseExpiry falls back to ~30 days when both inputs are unparseable","status":"passed","title":"falls back to ~30 days when both inputs are unparseable","duration":0.050583000000017364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages hoists role:system out of messages into systemText","status":"passed","title":"hoists role:system out of messages into systemText","duration":0.4399999999999977,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages flattens multipart text content into a string","status":"passed","title":"flattens multipart text content into a string","duration":0.05516700000001151,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages joins multiple system messages with a blank line","status":"passed","title":"joins multiple system messages with a blank line","duration":0.04704199999997627,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["normalizeMessages"],"fullName":"normalizeMessages returns empty results for empty input","status":"passed","title":"returns empty results for empty input","duration":0.10899999999998045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE forwards an OpenAI envelope chunk and emits [DONE] in flush","status":"passed","title":"forwards an OpenAI envelope chunk and emits [DONE] in flush","duration":22.976833,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE drains a trailing partial line without a newline in flush()","status":"passed","title":"drains a trailing partial line without a newline in flush()","duration":0.7435000000000116,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE does not forward chunks after [DONE] has been emitted","status":"passed","title":"does not forward chunks after [DONE] has been emitted","duration":0.549790999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE strips embedded newlines from inner body before forwarding","status":"passed","title":"strips embedded newlines from inner body before forwarding","duration":0.3542500000000075,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE upstream error envelope produces an error chunk + [DONE]","status":"passed","title":"upstream error envelope produces an error chunk + [DONE]","duration":1.8109579999999994,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["wrapQoderSSE"],"fullName":"wrapQoderSSE non-ok responses are returned unchanged (no transform)","status":"passed","title":"non-ok responses are returned unchanged (no transform)","duration":0.3292500000000018,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420334,"endTime":1781357420379.3293,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/qoder.test.js"},{"assertionResults":[{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip injects reasoning_content on a deepseek- assistant message that lacks it","status":"passed","title":"injects reasoning_content on a deepseek- assistant message that lacks it","duration":1.0375840000000096,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip preserves an existing reasoning_content instead of overwriting it","status":"passed","title":"preserves an existing reasoning_content instead of overwriting it","duration":0.20620800000000372,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip applies provider-level rule for provider 'deepseek' (scope all)","status":"passed","title":"applies provider-level rule for provider 'deepseek' (scope all)","duration":0.09204199999999219,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip matches deepseek model id case-insensitively for custom providers (#1543)","status":"passed","title":"matches deepseek model id case-insensitively for custom providers (#1543)","duration":0.1219170000000247,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip does not touch non-deepseek providers/models","status":"passed","title":"does not touch non-deepseek providers/models","duration":0.07816600000001017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — DeepSeek thinking round-trip"],"fullName":"injectReasoningContent — DeepSeek thinking round-trip maps deepseek-v4-pro-none alias to disabled thinking and strips reasoning_effort","status":"passed","title":"maps deepseek-v4-pro-none alias to disabled thinking and strips reasoning_effort","duration":0.14200000000002433,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip injects reasoning_content on a minimax assistant message that lacks it","status":"passed","title":"injects reasoning_content on a minimax assistant message that lacks it","duration":0.12937500000001023,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip injects reasoning_content on minimax assistant message with tool_calls but no reasoning_content","status":"passed","title":"injects reasoning_content on minimax assistant message with tool_calls but no reasoning_content","duration":0.1450839999999971,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip applies provider-level rule for provider 'minimax-cn' (scope all)","status":"passed","title":"applies provider-level rule for provider 'minimax-cn' (scope all)","duration":0.35183399999999665,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip preserves an existing reasoning_content on minimax instead of overwriting","status":"passed","title":"preserves an existing reasoning_content on minimax instead of overwriting","duration":0.0936670000000106,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["injectReasoningContent — MiniMax thinking round-trip"],"fullName":"injectReasoningContent — MiniMax thinking round-trip DefaultExecutor transformRequest runs the injector for minimax","status":"passed","title":"DefaultExecutor transformRequest runs the injector for minimax","duration":10.260250000000013,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenCodeExecutor — issue #1543 regression"],"fullName":"OpenCodeExecutor — issue #1543 regression runs the injector so deepseek-v4-flash-free round-trips reasoning_content","status":"passed","title":"runs the injector so deepseek-v4-flash-free round-trips reasoning_content","duration":0.13495900000000915,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420943,"endTime":1781357420956.2603,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/reasoningContentInjector.test.js"},{"assertionResults":[{"ancestorTitles":["Responses abort terminal synthesis"],"fullName":"Responses abort terminal synthesis emits response.failed + [DONE] when upstream errors (abort/stall)","status":"passed","title":"emits response.failed + [DONE] when upstream errors (abort/stall)","duration":2.309792000000016,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Responses abort terminal synthesis"],"fullName":"Responses abort terminal synthesis does not synthesize terminal for non-Responses streams (callback null)","status":"passed","title":"does not synthesize terminal for non-Responses streams (callback null)","duration":0.32724999999999227,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421308,"endTime":1781357421311.3271,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/responses-abort-terminal.test.js"},{"assertionResults":[{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end server is reachable","status":"skipped","title":"server is reachable","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end rtkEnabled flag is true (user must enable via dashboard)","status":"skipped","title":"rtkEnabled flag is true (user must enable via dashboard)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end compresses git diff tool_result and writes [RTK] savings to log","status":"skipped","title":"compresses git diff tool_result and writes [RTK] savings to log","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK end-to-end"],"fullName":"RTK end-to-end compresses grep-style tool_result","status":"skipped","title":"compresses grep-style tool_result","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417485,"endTime":1781357417485,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/rtk.e2e.test.js"},{"assertionResults":[{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E server reachable and rtkEnabled=true","status":"skipped","title":"server reachable and rtkEnabled=true","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for claude (cc/* → openai→claude)","status":"skipped","title":"compresses git diff for claude (cc/* → openai→claude)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for codex (cx/* → openai→openai-responses)","status":"skipped","title":"compresses git diff for codex (cx/* → openai→openai-responses)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for antigravity (ag/* → openai→antigravity)","status":"skipped","title":"compresses git diff for antigravity (ag/* → openai→antigravity)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for cursor (cu/* → openai→cursor)","status":"skipped","title":"compresses git diff for cursor (cu/* → openai→cursor)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for kiro (kr/* → openai→kiro)","status":"skipped","title":"compresses git diff for kiro (kr/* → openai→kiro)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for gemini (gemini/* → openai→gemini)","status":"skipped","title":"compresses git diff for gemini (gemini/* → openai→gemini)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for deepseek (deepseek/* → openai, passthrough)","status":"skipped","title":"compresses git diff for deepseek (deepseek/* → openai, passthrough)","failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK multi-provider E2E"],"fullName":"RTK multi-provider E2E compresses git diff for ollama (ollama/* → openai→ollama)","status":"skipped","title":"compresses git diff for ollama (ollama/* → openai→ollama)","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417485,"endTime":1781357417485,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/rtk.multi-provider.e2e.test.js"},{"assertionResults":[{"ancestorTitles":["RTK flag"],"fullName":"RTK flag default off, toggle works","status":"failed","title":"default off, toggle works","duration":6.488666000000023,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:58:18\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters gitDiff truncates hunks beyond 100 lines and preserves file header","status":"passed","title":"gitDiff truncates hunks beyond 100 lines and preserves file header","duration":1.082540999999992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters gitStatus groups by kind and produces compact output (Rust format)","status":"passed","title":"gitStatus groups by kind and produces compact output (Rust format)","duration":0.8149579999999901,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters grep groups matches by file and caps per-file lines (Rust format)","status":"passed","title":"grep groups matches by file and caps per-file lines (Rust format)","duration":1.4203339999999685,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters find groups paths by parent dir, shows basenames (Rust format)","status":"passed","title":"find groups paths by parent dir, shows basenames (Rust format)","duration":2.3829579999999737,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters"],"fullName":"RTK filters dedupLog collapses consecutive duplicates","status":"passed","title":"dedupLog collapses consecutive duplicates","duration":0.9325409999999579,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects git diff","status":"passed","title":"detects git diff","duration":0.6444169999999758,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects git status","status":"passed","title":"detects git status","duration":0.3123750000000314,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects grep","status":"passed","title":"detects grep","duration":0.6969170000000418,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter detects find","status":"passed","title":"detects find","duration":0.257000000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter"],"fullName":"autoDetectFilter falls back to dedupLog for generic text","status":"passed","title":"falls back to dedupLog for generic text","duration":0.550625000000025,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) ls: compact_ls strips perms/owner, keeps name + size","status":"passed","title":"ls: compact_ls strips perms/owner, keeps name + size","duration":0.9947920000000181,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) ls: filters noise dirs","status":"passed","title":"ls: filters noise dirs","duration":0.400209000000018,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) tree: removes summary, keeps structure","status":"passed","title":"tree: removes summary, keeps structure","duration":0.16912500000000819,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) smartTruncate: keeps head+tail, drops middle","status":"passed","title":"smartTruncate: keeps head+tail, drops middle","duration":0.4750839999999812,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) smartTruncate: passes through small input","status":"passed","title":"smartTruncate: passes through small input","duration":0.35916700000001356,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) readNumbered: compacts very long line-numbered dump","status":"passed","title":"readNumbered: compacts very long line-numbered dump","duration":0.5577499999999986,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["RTK filters (extras)"],"fullName":"RTK filters (extras) searchList: groups Cursor Glob output by parent dir","status":"passed","title":"searchList: groups Cursor Glob output by parent dir","duration":0.5541670000000067,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter (extras)"],"fullName":"autoDetectFilter (extras) detects tree via box-drawing glyphs","status":"passed","title":"detects tree via box-drawing glyphs","duration":0.4154169999999908,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter (extras)"],"fullName":"autoDetectFilter (extras) detects ls via total + perms rows","status":"passed","title":"detects ls via total + perms rows","duration":0.46708300000000236,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["autoDetectFilter (extras)"],"fullName":"autoDetectFilter (extras) detects Cursor search list","status":"passed","title":"detects Cursor search list","duration":0.33150000000000546,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["safeApply"],"fullName":"safeApply returns input if filter throws","status":"passed","title":"returns input if filter throws","duration":0.4914999999999736,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["safeApply"],"fullName":"safeApply returns input if filter returns non-string","status":"passed","title":"returns input if filter returns non-string","duration":0.041166000000032454,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (disabled)"],"fullName":"compressMessages (disabled) returns null when disabled","status":"failed","title":"returns null when disabled","duration":0.5823750000000132,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:248:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) compresses OpenAI tool message (string content)","status":"failed","title":"compresses OpenAI tool message (string content)","duration":0.3747500000000059,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) compresses Claude string-form tool_result","status":"failed","title":"compresses Claude string-form tool_result","duration":0.24745799999999463,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) compresses Claude array-form tool_result text parts","status":"failed","title":"compresses Claude array-form tool_result text parts","duration":0.19637499999998909,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) skips is_error tool_result","status":"failed","title":"skips is_error tool_result","duration":0.1054589999999962,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) skips below MIN_COMPRESS_SIZE (<500 bytes)","status":"failed","title":"skips below MIN_COMPRESS_SIZE (<500 bytes)","duration":0.092708000000016,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) never produces empty content (R14 guard)","status":"failed","title":"never produces empty content (R14 guard)","duration":0.1705000000000041,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) skips when body has no messages","status":"failed","title":"skips when body has no messages","duration":0.46870799999999235,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["compressMessages (enabled)"],"fullName":"compressMessages (enabled) handles mix of messages without crashing","status":"failed","title":"handles mix of messages without crashing","duration":0.4143750000000068,"failureMessages":["TypeError: (0 , __vite_ssr_import_1__.setRtkEnabled) is not a function\n at /Users/Working/router4/app/tests/unit/rtk.test.js:256:33\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at wrapper (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:722:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2621:52\n at run (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1150:20)\n at limiterFn (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1162:59)\n at runHook (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2620:10)"],"meta":{},"tags":[]},{"ancestorTitles":["formatRtkLog"],"fullName":"formatRtkLog returns null when no hits","status":"passed","title":"returns null when no hits","duration":0.28758400000003803,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["formatRtkLog"],"fullName":"formatRtkLog formats savings line with percentage","status":"passed","title":"formats savings line with percentage","duration":0.3488750000000209,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418074,"endTime":1781357418100.3489,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/rtk.test.js"},{"assertionResults":[{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support compresses tool results in Kiro conversationState.currentMessage","status":"passed","title":"compresses tool results in Kiro conversationState.currentMessage","duration":4.448541000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support compresses tool results in Kiro conversationState.history","status":"passed","title":"compresses tool results in Kiro conversationState.history","duration":0.5248339999999985,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support handles multiple tool results across history and currentMessage","status":"passed","title":"handles multiple tool results across history and currentMessage","duration":0.20795800000001918,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support preserves error tool results without compression","status":"passed","title":"preserves error tool results without compression","duration":0.13850000000002183,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support returns null when RTK is disabled","status":"passed","title":"returns null when RTK is disabled","duration":0.12616700000000947,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support handles Kiro body with no tool results gracefully","status":"passed","title":"handles Kiro body with no tool results gracefully","duration":0.1301249999999925,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Kiro format RTK support"],"fullName":"Kiro format RTK support handles malformed Kiro body without crashing","status":"passed","title":"handles malformed Kiro body without crashing","duration":0.1579590000000053,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421157,"endTime":1781357421163.158,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/rtkKiro.test.js"},{"assertionResults":[{"ancestorTitles":["request normalization"],"fullName":"request normalization claudeToOpenAIRequest flattens text-only content arrays into string","status":"failed","title":"claudeToOpenAIRequest flattens text-only content arrays into string","duration":6.497875000000022,"failureMessages":["AssertionError: expected [ { type: 'text', text: 'hi' }, …(1) ] to be 'hi\\nthere' // Object.is equality\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:24:40\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization claudeToOpenAIRequest preserves multimodal arrays","status":"passed","title":"claudeToOpenAIRequest preserves multimodal arrays","duration":0.2505419999999958,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization filterToOpenAIFormat flattens text-only arrays to string","status":"failed","title":"filterToOpenAIFormat flattens text-only arrays to string","duration":0.7644169999999804,"failureMessages":["AssertionError: expected [ { type: 'text', text: 'a' }, …(1) ] to be 'a\\nb' // Object.is equality\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:65:40\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization translateRequest keeps /v1/messages Claude->OpenAI text payloads string-safe","status":"failed","title":"translateRequest keeps /v1/messages Claude->OpenAI text payloads string-safe","duration":38.047000000000025,"failureMessages":["AssertionError: expected 'object' to be 'string' // Object.is equality\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:95:40\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization translateRequest strips unsupported Anthropic output_config for MiniMax Claude-compatible endpoints","status":"passed","title":"translateRequest strips unsupported Anthropic output_config for MiniMax Claude-compatible endpoints","duration":0.6000000000000227,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization translateRequest preserves output_config for Anthropic Claude","status":"passed","title":"translateRequest preserves output_config for Anthropic Claude","duration":0.3786249999999427,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization parseSSELine supports provider raw NDJSON stream lines","status":"failed","title":"parseSSELine supports provider raw NDJSON stream lines","duration":0.5533339999999498,"failureMessages":["AssertionError: expected null to deeply equal { model: 'gpt-oss:120b', …(2) }\n at /Users/Working/router4/app/tests/unit/translator-request-normalization.test.js:175:20\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/hoanganh/.npm/_npx/69c381f8ad94b576/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64"],"meta":{},"tags":[]},{"ancestorTitles":["request normalization"],"fullName":"request normalization parseSSELine still supports SSE data lines","status":"passed","title":"parseSSELine still supports SSE data lines","duration":0.07891600000004928,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418198,"endTime":1781357418245.5532,"status":"failed","message":"","name":"/Users/Working/router4/app/tests/unit/translator-request-normalization.test.js"},{"assertionResults":[{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:true when response is 200","status":"passed","title":"should return valid:true when response is 200","duration":5.8441250000000196,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:true when response is 400 (auth accepted but bad body)","status":"passed","title":"should return valid:true when response is 400 (auth accepted but bad body)","duration":0.7588330000000099,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:true when response is 429 (rate limited but auth ok)","status":"passed","title":"should return valid:true when response is 429 (rate limited but auth ok)","duration":0.7227499999999907,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:false with error when response is 401","status":"passed","title":"should return valid:false with error when response is 401","duration":0.4235840000000053,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should return valid:false with error when response is 403","status":"passed","title":"should return valid:false with error when response is 403","duration":0.6498750000000086,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should strip sso= prefix from apiKey","status":"passed","title":"should strip sso= prefix from apiKey","duration":0.4539580000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should accept raw token without sso= prefix","status":"passed","title":"should accept raw token without sso= prefix","duration":0.2549590000000137,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should POST to /rest/app-chat/conversations/new","status":"passed","title":"should POST to /rest/app-chat/conversations/new","duration":1.5012499999999989,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["grok-web validation"],"fullName":"grok-web validation should send Cloudflare-bypass headers","status":"passed","title":"should send Cloudflare-bypass headers","duration":1.2718340000000126,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should return valid:true when response is 200","status":"passed","title":"should return valid:true when response is 200","duration":0.4355419999999981,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should return valid:false when response is 401","status":"passed","title":"should return valid:false when response is 401","duration":0.4734589999999912,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should return valid:false when response is 403","status":"passed","title":"should return valid:false when response is 403","duration":0.0987920000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should strip __Secure-next-auth.session-token= prefix","status":"passed","title":"should strip __Secure-next-auth.session-token= prefix","duration":0.09225000000000705,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should accept raw token without prefix","status":"passed","title":"should accept raw token without prefix","duration":0.056707999999986214,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["perplexity-web validation"],"fullName":"perplexity-web validation should POST to /rest/sse/perplexity_ask","status":"passed","title":"should POST to /rest/sse/perplexity_ask","duration":0.23558299999999122,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420965,"endTime":1781357420979.4734,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/web-cookie-validation.test.js"},{"assertionResults":[{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service validates discovered endpoints are https x.ai URLs","status":"passed","title":"validates discovered endpoints are https x.ai URLs","duration":176.55020800000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service discovers endpoints without custom user-agent headers","status":"passed","title":"discovers endpoints without custom user-agent headers","duration":4.559584000000029,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service builds authorize URLs with CLIProxyAPI query extras","status":"passed","title":"builds authorize URLs with CLIProxyAPI query extras","duration":1.4428340000000048,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service generates dashboard auth data with CLIProxyAPI PKCE size and discovered endpoints","status":"passed","title":"generates dashboard auth data with CLIProxyAPI PKCE size and discovered endpoints","duration":832.7239999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/oauth service"],"fullName":"xai/oauth service exchanges dashboard codes against the discovered xAI token endpoint","status":"passed","title":"exchanges dashboard codes against the discovered xAI token endpoint","duration":68.221542,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357418293,"endTime":1781357419376.2214,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/xai-oauth-service.test.js"},{"assertionResults":[{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper refreshXaiToken module loads without throwing","status":"passed","title":"refreshXaiToken module loads without throwing","duration":16.43516600000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper formatProviderCredentials returns Bearer-shape for xai","status":"passed","title":"formatProviderCredentials returns Bearer-shape for xai","duration":0.44054199999999355,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper refreshTokenByProvider returns null when refreshToken missing","status":"passed","title":"refreshTokenByProvider returns null when refreshToken missing","duration":0.13845799999998576,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["xai/token-refresh wrapper"],"fullName":"xai/token-refresh wrapper refreshTokenByProvider returns expiresIn for refreshed xai tokens","status":"passed","title":"refreshTokenByProvider returns expiresIn for refreshed xai tokens","duration":8.223707999999988,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420679,"endTime":1781357420704.2236,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/unit/xai-tokenRefresh.test.js"},{"assertionResults":[{"ancestorTitles":["Antigravity → OpenAI"],"fullName":"Antigravity → OpenAI functionResponse + functionCall in same content keeps both","status":"passed","title":"functionResponse + functionCall in same content keeps both","duration":70.33683299999996,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity → OpenAI"],"fullName":"Antigravity → OpenAI functionCall without id keeps a stable matchable id","status":"passed","title":"functionCall without id keeps a stable matchable id","duration":2.991125000000011,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Antigravity → OpenAI"],"fullName":"Antigravity → OpenAI signature-only part does not produce empty text","status":"passed","title":"signature-only part does not produce empty text","duration":1.811666999999943,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419987,"endTime":1781357420061.8118,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-antigravity.test.js"},{"assertionResults":[{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI system array keeps all text parts","status":"passed","title":"system array keeps all text parts","duration":30.462249999999983,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI assistant thinking block survives Claude→Claude passthrough","status":"passed","title":"assistant thinking block survives Claude→Claude passthrough","duration":0.435292000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI redacted_thinking block is not silently dropped","status":"passed","title":"redacted_thinking block is not silently dropped","duration":5.601832999999999,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Claude Code CLI context → OpenAI"],"fullName":"Claude Code CLI context → OpenAI tool_result image block is preserved","status":"passed","title":"tool_result image block is preserved","duration":2.006584000000032,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420245,"endTime":1781357420284.0066,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-claudeCode-context.test.js"},{"assertionResults":[{"ancestorTitles":["Codex CLI Responses → OpenAI"],"fullName":"Codex CLI Responses → OpenAI assistant has no empty tool_calls array when all names are empty","status":"passed","title":"assistant has no empty tool_calls array when all names are empty","duration":34.838250000000016,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex CLI Responses → OpenAI"],"fullName":"Codex CLI Responses → OpenAI function_call arguments end up as a string","status":"passed","title":"function_call arguments end up as a string","duration":3.1472499999999854,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["Codex CLI Responses → OpenAI"],"fullName":"Codex CLI Responses → OpenAI input_image with file_id is not used as a raw url","status":"passed","title":"input_image with file_id is not used as a raw url","duration":1.2459160000000224,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Codex Responses (reverse)"],"fullName":"OpenAI → Codex Responses (reverse) call_id longer than 64 chars is clamped","status":"passed","title":"call_id longer than 64 chars is clamped","duration":0.35595800000004374,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420270,"endTime":1781357420309.356,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-codexCli-responses.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI → Gemini"],"fullName":"OpenAI → Gemini multiple system messages are all kept","status":"passed","title":"multiple system messages are all kept","duration":43.64804099999998,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Cursor"],"fullName":"OpenAI → Cursor image content is preserved","status":"passed","title":"image content is preserved","duration":1.1759589999999776,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Cursor"],"fullName":"OpenAI → Cursor respects client max_tokens","status":"passed","title":"respects client max_tokens","duration":4.252125000000035,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → CommandCode"],"fullName":"OpenAI → CommandCode malformed tool arguments are not silently emptied","status":"passed","title":"malformed tool arguments are not silently emptied","duration":9.410250000000019,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → CommandCode"],"fullName":"OpenAI → CommandCode image content is preserved","status":"passed","title":"image content is preserved","duration":1.586500000000001,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419300,"endTime":1781357419360.5864,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-gemini-cursor-commandcode.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI → Kiro"],"fullName":"OpenAI → Kiro malformed tool arguments do not throw the whole request","status":"passed","title":"malformed tool arguments do not throw the whole request","duration":32.290333000000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Kiro"],"fullName":"OpenAI → Kiro respects client max_tokens","status":"passed","title":"respects client max_tokens","duration":3.8617500000000007,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Kiro"],"fullName":"OpenAI → Kiro remote image url is preserved as an image, not text","status":"passed","title":"remote image url is preserved as an image, not text","duration":3.9039579999999887,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419414,"endTime":1781357419453.904,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-kiro.test.js"},{"assertionResults":[{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss image with source.type=url is preserved (NOT dropped)","status":"passed","title":"image with source.type=url is preserved (NOT dropped)","duration":59.27058400000004,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss thinking block survives round-trip Claude→OpenAI→Claude","status":"passed","title":"thinking block survives round-trip Claude→OpenAI→Claude","duration":2.403332999999975,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss tool_result with image block is not turned into raw JSON / dropped","status":"passed","title":"tool_result with image block is not turned into raw JSON / dropped","duration":2.4572499999999877,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss tool_result is_error flag is preserved","status":"passed","title":"tool_result is_error flag is preserved","duration":2.361500000000035,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: Claude → OpenAI bridge data loss"],"fullName":"bug: Claude → OpenAI bridge data loss system array non-text parts are not silently dropped","status":"passed","title":"system array non-text parts are not silently dropped","duration":1.1465840000000185,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: tool_call id stability across bridge"],"fullName":"bug: tool_call id stability across bridge sanitized tool id stays matched between call and result","status":"passed","title":"sanitized tool id stays matched between call and result","duration":0.23770899999999529,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["bug: empty content message handling"],"fullName":"bug: empty content message handling assistant message with only tool_calls is not dropped","status":"passed","title":"assistant message with only tool_calls is not dropped","duration":0.7614169999999945,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419837,"endTime":1781357419906.7615,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-openai-bridge.test.js"},{"assertionResults":[{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping does not inject Claude Code system prompt for compatible providers","status":"passed","title":"does not inject Claude Code system prompt for compatible providers","duration":55.912874999999985,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping assistant reasoning_content becomes a thinking block","status":"passed","title":"assistant reasoning_content becomes a thinking block","duration":1.6859160000000202,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping tool_choice=none is not turned into auto","status":"passed","title":"tool_choice=none is not turned into auto","duration":0.6051669999999945,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping input_audio content is preserved","status":"passed","title":"input_audio content is preserved","duration":0.6409170000000017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["OpenAI → Claude context mapping"],"fullName":"OpenAI → Claude context mapping remote http image_url is preserved","status":"passed","title":"remote http image_url is preserved","duration":0.37454200000001947,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420491,"endTime":1781357420550.3745,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/bugs-toClaude-context.test.js"},{"assertionResults":[{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cc': all models OpenAI→target","status":"passed","title":"'cc': all models OpenAI→target","duration":72.16029200000003,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cx': all models OpenAI→target","status":"passed","title":"'cx': all models OpenAI→target","duration":1.2824589999999603,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gc': all models OpenAI→target","status":"passed","title":"'gc': all models OpenAI→target","duration":1.4795420000000377,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'qw': all models OpenAI→target","status":"passed","title":"'qw': all models OpenAI→target","duration":0.37274999999999636,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'if': all models OpenAI→target","status":"passed","title":"'if': all models OpenAI→target","duration":0.39066700000000765,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'ag': all models OpenAI→target","status":"passed","title":"'ag': all models OpenAI→target","duration":1.6819590000000062,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gh': all models OpenAI→target","status":"passed","title":"'gh': all models OpenAI→target","duration":0.7901659999999993,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kr': all models OpenAI→target","status":"passed","title":"'kr': all models OpenAI→target","duration":4.4877500000000055,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'qd': all models OpenAI→target","status":"passed","title":"'qd': all models OpenAI→target","duration":0.5998749999999973,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cu': all models OpenAI→target","status":"passed","title":"'cu': all models OpenAI→target","duration":3.7765830000000165,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kmc': all models OpenAI→target","status":"passed","title":"'kmc': all models OpenAI→target","duration":0.40554199999996854,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kc': all models OpenAI→target","status":"passed","title":"'kc': all models OpenAI→target","duration":0.1564999999999941,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'opencode-go': all models OpenAI→target","status":"passed","title":"'opencode-go': all models OpenAI→target","duration":0.15104199999996126,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'mmf': all models OpenAI→target","status":"passed","title":"'mmf': all models OpenAI→target","duration":0.034958000000017364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cl': all models OpenAI→target","status":"passed","title":"'cl': all models OpenAI→target","duration":0.09925000000004047,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openai': all models OpenAI→target","status":"passed","title":"'openai': all models OpenAI→target","duration":1.4176249999999868,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'anthropic': all models OpenAI→target","status":"passed","title":"'anthropic': all models OpenAI→target","duration":0.0993750000000091,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gemini': all models OpenAI→target","status":"passed","title":"'gemini': all models OpenAI→target","duration":0.22162500000001728,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openrouter': all models OpenAI→target","status":"passed","title":"'openrouter': all models OpenAI→target","duration":0.14474999999998772,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'glm': all models OpenAI→target","status":"passed","title":"'glm': all models OpenAI→target","duration":0.07362499999999272,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'glm-cn': all models OpenAI→target","status":"passed","title":"'glm-cn': all models OpenAI→target","duration":0.06374999999997044,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kimi': all models OpenAI→target","status":"passed","title":"'kimi': all models OpenAI→target","duration":0.06100000000003547,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'minimax': all models OpenAI→target","status":"passed","title":"'minimax': all models OpenAI→target","duration":0.062124999999980446,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'blackbox': all models OpenAI→target","status":"passed","title":"'blackbox': all models OpenAI→target","duration":0.643209000000013,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'minimax-cn': all models OpenAI→target","status":"passed","title":"'minimax-cn': all models OpenAI→target","duration":0.3412500000000023,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'alicode': all models OpenAI→target","status":"passed","title":"'alicode': all models OpenAI→target","duration":0.3019170000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'alicode-intl': all models OpenAI→target","status":"passed","title":"'alicode-intl': all models OpenAI→target","duration":0.0993750000000091,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'volcengine-ark': all models OpenAI→target","status":"passed","title":"'volcengine-ark': all models OpenAI→target","duration":0.0997499999999718,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cloudflare-ai': all models OpenAI→target","status":"passed","title":"'cloudflare-ai': all models OpenAI→target","duration":0.12954200000001492,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'byteplus': all models OpenAI→target","status":"passed","title":"'byteplus': all models OpenAI→target","duration":0.0806660000000079,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'deepseek': all models OpenAI→target","status":"passed","title":"'deepseek': all models OpenAI→target","duration":0.07229200000000446,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'commandcode': all models OpenAI→target","status":"passed","title":"'commandcode': all models OpenAI→target","duration":0.6159999999999854,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'groq': all models OpenAI→target","status":"passed","title":"'groq': all models OpenAI→target","duration":0.07137499999998909,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'xai': all models OpenAI→target","status":"passed","title":"'xai': all models OpenAI→target","duration":0.06083300000000236,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'mistral': all models OpenAI→target","status":"passed","title":"'mistral': all models OpenAI→target","duration":0.045707999999990534,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'perplexity': all models OpenAI→target","status":"passed","title":"'perplexity': all models OpenAI→target","duration":0.03716700000001083,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'together': all models OpenAI→target","status":"passed","title":"'together': all models OpenAI→target","duration":0.054082999999991443,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'fireworks': all models OpenAI→target","status":"passed","title":"'fireworks': all models OpenAI→target","duration":0.14187499999997044,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cerebras': all models OpenAI→target","status":"passed","title":"'cerebras': all models OpenAI→target","duration":0.22066699999999173,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'cohere': all models OpenAI→target","status":"passed","title":"'cohere': all models OpenAI→target","duration":0.060625000000015916,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nvidia': all models OpenAI→target","status":"passed","title":"'nvidia': all models OpenAI→target","duration":0.03933399999999665,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nebius': all models OpenAI→target","status":"passed","title":"'nebius': all models OpenAI→target","duration":0.026666999999974905,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'voyage-ai': all models OpenAI→target","status":"passed","title":"'voyage-ai': all models OpenAI→target","duration":0.07408299999997325,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'siliconflow': all models OpenAI→target","status":"passed","title":"'siliconflow': all models OpenAI→target","duration":0.14766600000001517,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'xiaomi-mimo': all models OpenAI→target","status":"passed","title":"'xiaomi-mimo': all models OpenAI→target","duration":0.0805000000000291,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'xiaomi-tokenplan': all models OpenAI→target","status":"passed","title":"'xiaomi-tokenplan': all models OpenAI→target","duration":0.10941600000001017,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'hyperbolic': all models OpenAI→target","status":"passed","title":"'hyperbolic': all models OpenAI→target","duration":0.08329200000002857,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'ollama': all models OpenAI→target","status":"passed","title":"'ollama': all models OpenAI→target","duration":0.48337500000002365,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'vertex': all models OpenAI→target","status":"passed","title":"'vertex': all models OpenAI→target","duration":0.15966600000001563,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'vertex-partner': all models OpenAI→target","status":"passed","title":"'vertex-partner': all models OpenAI→target","duration":0.055124999999975444,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'grok-web': all models OpenAI→target","status":"passed","title":"'grok-web': all models OpenAI→target","duration":0.10583300000001827,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'perplexity-web': all models OpenAI→target","status":"passed","title":"'perplexity-web': all models OpenAI→target","duration":0.06662499999998772,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openai-tts-models': all models OpenAI→target","status":"passed","title":"'openai-tts-models': all models OpenAI→target","duration":0.23250000000001592,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openai-tts-voices': all models OpenAI→target","status":"passed","title":"'openai-tts-voices': all models OpenAI→target","duration":5.8156660000000215,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openrouter-tts-models': all models OpenAI→target","status":"passed","title":"'openrouter-tts-models': all models OpenAI→target","duration":0.1292500000000132,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'openrouter-tts-voices': all models OpenAI→target","status":"passed","title":"'openrouter-tts-voices': all models OpenAI→target","duration":0.14579199999997172,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'elevenlabs-tts-models': all models OpenAI→target","status":"passed","title":"'elevenlabs-tts-models': all models OpenAI→target","duration":0.05520899999999074,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'edge-tts': all models OpenAI→target","status":"passed","title":"'edge-tts': all models OpenAI→target","duration":0.10849999999999227,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'local-device': all models OpenAI→target","status":"passed","title":"'local-device': all models OpenAI→target","duration":0.026917000000025837,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'google-tts': all models OpenAI→target","status":"passed","title":"'google-tts': all models OpenAI→target","duration":0.5269170000000258,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gemini-tts-models': all models OpenAI→target","status":"passed","title":"'gemini-tts-models': all models OpenAI→target","duration":0.04191699999995535,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'gemini-tts-voices': all models OpenAI→target","status":"passed","title":"'gemini-tts-voices': all models OpenAI→target","duration":0.5273749999999495,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nanobanana': all models OpenAI→target","status":"passed","title":"'nanobanana': all models OpenAI→target","duration":0.06324999999998226,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'sdwebui': all models OpenAI→target","status":"passed","title":"'sdwebui': all models OpenAI→target","duration":0.03866699999997536,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'comfyui': all models OpenAI→target","status":"passed","title":"'comfyui': all models OpenAI→target","duration":0.0343340000000012,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'huggingface': all models OpenAI→target","status":"passed","title":"'huggingface': all models OpenAI→target","duration":0.05170900000001666,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'agentrouter': all models OpenAI→target","status":"passed","title":"'agentrouter': all models OpenAI→target","duration":0.08312499999999545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'aimlapi': all models OpenAI→target","status":"passed","title":"'aimlapi': all models OpenAI→target","duration":0.34287499999999227,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'novita': all models OpenAI→target","status":"passed","title":"'novita': all models OpenAI→target","duration":0.06187499999998636,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'modal': all models OpenAI→target","status":"passed","title":"'modal': all models OpenAI→target","duration":0.031207999999992353,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'reka': all models OpenAI→target","status":"passed","title":"'reka': all models OpenAI→target","duration":0.03554100000002336,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nlpcloud': all models OpenAI→target","status":"passed","title":"'nlpcloud': all models OpenAI→target","duration":0.059332999999980984,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'bazaarlink': all models OpenAI→target","status":"passed","title":"'bazaarlink': all models OpenAI→target","duration":0.03520800000001145,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'completions': all models OpenAI→target","status":"passed","title":"'completions': all models OpenAI→target","duration":0.05158399999999119,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'enally': all models OpenAI→target","status":"passed","title":"'enally': all models OpenAI→target","duration":0.039917000000002645,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'freetheai': all models OpenAI→target","status":"passed","title":"'freetheai': all models OpenAI→target","duration":0.04895800000002737,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'llm7': all models OpenAI→target","status":"passed","title":"'llm7': all models OpenAI→target","duration":0.04016599999999926,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'lepton': all models OpenAI→target","status":"passed","title":"'lepton': all models OpenAI→target","duration":0.07337499999999864,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'kluster': all models OpenAI→target","status":"passed","title":"'kluster': all models OpenAI→target","duration":0.056207999999969616,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'ai21': all models OpenAI→target","status":"passed","title":"'ai21': all models OpenAI→target","duration":0.05424999999996771,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'inference-net': all models OpenAI→target","status":"passed","title":"'inference-net': all models OpenAI→target","duration":0.04241700000000037,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'predibase': all models OpenAI→target","status":"passed","title":"'predibase': all models OpenAI→target","duration":0.06312500000001364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'bytez': all models OpenAI→target","status":"passed","title":"'bytez': all models OpenAI→target","duration":0.042208000000016455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'morph': all models OpenAI→target","status":"passed","title":"'morph': all models OpenAI→target","duration":0.03262499999999591,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'longcat': all models OpenAI→target","status":"passed","title":"'longcat': all models OpenAI→target","duration":0.043040999999959695,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'puter': all models OpenAI→target","status":"passed","title":"'puter': all models OpenAI→target","duration":0.2721250000000168,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'uncloseai': all models OpenAI→target","status":"passed","title":"'uncloseai': all models OpenAI→target","duration":0.400209000000018,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'scaleway': all models OpenAI→target","status":"passed","title":"'scaleway': all models OpenAI→target","duration":0.14537500000000136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'deepinfra': all models OpenAI→target","status":"passed","title":"'deepinfra': all models OpenAI→target","duration":0.05091599999997243,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'sambanova': all models OpenAI→target","status":"passed","title":"'sambanova': all models OpenAI→target","duration":0.04541700000004312,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nscale': all models OpenAI→target","status":"passed","title":"'nscale': all models OpenAI→target","duration":0.03541699999999537,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'baseten': all models OpenAI→target","status":"passed","title":"'baseten': all models OpenAI→target","duration":0.03412500000001728,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'publicai': all models OpenAI→target","status":"passed","title":"'publicai': all models OpenAI→target","duration":0.025458999999955267,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'nous-research': all models OpenAI→target","status":"passed","title":"'nous-research': all models OpenAI→target","duration":0.03483399999998937,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'glhf': all models OpenAI→target","status":"passed","title":"'glhf': all models OpenAI→target","duration":0.11449999999996407,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'deepgram': all models OpenAI→target","status":"passed","title":"'deepgram': all models OpenAI→target","duration":0.11358300000000554,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'assemblyai': all models OpenAI→target","status":"passed","title":"'assemblyai': all models OpenAI→target","duration":0.03683399999999892,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'fal-ai': all models OpenAI→target","status":"passed","title":"'fal-ai': all models OpenAI→target","duration":0.07879200000002129,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'stability-ai': all models OpenAI→target","status":"passed","title":"'stability-ai': all models OpenAI→target","duration":0.060708000000033735,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'black-forest-labs': all models OpenAI→target","status":"passed","title":"'black-forest-labs': all models OpenAI→target","duration":0.06979200000000674,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'recraft': all models OpenAI→target","status":"passed","title":"'recraft': all models OpenAI→target","duration":0.03404199999999946,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: every model translates without throwing"],"fullName":"coverage: every model translates without throwing 'runwayml': all models OpenAI→target","status":"passed","title":"'runwayml': all models OpenAI→target","duration":0.04954200000003084,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: image-strip models drop image content"],"fullName":"coverage: image-strip models drop image content 'kr'/'deepseek-3.2' strips image when strip=[image]","status":"passed","title":"'kr'/'deepseek-3.2' strips image when strip=[image]","duration":0.18833300000000008,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["coverage: image-strip models drop image content"],"fullName":"coverage: image-strip models drop image content 'kr'/'qwen3-coder-next' strips image when strip=[image]","status":"passed","title":"'kr'/'qwen3-coder-next' strips image when strip=[image]","duration":0.04866700000002311,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419320,"endTime":1781357419427.1882,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/coverage-all-models.test.js"},{"assertionResults":[{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI system → system role","status":"passed","title":"system → system role","duration":0.9897080000000074,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI tool_use → assistant.tool_calls with matching id","status":"passed","title":"tool_use → assistant.tool_calls with matching id","duration":0.22016600000000608,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI tool_result → tool message with matching id","status":"passed","title":"tool_result → tool message with matching id","duration":0.14220800000001077,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: Claude source preserves core fields → OpenAI"],"fullName":"roundtrip: Claude source preserves core fields → OpenAI tool arguments are valid JSON string","status":"passed","title":"tool arguments are valid JSON string","duration":0.4284170000000245,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: OpenAI tools → Claude → keeps tool name"],"fullName":"roundtrip: OpenAI tools → Claude → keeps tool name tool name survives openai→claude","status":"passed","title":"tool name survives openai→claude","duration":0.127666999999974,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: parallel tool calls keep distinct ids"],"fullName":"roundtrip: parallel tool calls keep distinct ids two tool_calls, two distinct ids","status":"passed","title":"two tool_calls, two distinct ids","duration":0.07941700000000651,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["roundtrip: parallel tool calls keep distinct ids"],"fullName":"roundtrip: parallel tool calls keep distinct ids each tool_call has a matching tool result","status":"passed","title":"each tool_call has a matching tool result","duration":0.1069169999999815,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357421475,"endTime":1781357421477.4285,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/format-roundtrip.test.js"},{"assertionResults":[{"ancestorTitles":["GOLDEN request: OpenAI → Claude"],"fullName":"GOLDEN request: OpenAI → Claude full body (system/image/tool/tool_result)","status":"passed","title":"full body (system/image/tool/tool_result)","duration":36.29050000000001,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN request: OpenAI → Claude"],"fullName":"GOLDEN request: OpenAI → Claude reasoning_effort → thinking budget","status":"passed","title":"reasoning_effort → thinking budget","duration":1.0628750000000196,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN request: OpenAI → Gemini"],"fullName":"GOLDEN request: OpenAI → Gemini full body (system/image/tool/tool_result)","status":"passed","title":"full body (system/image/tool/tool_result)","duration":2.0823749999999563,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN request: OpenAI → Kiro"],"fullName":"GOLDEN request: OpenAI → Kiro full body (image base64 + tool_result)","status":"passed","title":"full body (image base64 + tool_result)","duration":4.222083999999995,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420197,"endTime":1781357420241.2222,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/golden-request.test.js"},{"assertionResults":[{"ancestorTitles":["GOLDEN response stream: Claude → OpenAI"],"fullName":"GOLDEN response stream: Claude → OpenAI text + thinking + tool_use + usage + finish","status":"passed","title":"text + thinking + tool_use + usage + finish","duration":220.46841600000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Gemini → OpenAI"],"fullName":"GOLDEN response stream: Gemini → OpenAI text + thought(no-sig) + functionCall + usage + finish","status":"passed","title":"text + thought(no-sig) + functionCall + usage + finish","duration":1.9031249999999886,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Gemini → OpenAI"],"fullName":"GOLDEN response stream: Gemini → OpenAI image output (inlineData → delta.images)","status":"passed","title":"image output (inlineData → delta.images)","duration":1.1042079999999714,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Kiro → OpenAI"],"fullName":"GOLDEN response stream: Kiro → OpenAI text + reasoning + toolUse + usage + stop","status":"passed","title":"text + reasoning + toolUse + usage + stop","duration":3.180749999999989,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: Ollama → OpenAI"],"fullName":"GOLDEN response stream: Ollama → OpenAI content + thinking + tool_calls + done usage","status":"passed","title":"content + thinking + tool_calls + done usage","duration":0.799541999999974,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: OpenAI-Responses (codex) → OpenAI"],"fullName":"GOLDEN response stream: OpenAI-Responses (codex) → OpenAI text + reasoning + tool_call + completed usage","status":"passed","title":"text + reasoning + tool_call + completed usage","duration":0.9961660000000165,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN response stream: OpenAI-Responses (codex) → OpenAI"],"fullName":"GOLDEN response stream: OpenAI-Responses (codex) → OpenAI error event → error chunk (fallback id/created)","status":"passed","title":"error event → error chunk (fallback id/created)","duration":0.5871250000000146,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357419600,"endTime":1781357419829.5872,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/golden-response-stream.test.js"},{"assertionResults":[{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) agentrouter → url (stream + non-stream)","status":"passed","title":"agentrouter → url (stream + non-stream)","duration":4.1732920000000036,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) ai21 → url (stream + non-stream)","status":"passed","title":"ai21 → url (stream + non-stream)","duration":0.38016700000000014,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) aimlapi → url (stream + non-stream)","status":"passed","title":"aimlapi → url (stream + non-stream)","duration":0.19050000000001432,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) alicode → url (stream + non-stream)","status":"passed","title":"alicode → url (stream + non-stream)","duration":0.16754199999999742,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) alicode-intl → url (stream + non-stream)","status":"passed","title":"alicode-intl → url (stream + non-stream)","duration":0.16300000000001091,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) anthropic → url (stream + non-stream)","status":"passed","title":"anthropic → url (stream + non-stream)","duration":0.0952920000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) assemblyai → url (stream + non-stream)","status":"passed","title":"assemblyai → url (stream + non-stream)","duration":0.13262499999999022,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) baseten → url (stream + non-stream)","status":"passed","title":"baseten → url (stream + non-stream)","duration":0.08541700000000674,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) bazaarlink → url (stream + non-stream)","status":"passed","title":"bazaarlink → url (stream + non-stream)","duration":0.6658339999999896,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) blackbox → url (stream + non-stream)","status":"passed","title":"blackbox → url (stream + non-stream)","duration":2.319166999999993,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) byteplus → url (stream + non-stream)","status":"passed","title":"byteplus → url (stream + non-stream)","duration":1.3785840000000178,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) bytez → url (stream + non-stream)","status":"passed","title":"bytez → url (stream + non-stream)","duration":0.07612500000001887,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cerebras → url (stream + non-stream)","status":"passed","title":"cerebras → url (stream + non-stream)","duration":0.051000000000016144,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) chutes → url (stream + non-stream)","status":"passed","title":"chutes → url (stream + non-stream)","duration":0.046125000000017735,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) claude → url (stream + non-stream)","status":"passed","title":"claude → url (stream + non-stream)","duration":0.05104199999999537,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cline → url (stream + non-stream)","status":"passed","title":"cline → url (stream + non-stream)","duration":0.09475000000000477,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cloudflare-ai → url (stream + non-stream)","status":"passed","title":"cloudflare-ai → url (stream + non-stream)","duration":0.04620800000000713,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) codebuddy → url (stream + non-stream)","status":"passed","title":"codebuddy → url (stream + non-stream)","duration":0.039042000000023336,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) cohere → url (stream + non-stream)","status":"passed","title":"cohere → url (stream + non-stream)","duration":0.03937500000000682,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) completions → url (stream + non-stream)","status":"passed","title":"completions → url (stream + non-stream)","duration":0.039332999999999174,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) deepgram → url (stream + non-stream)","status":"passed","title":"deepgram → url (stream + non-stream)","duration":0.03874999999999318,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) deepinfra → url (stream + non-stream)","status":"passed","title":"deepinfra → url (stream + non-stream)","duration":0.03741700000000492,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) deepseek → url (stream + non-stream)","status":"passed","title":"deepseek → url (stream + non-stream)","duration":0.03629199999997468,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) enally → url (stream + non-stream)","status":"passed","title":"enally → url (stream + non-stream)","duration":0.04058299999999804,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) fireworks → url (stream + non-stream)","status":"passed","title":"fireworks → url (stream + non-stream)","duration":0.09779199999999832,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) freetheai → url (stream + non-stream)","status":"passed","title":"freetheai → url (stream + non-stream)","duration":0.05737499999997908,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) gemini → url (stream + non-stream)","status":"passed","title":"gemini → url (stream + non-stream)","duration":0.047875000000004775,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) gitlab → url (stream + non-stream)","status":"passed","title":"gitlab → url (stream + non-stream)","duration":0.043250000000000455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) glhf → url (stream + non-stream)","status":"passed","title":"glhf → url (stream + non-stream)","duration":0.039500000000003865,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) glm → url (stream + non-stream)","status":"passed","title":"glm → url (stream + non-stream)","duration":0.04024999999998613,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) glm-cn → url (stream + non-stream)","status":"passed","title":"glm-cn → url (stream + non-stream)","duration":0.03745799999998667,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) groq → url (stream + non-stream)","status":"passed","title":"groq → url (stream + non-stream)","duration":0.03708399999999301,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) hyperbolic → url (stream + non-stream)","status":"passed","title":"hyperbolic → url (stream + non-stream)","duration":0.037208000000021,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) inference-net → url (stream + non-stream)","status":"passed","title":"inference-net → url (stream + non-stream)","duration":0.036624999999986585,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kilocode → url (stream + non-stream)","status":"passed","title":"kilocode → url (stream + non-stream)","duration":0.036333999999982325,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kimi → url (stream + non-stream)","status":"passed","title":"kimi → url (stream + non-stream)","duration":0.035124999999993634,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kimi-coding → url (stream + non-stream)","status":"passed","title":"kimi-coding → url (stream + non-stream)","duration":0.03779199999999605,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) kluster → url (stream + non-stream)","status":"passed","title":"kluster → url (stream + non-stream)","duration":0.03608400000001666,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) lepton → url (stream + non-stream)","status":"passed","title":"lepton → url (stream + non-stream)","duration":0.03533400000000597,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) llm7 → url (stream + non-stream)","status":"passed","title":"llm7 → url (stream + non-stream)","duration":0.03441600000002154,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) longcat → url (stream + non-stream)","status":"passed","title":"longcat → url (stream + non-stream)","duration":0.03495899999998642,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) minimax → url (stream + non-stream)","status":"passed","title":"minimax → url (stream + non-stream)","duration":0.03437500000001137,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) minimax-cn → url (stream + non-stream)","status":"passed","title":"minimax-cn → url (stream + non-stream)","duration":0.12074999999998681,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) mistral → url (stream + non-stream)","status":"passed","title":"mistral → url (stream + non-stream)","duration":0.5602499999999964,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) mmf → url (stream + non-stream)","status":"passed","title":"mmf → url (stream + non-stream)","duration":0.15541600000000244,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) modal → url (stream + non-stream)","status":"passed","title":"modal → url (stream + non-stream)","duration":0.043250000000000455,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) morph → url (stream + non-stream)","status":"passed","title":"morph → url (stream + non-stream)","duration":0.03712499999997476,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nanobanana → url (stream + non-stream)","status":"passed","title":"nanobanana → url (stream + non-stream)","duration":0.15158299999998803,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nebius → url (stream + non-stream)","status":"passed","title":"nebius → url (stream + non-stream)","duration":0.5043749999999818,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nlpcloud → url (stream + non-stream)","status":"passed","title":"nlpcloud → url (stream + non-stream)","duration":0.19208399999999415,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nous-research → url (stream + non-stream)","status":"passed","title":"nous-research → url (stream + non-stream)","duration":0.056583999999986645,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) novita → url (stream + non-stream)","status":"passed","title":"novita → url (stream + non-stream)","duration":0.04091700000000742,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nscale → url (stream + non-stream)","status":"passed","title":"nscale → url (stream + non-stream)","duration":0.07099999999999795,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) nvidia → url (stream + non-stream)","status":"passed","title":"nvidia → url (stream + non-stream)","duration":0.05579199999999673,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) ollama → url (stream + non-stream)","status":"passed","title":"ollama → url (stream + non-stream)","duration":0.04391699999999332,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) openai → url (stream + non-stream)","status":"passed","title":"openai → url (stream + non-stream)","duration":0.038375000000002046,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) openrouter → url (stream + non-stream)","status":"passed","title":"openrouter → url (stream + non-stream)","duration":0.15712500000000773,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) perplexity → url (stream + non-stream)","status":"passed","title":"perplexity → url (stream + non-stream)","duration":0.34070800000000645,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) predibase → url (stream + non-stream)","status":"passed","title":"predibase → url (stream + non-stream)","duration":0.10512500000001523,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) publicai → url (stream + non-stream)","status":"passed","title":"publicai → url (stream + non-stream)","duration":0.05508299999999622,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) puter → url (stream + non-stream)","status":"passed","title":"puter → url (stream + non-stream)","duration":0.04441700000000992,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) reka → url (stream + non-stream)","status":"passed","title":"reka → url (stream + non-stream)","duration":0.04249999999998977,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) sambanova → url (stream + non-stream)","status":"passed","title":"sambanova → url (stream + non-stream)","duration":0.04062499999997726,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) scaleway → url (stream + non-stream)","status":"passed","title":"scaleway → url (stream + non-stream)","duration":0.041249999999990905,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) siliconflow → url (stream + non-stream)","status":"passed","title":"siliconflow → url (stream + non-stream)","duration":0.04487499999999045,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) together → url (stream + non-stream)","status":"passed","title":"together → url (stream + non-stream)","duration":0.038000000000010914,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) uncloseai → url (stream + non-stream)","status":"passed","title":"uncloseai → url (stream + non-stream)","duration":0.03808300000000031,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) vercel-ai-gateway → url (stream + non-stream)","status":"passed","title":"vercel-ai-gateway → url (stream + non-stream)","duration":0.039709000000016204,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) volcengine-ark → url (stream + non-stream)","status":"passed","title":"volcengine-ark → url (stream + non-stream)","duration":0.07458299999998985,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) xai → url (stream + non-stream)","status":"passed","title":"xai → url (stream + non-stream)","duration":0.040124999999989086,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildUrl (default executor providers)"],"fullName":"GOLDEN buildUrl (default executor providers) xiaomi-mimo → url (stream + non-stream)","status":"passed","title":"xiaomi-mimo → url (stream + non-stream)","duration":0.05379199999998718,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) agentrouter → headers (apiKey / oauth)","status":"passed","title":"agentrouter → headers (apiKey / oauth)","duration":0.5167500000000018,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) ai21 → headers (apiKey / oauth)","status":"passed","title":"ai21 → headers (apiKey / oauth)","duration":0.11687499999999318,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) aimlapi → headers (apiKey / oauth)","status":"passed","title":"aimlapi → headers (apiKey / oauth)","duration":0.52366600000002,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) alicode → headers (apiKey / oauth)","status":"passed","title":"alicode → headers (apiKey / oauth)","duration":0.24133299999999736,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) alicode-intl → headers (apiKey / oauth)","status":"passed","title":"alicode-intl → headers (apiKey / oauth)","duration":0.35595899999998437,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) anthropic → headers (apiKey / oauth)","status":"passed","title":"anthropic → headers (apiKey / oauth)","duration":0.4431669999999883,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) assemblyai → headers (apiKey / oauth)","status":"passed","title":"assemblyai → headers (apiKey / oauth)","duration":0.39537500000000136,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) baseten → headers (apiKey / oauth)","status":"passed","title":"baseten → headers (apiKey / oauth)","duration":0.35354199999997604,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) bazaarlink → headers (apiKey / oauth)","status":"passed","title":"bazaarlink → headers (apiKey / oauth)","duration":0.15829100000001972,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) blackbox → headers (apiKey / oauth)","status":"passed","title":"blackbox → headers (apiKey / oauth)","duration":0.12562500000001364,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) byteplus → headers (apiKey / oauth)","status":"passed","title":"byteplus → headers (apiKey / oauth)","duration":0.14662500000000023,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) bytez → headers (apiKey / oauth)","status":"passed","title":"bytez → headers (apiKey / oauth)","duration":0.09499999999999886,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cerebras → headers (apiKey / oauth)","status":"passed","title":"cerebras → headers (apiKey / oauth)","duration":0.06912499999998545,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) chutes → headers (apiKey / oauth)","status":"passed","title":"chutes → headers (apiKey / oauth)","duration":0.06420900000000529,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) claude → headers (apiKey / oauth)","status":"passed","title":"claude → headers (apiKey / oauth)","duration":0.19599999999999795,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cline → headers (apiKey / oauth)","status":"passed","title":"cline → headers (apiKey / oauth)","duration":0.3664169999999842,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cloudflare-ai → headers (apiKey / oauth)","status":"passed","title":"cloudflare-ai → headers (apiKey / oauth)","duration":1.8253749999999798,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) codebuddy → headers (apiKey / oauth)","status":"passed","title":"codebuddy → headers (apiKey / oauth)","duration":0.23312500000000114,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) cohere → headers (apiKey / oauth)","status":"passed","title":"cohere → headers (apiKey / oauth)","duration":0.07420799999999872,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) completions → headers (apiKey / oauth)","status":"passed","title":"completions → headers (apiKey / oauth)","duration":0.06120799999999349,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) deepgram → headers (apiKey / oauth)","status":"passed","title":"deepgram → headers (apiKey / oauth)","duration":0.055415999999979704,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) deepinfra → headers (apiKey / oauth)","status":"passed","title":"deepinfra → headers (apiKey / oauth)","duration":0.05375000000000796,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) deepseek → headers (apiKey / oauth)","status":"passed","title":"deepseek → headers (apiKey / oauth)","duration":0.05112500000001319,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) enally → headers (apiKey / oauth)","status":"passed","title":"enally → headers (apiKey / oauth)","duration":0.05591699999999378,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) fireworks → headers (apiKey / oauth)","status":"passed","title":"fireworks → headers (apiKey / oauth)","duration":0.051375000000007276,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) freetheai → headers (apiKey / oauth)","status":"passed","title":"freetheai → headers (apiKey / oauth)","duration":0.05058400000001484,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) gemini → headers (apiKey / oauth)","status":"passed","title":"gemini → headers (apiKey / oauth)","duration":0.09274999999999523,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) gitlab → headers (apiKey / oauth)","status":"passed","title":"gitlab → headers (apiKey / oauth)","duration":0.09000000000000341,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) glhf → headers (apiKey / oauth)","status":"passed","title":"glhf → headers (apiKey / oauth)","duration":0.06158299999998462,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) glm → headers (apiKey / oauth)","status":"passed","title":"glm → headers (apiKey / oauth)","duration":0.07345899999998551,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) glm-cn → headers (apiKey / oauth)","status":"passed","title":"glm-cn → headers (apiKey / oauth)","duration":0.055125000000003865,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) groq → headers (apiKey / oauth)","status":"passed","title":"groq → headers (apiKey / oauth)","duration":0.05412499999999909,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) hyperbolic → headers (apiKey / oauth)","status":"passed","title":"hyperbolic → headers (apiKey / oauth)","duration":0.05341699999999605,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) inference-net → headers (apiKey / oauth)","status":"passed","title":"inference-net → headers (apiKey / oauth)","duration":0.10287499999998317,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kilocode → headers (apiKey / oauth)","status":"passed","title":"kilocode → headers (apiKey / oauth)","duration":0.149249999999995,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kimi → headers (apiKey / oauth)","status":"passed","title":"kimi → headers (apiKey / oauth)","duration":0.21137500000000387,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kimi-coding → headers (apiKey / oauth)","status":"passed","title":"kimi-coding → headers (apiKey / oauth)","duration":0.2532500000000084,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) kluster → headers (apiKey / oauth)","status":"passed","title":"kluster → headers (apiKey / oauth)","duration":0.7527090000000101,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) lepton → headers (apiKey / oauth)","status":"passed","title":"lepton → headers (apiKey / oauth)","duration":0.31008400000001757,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) llm7 → headers (apiKey / oauth)","status":"passed","title":"llm7 → headers (apiKey / oauth)","duration":0.21358299999999986,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) longcat → headers (apiKey / oauth)","status":"passed","title":"longcat → headers (apiKey / oauth)","duration":0.16629100000000108,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) minimax → headers (apiKey / oauth)","status":"passed","title":"minimax → headers (apiKey / oauth)","duration":0.18062499999999204,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) minimax-cn → headers (apiKey / oauth)","status":"passed","title":"minimax-cn → headers (apiKey / oauth)","duration":0.3117499999999893,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) mistral → headers (apiKey / oauth)","status":"passed","title":"mistral → headers (apiKey / oauth)","duration":0.08525000000000205,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) mmf → headers (apiKey / oauth)","status":"passed","title":"mmf → headers (apiKey / oauth)","duration":0.07020800000000804,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) modal → headers (apiKey / oauth)","status":"passed","title":"modal → headers (apiKey / oauth)","duration":0.056874999999990905,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) morph → headers (apiKey / oauth)","status":"passed","title":"morph → headers (apiKey / oauth)","duration":0.06220899999999574,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nanobanana → headers (apiKey / oauth)","status":"passed","title":"nanobanana → headers (apiKey / oauth)","duration":0.05120900000000006,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nebius → headers (apiKey / oauth)","status":"passed","title":"nebius → headers (apiKey / oauth)","duration":0.051792000000006055,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nlpcloud → headers (apiKey / oauth)","status":"passed","title":"nlpcloud → headers (apiKey / oauth)","duration":0.07245800000001168,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nous-research → headers (apiKey / oauth)","status":"passed","title":"nous-research → headers (apiKey / oauth)","duration":0.05220899999997641,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) novita → headers (apiKey / oauth)","status":"passed","title":"novita → headers (apiKey / oauth)","duration":0.04958300000001259,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nscale → headers (apiKey / oauth)","status":"passed","title":"nscale → headers (apiKey / oauth)","duration":0.06037500000002183,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) nvidia → headers (apiKey / oauth)","status":"passed","title":"nvidia → headers (apiKey / oauth)","duration":0.3417079999999828,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) ollama → headers (apiKey / oauth)","status":"passed","title":"ollama → headers (apiKey / oauth)","duration":0.22091700000001424,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) openai → headers (apiKey / oauth)","status":"passed","title":"openai → headers (apiKey / oauth)","duration":0.18137500000000273,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) openrouter → headers (apiKey / oauth)","status":"passed","title":"openrouter → headers (apiKey / oauth)","duration":0.18883299999998826,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) perplexity → headers (apiKey / oauth)","status":"passed","title":"perplexity → headers (apiKey / oauth)","duration":0.147625000000005,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) predibase → headers (apiKey / oauth)","status":"passed","title":"predibase → headers (apiKey / oauth)","duration":0.0589170000000081,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) publicai → headers (apiKey / oauth)","status":"passed","title":"publicai → headers (apiKey / oauth)","duration":0.0625,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) puter → headers (apiKey / oauth)","status":"passed","title":"puter → headers (apiKey / oauth)","duration":0.05129200000001788,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) reka → headers (apiKey / oauth)","status":"passed","title":"reka → headers (apiKey / oauth)","duration":0.05262500000000614,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) sambanova → headers (apiKey / oauth)","status":"passed","title":"sambanova → headers (apiKey / oauth)","duration":0.11912499999999682,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) scaleway → headers (apiKey / oauth)","status":"passed","title":"scaleway → headers (apiKey / oauth)","duration":0.3404999999999916,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) siliconflow → headers (apiKey / oauth)","status":"passed","title":"siliconflow → headers (apiKey / oauth)","duration":0.1661670000000015,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) together → headers (apiKey / oauth)","status":"passed","title":"together → headers (apiKey / oauth)","duration":0.16275000000001683,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) uncloseai → headers (apiKey / oauth)","status":"passed","title":"uncloseai → headers (apiKey / oauth)","duration":0.15316699999999628,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) vercel-ai-gateway → headers (apiKey / oauth)","status":"passed","title":"vercel-ai-gateway → headers (apiKey / oauth)","duration":0.13716700000000515,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) volcengine-ark → headers (apiKey / oauth)","status":"passed","title":"volcengine-ark → headers (apiKey / oauth)","duration":0.1359160000000088,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) xai → headers (apiKey / oauth)","status":"passed","title":"xai → headers (apiKey / oauth)","duration":0.14520799999999667,"failureMessages":[],"meta":{},"tags":[]},{"ancestorTitles":["GOLDEN buildHeaders (default executor providers)"],"fullName":"GOLDEN buildHeaders (default executor providers) xiaomi-mimo → headers (apiKey / oauth)","status":"passed","title":"xiaomi-mimo → headers (apiKey / oauth)","duration":0.1335409999999797,"failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357420777,"endTime":1781357420806.1453,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/golden-url-header.test.js"},{"assertionResults":[{"ancestorTitles":["REAL provider smoke"],"fullName":"REAL provider smoke has active providers in DB","status":"skipped","title":"has active providers in DB","failureMessages":[],"meta":{},"tags":[]}],"startTime":1781357417485,"endTime":1781357417485,"status":"passed","message":"","name":"/Users/Working/router4/app/tests/translator/real/smoke-providers.real.test.js"}]} \ No newline at end of file diff --git a/tests/__baseline__/oauth-urls-baseline.json b/tests/__baseline__/oauth-urls-baseline.json index 23e40031..44faad70 100644 --- a/tests/__baseline__/oauth-urls-baseline.json +++ b/tests/__baseline__/oauth-urls-baseline.json @@ -40,5 +40,17 @@ "qwen": "https://chat.qwen.ai/api/v1/oauth2/device/code", "iflow": "https://iflow.cn/oauth", "kiro": "https://prod.us-east-1.auth.desktop.kiro.dev" + }, + "refreshUrls": { + "cline": "https://api.cline.bot/api/v1/auth/refresh", + "kimi-coding": "https://auth.kimi.com/api/oauth/token", + "xai": "https://auth.x.ai/oauth2/token" + }, + "clientIds": { + "claude": "9d1c250a-e61b-44d9-88ed-5944d1962f5e", + "codex": "app_EMoamEEZ73f0CkXaXp7hrann", + "qwen": "f0304373b74a44d2b584a3fb70ca9e56", + "iflow": "10009311001", + "kimi-coding": "17e5f671-d194-4dfb-9706-5516cb48c098" } } \ No newline at end of file diff --git a/tests/__baseline__/verify-oauth-urls.mjs b/tests/__baseline__/verify-oauth-urls.mjs index 737d8772..0c3cec76 100644 --- a/tests/__baseline__/verify-oauth-urls.mjs +++ b/tests/__baseline__/verify-oauth-urls.mjs @@ -27,6 +27,18 @@ const resolved = { iflow: PROVIDERS.iflow?.authUrl, kiro: PROVIDERS.kiro?.authUrl, }, + refreshUrls: { + cline: PROVIDERS.cline?.refreshUrl, + "kimi-coding": PROVIDERS["kimi-coding"]?.refreshUrl, + xai: PROVIDERS.xai?.refreshUrl, + }, + clientIds: { + claude: PROVIDERS.claude?.clientId, + codex: PROVIDERS.codex?.clientId, + qwen: PROVIDERS.qwen?.clientId, + iflow: PROVIDERS.iflow?.clientId, + "kimi-coding": PROVIDERS["kimi-coding"]?.clientId, + }, }; const current = JSON.parse(JSON.stringify(resolved));