test(video): cover terminal and plugin-context retention

This commit is contained in:
diegosouzapw
2026-08-26 21:24:41 -03:00
parent 2ac715aa9c
commit 6dab0df038
4 changed files with 101 additions and 1 deletions

View File

@@ -56,6 +56,17 @@ test("no headers arg → backward compatible (undefined in ctx)", async () => {
assert.equal(capturedCtx!.headers, undefined);
});
test("transcript sensitivity is propagated as server-owned plugin context", async () => {
let capturedCtx: Record<string, unknown> | undefined;
registerHook("onRequest", PLUGIN, async (ctx: Record<string, unknown>) => {
capturedCtx = ctx;
return {};
});
const gate = await runPluginOnRequestHook(baseArgs({ videoTranscriptSensitive: true }));
assert.equal(gate.blocked, false);
assert.equal(capturedCtx?.videoTranscriptSensitive, true);
});
test("a blocking hook → blocked:true with a 403 JSON Response", async () => {
registerHook("onRequest", PLUGIN, async () => ({
blocked: true,

View File

@@ -6,7 +6,9 @@
import { test, after } from "node:test";
import assert from "node:assert/strict";
const { registerHook, unregisterHook } = await import("../../src/lib/plugins/hooks.ts");const { runPluginOnResponseHook, runPluginOnStreamCompleteHook } = await import("../../open-sse/handlers/chatCore/pluginOnResponse.ts");
const { registerHook, unregisterHook } = await import("../../src/lib/plugins/hooks.ts");
const { runPluginOnResponseHook, runPluginOnStreamCompleteHook } =
await import("../../open-sse/handlers/chatCore/pluginOnResponse.ts");
async function waitFor(pred: () => boolean, timeoutMs = 2000): Promise<void> {
const deadline = Date.now() + timeoutMs;
@@ -126,6 +128,27 @@ test("no headers arg → backward compatible (undefined in ctx)", async () => {
assert.equal(captured!.headers, undefined);
});
test("transcript sensitivity is propagated as server-owned plugin context", async () => {
let captured: Record<string, unknown> | undefined;
registerHook("onResponse", "test-onresponse-plugin", async (ctx: Record<string, unknown>) => {
captured = ctx;
return {};
});
await runPluginOnResponseHook({
requestId: "req-transcript-sensitive",
body: { messages: [{ role: "user", content: "processed video request" }] },
model: "gpt-4o",
provider: "openai",
apiKeyInfo: null,
response: { status: 200, data: { ok: true } },
videoTranscriptSensitive: true,
});
await waitFor(() => captured !== undefined);
assert.equal(captured?.videoTranscriptSensitive, true);
});
test("a throwing hook never rejects the caller (fail-open)", async () => {
registerHook("onResponse", "test-onresponse-plugin", async () => {
throw new Error("boom");

View File

@@ -264,3 +264,39 @@ test("transcript-sensitive round-robin masked-200 failures omit quality echoes f
assert.equal(retainedLogs.includes(transcriptSentinel), false);
assert.match(retainedLogs, /omitted: video transcript/);
});
test("transcript-sensitive terminal logs omit the echo while the functional client error stays intact", async () => {
const transcriptSentinel = "PRIVATE_COMBO_TERMINAL_TRANSCRIPT_SENTINEL";
const localWarnCalls: WarnCall[] = [];
const result = await handleComboChat({
body: { model: "test", messages: [{ role: "user", content: "processed video request" }] },
combo: {
name: "test-combo-10597-private-terminal",
strategy: "priority",
models: [{ model: "claude/private-video-terminal" }],
config: { maxRetries: 0 },
},
handleSingleModel: async () =>
new Response(JSON.stringify({ error: { message: transcriptSentinel } }), {
status: 500,
headers: { "Content-Type": "application/json" },
}),
log: {
info: () => {},
debug: () => {},
error: () => {},
warn: (tag: string, msg: string, meta?: unknown) => {
localWarnCalls.push({ tag, msg, meta });
},
},
settings: {},
allCombos: [],
videoTranscriptSensitive: true,
});
assert.equal(result.ok, false);
assert.match(await result.text(), new RegExp(transcriptSentinel));
const retainedLogs = JSON.stringify(localWarnCalls);
assert.equal(retainedLogs.includes(transcriptSentinel), false);
assert.match(retainedLogs, /omitted: video transcript/);
});

View File

@@ -223,6 +223,36 @@ test("tryFusionDispatch: owns the request and synthesizes for the fusion strateg
assert.ok(dispatched.includes("p/panelA") && dispatched.includes("p/panelB"));
});
test("tryFusionDispatch: propagates transcript sensitivity into native fusion logs", async () => {
const transcriptSentinel = "PRIVATE_FUSION_PRELUDE_TRANSCRIPT_SENTINEL";
const ctx = setup({
name: "private-fusion",
strategy: "fusion",
models: [{ model: "p/failing" }, { model: "p/healthy" }],
config: { minPanel: 1 },
});
const res = await tryFusionDispatch({
body: ctx.body,
combo: ctx.combo,
cfg: ctx.config as unknown as Record<string, unknown>,
config: ctx.config,
strategy: "fusion",
allCombos: [],
handleSingleModel: async () => okResponse("unused"),
handleSingleModelWithTimeout: async (_body, modelStr) => {
if (modelStr === "p/failing") throw new Error(transcriptSentinel);
return okResponse("safe answer");
},
log: ctx.log,
runCombo: async () => okResponse("recursed"),
videoTranscriptSensitive: true,
});
assert.ok(res);
const retainedLogs = JSON.stringify(ctx.records);
assert.equal(retainedLogs.includes(transcriptSentinel), false);
assert.match(retainedLogs, /omitted: video transcript/);
});
test("tryRuntimeUnitDispatch: falls through when the combo has no executable combo-ref", async () => {
const ctx = setup({
name: "flat",