From 76832bcde9d241f901321a87430f4d3a0412e605 Mon Sep 17 00:00:00 2001 From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Date: Wed, 4 Nov 2026 13:00:57 -0300 Subject: [PATCH 1/2] fix(compression): analytics reports lite again when lite runs as a scoped stacked step --- ...0000-compression-analytics-reports-lite.md | 1 + open-sse/handlers/chatCore.ts | 4 ++++ .../chatCore/compressionAnalyticsWrite.ts | 12 ++++++---- .../services/compression/deriveDefaultPlan.ts | 3 +++ .../compression/lossyRequestPolicy.ts | 7 +++++- ...atcore-compression-analytics-write.test.ts | 23 +++++++++++++++++++ .../compression/lossy-request-policy.test.ts | 11 +++++++++ 7 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 changelog.d/fixes/0000-compression-analytics-reports-lite.md diff --git a/changelog.d/fixes/0000-compression-analytics-reports-lite.md b/changelog.d/fixes/0000-compression-analytics-reports-lite.md new file mode 100644 index 000000000000..67727c8957f7 --- /dev/null +++ b/changelog.d/fixes/0000-compression-analytics-reports-lite.md @@ -0,0 +1 @@ +- **fix(compression): analytics reports lite again when lite runs as a scoped stacked step**: since #18818 the lossy-request policy runs a configured `lite` as a one-step stacked pipeline. Compression analytics then recorded `stacked` as both mode and engine, so the dashboard's mode and engine breakdowns no longer showed lite. The plan now carries `reportedMode: "lite"`, and the analytics row records that; dispatch is unchanged. diff --git a/open-sse/handlers/chatCore.ts b/open-sse/handlers/chatCore.ts index acbb39f937be..06c3c059cb7e 100644 --- a/open-sse/handlers/chatCore.ts +++ b/open-sse/handlers/chatCore.ts @@ -1590,6 +1590,8 @@ async function handleChatCoreInner({ } ); const mode = compressionPlan.mode as CompressionConfig["defaultMode"]; + // Configured mode for analytics when a policy wrapped it (lite as a one-step stacked plan). + const reportedMode = mode === "stacked" ? compressionPlan.reportedMode : undefined; if (adaptiveTelemetry && adaptiveTelemetry.fit === false) { log?.warn?.( "COMPRESSION", @@ -1736,6 +1738,7 @@ async function handleChatCoreInner({ effectiveServiceTier, comboName, mode, + reportedMode, compressionComboId: config.compressionComboId, skillRequestId, cavemanOutputModeApplied, @@ -1757,6 +1760,7 @@ async function handleChatCoreInner({ effectiveServiceTier, comboName, mode, + reportedMode, compressionComboId: config.compressionComboId, skillRequestId, cavemanOutputModeApplied, diff --git a/open-sse/handlers/chatCore/compressionAnalyticsWrite.ts b/open-sse/handlers/chatCore/compressionAnalyticsWrite.ts index c3b0882e0376..042efc282a51 100644 --- a/open-sse/handlers/chatCore/compressionAnalyticsWrite.ts +++ b/open-sse/handlers/chatCore/compressionAnalyticsWrite.ts @@ -27,6 +27,10 @@ type WriteOpts = { effectiveServiceTier: string | undefined; comboName: string | null | undefined; mode: string; + /** The mode the user configured, when the dispatched plan wraps it (lite run as a one-step + * stacked pipeline by the lossy-request policy). Recorded as mode and engine so analytics + * keeps reporting what was configured, not the wrapper. */ + reportedMode?: string; compressionComboId: string | null | undefined; skillRequestId: string; cavemanOutputModeApplied: boolean; @@ -66,8 +70,8 @@ function buildAnalyticsRow( timestamp: new Date().toISOString(), combo_id: opts.comboName ?? null, provider: opts.provider ?? null, - mode: opts.mode, - engine: stats.engine ?? opts.mode, + mode: opts.reportedMode ?? opts.mode, + engine: opts.reportedMode ?? stats.engine ?? opts.mode, compression_combo_id: stats.compressionComboId ?? opts.compressionComboId ?? null, original_tokens: stats.originalTokens, compressed_tokens: stats.compressedTokens, @@ -110,8 +114,8 @@ export function writeCompressionSkip(opts: WriteOpts, skipReason: string): Promi timestamp: new Date().toISOString(), combo_id: opts.comboName ?? null, provider: opts.provider ?? null, - mode: opts.mode, - engine: stats.engine ?? opts.mode, + mode: opts.reportedMode ?? opts.mode, + engine: opts.reportedMode ?? stats.engine ?? opts.mode, compression_combo_id: stats.compressionComboId ?? opts.compressionComboId ?? null, original_tokens: stats.originalTokens, compressed_tokens: stats.compressedTokens, diff --git a/open-sse/services/compression/deriveDefaultPlan.ts b/open-sse/services/compression/deriveDefaultPlan.ts index bc8ac690e933..46735c9b041e 100644 --- a/open-sse/services/compression/deriveDefaultPlan.ts +++ b/open-sse/services/compression/deriveDefaultPlan.ts @@ -21,6 +21,9 @@ export interface DerivedPlan { /** Which precedence layer decided this plan (Phase 3 observability). Optional so * Phase 1/2 callers and snapshots are unaffected. */ source?: CompressionSource; + /** Set when a policy wraps a configured single mode in another dispatch shape (lite run as + * a one-step stacked pipeline), so analytics still reports the configured mode. */ + reportedMode?: string; } /** diff --git a/open-sse/services/compression/lossyRequestPolicy.ts b/open-sse/services/compression/lossyRequestPolicy.ts index e3dc010ce976..c521166c2099 100644 --- a/open-sse/services/compression/lossyRequestPolicy.ts +++ b/open-sse/services/compression/lossyRequestPolicy.ts @@ -93,7 +93,12 @@ export function downgradeUnrequestedLossy( // A scoped step overrides global Lite settings without changing the stored config. if (plan.mode === "lite") { - return { ...plan, mode: "stacked", stackedPipeline: [LOSSLESS_LITE_STEP] }; + return { + ...plan, + mode: "stacked", + stackedPipeline: [LOSSLESS_LITE_STEP], + reportedMode: "lite", + }; } if (LOSSY_SINGLE_MODES.has(plan.mode)) { diff --git a/tests/unit/chatcore-compression-analytics-write.test.ts b/tests/unit/chatcore-compression-analytics-write.test.ts index d8645451b3f3..69602ba15ce2 100644 --- a/tests/unit/chatcore-compression-analytics-write.test.ts +++ b/tests/unit/chatcore-compression-analytics-write.test.ts @@ -102,6 +102,29 @@ test("writes the analytics row with mapped tokens/engine and resolves", async () assert.equal(row!.vf, 0); }); +test("a wrapped plan records the configured mode as mode and engine", async () => { + // Lite dispatched as a one-step stacked pipeline (lossy-request policy) must still show up as + // lite in analytics, not as the stacked wrapper. + await writeCompressionAnalytics({ + ...baseOpts("ca-req-reported", { engine: "stacked" }), + mode: "stacked", + reportedMode: "lite", + }); + const row = analyticsRow("ca-req-reported"); + assert.equal(row!.mode, "lite"); + assert.equal(row!.engine, "lite"); +}); + +test("without reportedMode the dispatched mode and engine are recorded as before", async () => { + await writeCompressionAnalytics({ + ...baseOpts("ca-req-stacked", { engine: "stacked" }), + mode: "stacked", + }); + const row = analyticsRow("ca-req-stacked"); + assert.equal(row!.mode, "stacked"); + assert.equal(row!.engine, "stacked"); +}); + test("validation_fallback is 1 when the stats flagged a fallback", async () => { await writeCompressionAnalytics(baseOpts("ca-req-2", { fallbackApplied: true })); const row = analyticsRow("ca-req-2"); diff --git a/tests/unit/compression/lossy-request-policy.test.ts b/tests/unit/compression/lossy-request-policy.test.ts index a9349e7fe977..64838b470cdd 100644 --- a/tests/unit/compression/lossy-request-policy.test.ts +++ b/tests/unit/compression/lossy-request-policy.test.ts @@ -89,10 +89,21 @@ test("lite mode is scoped to a tool-preserving Lite step on the default path", ( ...lite, mode: "stacked", stackedPipeline: [LOSSLESS_LITE], + // Analytics keeps reporting the configured mode, not the stacked wrapper. + reportedMode: "lite", }); assert.equal(applyLossyRequestPolicy(lite, "allow-lossy"), lite); }); +test("only the lite wrapper carries a reportedMode", () => { + const stacked: DerivedPlan = { + mode: "stacked", + source: "default", + stackedPipeline: [{ engine: "session-dedup" }], + }; + assert.equal("reportedMode" in applyLossyRequestPolicy(stacked, null), false); +}); + test("allow-lossy keeps lite tool-result truncation as configured", () => { const safe: DerivedPlan = { mode: "stacked", From 7430dfab79900723f042556b32258cca81bcbc9b Mon Sep 17 00:00:00 2001 From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Date: Wed, 4 Nov 2026 13:03:16 -0300 Subject: [PATCH 2/2] docs(changelog): number the compression analytics fragment after the PR --- ...eports-lite.md => 19012-compression-analytics-reports-lite.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/fixes/{0000-compression-analytics-reports-lite.md => 19012-compression-analytics-reports-lite.md} (100%) diff --git a/changelog.d/fixes/0000-compression-analytics-reports-lite.md b/changelog.d/fixes/19012-compression-analytics-reports-lite.md similarity index 100% rename from changelog.d/fixes/0000-compression-analytics-reports-lite.md rename to changelog.d/fixes/19012-compression-analytics-reports-lite.md