Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions open-sse/handlers/chatCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { checkSemanticCache } from "./chatCore/semanticCache.ts";
import { applyClientUsageBuffer } from "./chatCore/clientUsageBuffer.ts";
import { buildPostCallGuardrailContext } from "./chatCore/postCallGuardrailContext.ts";
import { storeSemanticCacheResponse } from "./chatCore/semanticCacheStore.ts";
import { buildNonStreamingResponseHeaders } from "./chatCore/nonStreamingResponseHeaders.ts";
import { sanitizeChatRequestBody } from "./chatCore/sanitization.ts";
import {
getHeaderValueCaseInsensitive,
Expand Down Expand Up @@ -161,7 +162,6 @@ import { saveRequestUsage, trackPendingRequest, appendRequestLog } from "@/lib/u
import { finalizePendingScope, updatePendingScope } from "@/lib/usage/pendingRequestScope";
import { recordCost } from "@/domain/costRules";
import { calculateCost } from "@/lib/usage/costCalculator";
import { attachOmniRouteMetaHeaders } from "@/domain/omnirouteResponseMeta";
import {
buildClaudePassthroughToolNameMap,
restoreClaudePassthroughToolNames,
Expand Down Expand Up @@ -3619,22 +3619,15 @@ export async function handleChatCore({
providerResponse: responseBody,
clientResponse: translatedResponse,
});
const responseHeaders: Record<string, string> = {
"Content-Type": "application/json",
[OMNIROUTE_RESPONSE_HEADERS.cache]: "MISS",
};
attachOmniRouteMetaHeaders(responseHeaders, {
const responseHeaders = buildNonStreamingResponseHeaders({
provider,
model,
cacheHit: false,
latencyMs: Date.now() - startTime,
usage: responseUsage,
costUsd: estimatedCost,
startTime,
responseUsage,
estimatedCost,
requestId: skillRequestId,
compressionResponseMeta,
});
if (compressionResponseMeta) {
responseHeaders[OMNIROUTE_RESPONSE_HEADERS.compression] = compressionResponseMeta;
}
// #1311: echo the requested alias/combo name in the non-streaming response model.
if (echoModel) echoModelInObject(translatedResponse, echoModel);
return {
Expand Down
46 changes: 46 additions & 0 deletions open-sse/handlers/chatCore/nonStreamingResponseHeaders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* chatCore non-streaming success response headers (Quality Gate v2 / Fase 9 — chatCore god-file
* decomposition, #3501).
*
* Extracted from handleChatCore's non-streaming success path: build the response header map for a
* cache-MISS JSON response — the static Content-Type + cache marker, the OmniRoute meta headers
* (provider/model/latency/usage/cost/request-id), and the optional compression header. Pure builder
* (returns a fresh map; only mutates the map it owns). Behaviour is byte-identical to the previous
* inline block, including `latencyMs: now - startTime`.
*/
import { OMNIROUTE_RESPONSE_HEADERS } from "@/shared/constants/headers";
import { attachOmniRouteMetaHeaders as defaultAttachMeta } from "@/domain/omnirouteResponseMeta";

export function buildNonStreamingResponseHeaders(
args: {
provider: string | null | undefined;
model: string | null | undefined;
startTime: number;
responseUsage: unknown;
estimatedCost: number;
requestId: unknown;
compressionResponseMeta?: string | null | undefined;
},
deps: { attachOmniRouteMetaHeaders: typeof defaultAttachMeta; now: () => number } = {
attachOmniRouteMetaHeaders: defaultAttachMeta,
now: Date.now,
}
): Record<string, string> {
const responseHeaders: Record<string, string> = {
"Content-Type": "application/json",
[OMNIROUTE_RESPONSE_HEADERS.cache]: "MISS",
};
deps.attachOmniRouteMetaHeaders(responseHeaders, {
provider: args.provider,
model: args.model,
cacheHit: false,
latencyMs: deps.now() - args.startTime,
usage: args.responseUsage,
costUsd: args.estimatedCost,
requestId: args.requestId,
});
if (args.compressionResponseMeta) {
responseHeaders[OMNIROUTE_RESPONSE_HEADERS.compression] = args.compressionResponseMeta;
}
return responseHeaders;
}
73 changes: 73 additions & 0 deletions tests/unit/chatcore-nonstreaming-response-headers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Characterization of buildNonStreamingResponseHeaders — the cache-MISS response header builder
// extracted from handleChatCore's non-streaming success path (chatCore god-file decomposition,
// #3501). attachOmniRouteMetaHeaders + now are injected so the static headers, the meta payload,
// and the optional compression header are observable. Locks: Content-Type + cache MISS, latencyMs =
// now - startTime, and the compression header only when meta is present.
import { test } from "node:test";
import assert from "node:assert/strict";

const { buildNonStreamingResponseHeaders } = await import(
"../../open-sse/handlers/chatCore/nonStreamingResponseHeaders.ts"
);

function makeDeps(now = 1000) {
const metaCalls: Array<{ headers: Record<string, string>; meta: Record<string, unknown> }> = [];
const deps = {
attachOmniRouteMetaHeaders: (headers: Record<string, string>, meta: Record<string, unknown>) => {
metaCalls.push({ headers, meta });
headers["x-omniroute-meta"] = "attached";
},
now: () => now,
} as Parameters<typeof buildNonStreamingResponseHeaders>[1];
return { deps, metaCalls };
}

function baseArgs(overrides: Record<string, unknown> = {}) {
return {
provider: "openai",
model: "gpt-x",
startTime: 600,
responseUsage: { prompt_tokens: 5 },
estimatedCost: 0.0012,
requestId: "req-1",
compressionResponseMeta: undefined,
...overrides,
} as Parameters<typeof buildNonStreamingResponseHeaders>[0];
}

test("static headers: Content-Type json + cache MISS", () => {
const { deps } = makeDeps();
const h = buildNonStreamingResponseHeaders(baseArgs(), deps);
assert.equal(h["Content-Type"], "application/json");
// cache marker key/value
assert.ok(Object.values(h).includes("MISS"));
});

test("meta receives provider/model/cacheHit false/latency/usage/cost/requestId", () => {
const { deps, metaCalls } = makeDeps(1000);
buildNonStreamingResponseHeaders(baseArgs({ startTime: 600 }), deps);
assert.equal(metaCalls.length, 1);
const meta = metaCalls[0].meta;
assert.equal(meta.provider, "openai");
assert.equal(meta.model, "gpt-x");
assert.equal(meta.cacheHit, false);
assert.equal(meta.latencyMs, 400); // now 1000 - startTime 600
assert.deepEqual(meta.usage, { prompt_tokens: 5 });
assert.equal(meta.costUsd, 0.0012);
assert.equal(meta.requestId, "req-1");
});

test("no compression meta → no compression header", () => {
const { deps } = makeDeps();
const h = buildNonStreamingResponseHeaders(baseArgs({ compressionResponseMeta: undefined }), deps);
assert.ok(!Object.values(h).includes("engine:x"));
});

test("compression meta present → compression header set to that value", () => {
const { deps } = makeDeps();
const h = buildNonStreamingResponseHeaders(
baseArgs({ compressionResponseMeta: "engine:x; source=header" }),
deps
);
assert.ok(Object.values(h).includes("engine:x; source=header"));
});
Loading