mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-18 21:02:50 +03:00
fix(video): redact executor diagnostics
This commit is contained in:
@@ -202,6 +202,10 @@ export type ExecuteInput = {
|
||||
* this to apply client-format-aware policies such as `</think>` close-marker
|
||||
* suppression. */
|
||||
clientResponseFormat?: string | null;
|
||||
/** True when upstream diagnostics may echo a video transcript. Executors must
|
||||
* preserve operational responses/errors while omitting those echoes from
|
||||
* retained logs. */
|
||||
videoTranscriptSensitive?: boolean;
|
||||
/** Callback to persist tokens that are proactively refreshed during execution.
|
||||
* Accepts a partial credentials patch (e.g. `{ accessToken, refreshToken }` or
|
||||
* `{ testStatus: "expired", isActive: false }`); the caller merges into the
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { redactVideoTranscriptSensitiveText } from "../../src/lib/guardrails/videoTranscriptLogRedaction.ts";
|
||||
import type { KeyHealth } from "../services/apiKeyRotator.ts";
|
||||
|
||||
import { DefaultExecutor } from "./default.ts";
|
||||
@@ -45,6 +46,11 @@ function asRecord(value: unknown): JsonRecord | null {
|
||||
return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : null;
|
||||
}
|
||||
|
||||
function retainGlmDiagnostic(error: unknown, input: ExecuteInput): string {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
return redactVideoTranscriptSensitiveText(message, input.videoTranscriptSensitive === true);
|
||||
}
|
||||
|
||||
function getEffectiveKey(credentials: ProviderCredentials): string {
|
||||
const extraKeys = (credentials.providerSpecificData?.extraApiKeys as string[] | undefined) ?? [];
|
||||
if (credentials.apiKey && credentials.connectionId && extraKeys.length > 0) {
|
||||
@@ -465,6 +471,7 @@ export class GlmExecutor extends DefaultExecutor {
|
||||
timeoutMs: STREAM_READINESS_TIMEOUT_MS,
|
||||
provider: this.provider,
|
||||
model: input.model,
|
||||
redactUpstreamDiagnosticForLog: input.videoTranscriptSensitive === true,
|
||||
log: input.log,
|
||||
});
|
||||
response = readiness.response;
|
||||
@@ -559,7 +566,7 @@ export class GlmExecutor extends DefaultExecutor {
|
||||
if (!isRetryableGlmFallbackError(error)) throw error;
|
||||
input.log?.debug?.(
|
||||
"GLM_FALLBACK",
|
||||
`${primaryTransport} error (${error instanceof Error ? error.message : String(error)}); trying ${fallbackTransport}`
|
||||
`${primaryTransport} error (${retainGlmDiagnostic(error, input)}); trying ${fallbackTransport}`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -572,7 +579,7 @@ export class GlmExecutor extends DefaultExecutor {
|
||||
if (!primaryResult) throw error;
|
||||
input.log?.debug?.(
|
||||
"GLM_FALLBACK",
|
||||
`${fallbackTransport} fallback failed (${error instanceof Error ? error.message : String(error)}); returning primary response`
|
||||
`${fallbackTransport} fallback failed (${retainGlmDiagnostic(error, input)}); returning primary response`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3173,6 +3173,7 @@ export async function handleChatCore({
|
||||
userAgent
|
||||
),
|
||||
clientResponseFormat,
|
||||
videoTranscriptSensitive,
|
||||
onCredentialsRefreshed,
|
||||
skipUpstreamRetry,
|
||||
contextEditing: { enabled: contextEditingEnabled },
|
||||
@@ -3489,6 +3490,7 @@ export async function handleChatCore({
|
||||
userAgent
|
||||
),
|
||||
clientResponseFormat,
|
||||
videoTranscriptSensitive,
|
||||
onCredentialsRefreshed,
|
||||
skipUpstreamRetry,
|
||||
contextEditing: { enabled: contextEditingEnabled },
|
||||
@@ -4036,6 +4038,7 @@ export async function handleChatCore({
|
||||
upstreamExtraHeaders: buildUpstreamHeadersForExecute(retryModelId),
|
||||
clientHeaders: buildExecutorClientHeaders(clientRawRequest?.headers, userAgent),
|
||||
clientResponseFormat,
|
||||
videoTranscriptSensitive,
|
||||
onCredentialsRefreshed,
|
||||
skipUpstreamRetry: isCombo,
|
||||
contextEditing: { enabled: contextEditingEnabled },
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
*/
|
||||
|
||||
import { getExecutor } from "../../executors/index.ts";
|
||||
import type { ExecuteInput } from "../../executors/base.ts";
|
||||
import { isCliproxyapiDeepModeEnabled } from "../../executors/cliproxyapi.ts";
|
||||
import { isDarioDeepModeEnabled } from "../../executors/dario.ts";
|
||||
import { redactVideoTranscriptSensitiveText } from "../../../src/lib/guardrails/videoTranscriptLogRedaction.ts";
|
||||
import { getCachedSettings } from "@/lib/db/readCache";
|
||||
import { getUpstreamProxyConfigCached } from "./comboContextCache.ts";
|
||||
import type { FallbackBackend } from "@/lib/db/upstreamProxy";
|
||||
@@ -48,6 +50,11 @@ function parseFallbackCodes(raw: unknown): number[] | null {
|
||||
return parsed.length > 0 ? parsed : null;
|
||||
}
|
||||
|
||||
function retainExecutorDiagnostic(error: unknown, input: ExecuteInput): string {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
return redactVideoTranscriptSensitiveText(message, input.videoTranscriptSensitive === true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the CLIProxyAPI-related settings shared by both the direct
|
||||
* `mode: "cliproxyapi"` passthrough leg and the `mode: "fallback"` retry leg:
|
||||
@@ -155,25 +162,20 @@ export async function resolveExecutorWithProxy(
|
||||
const isRetryableStatus = (s: number) => fallbackCodes.includes(s) || s === 0;
|
||||
|
||||
const wrapper = Object.create(nativeExec);
|
||||
wrapper.execute = async (input: {
|
||||
model: string;
|
||||
body: unknown;
|
||||
stream: boolean;
|
||||
credentials: unknown;
|
||||
signal?: AbortSignal | null;
|
||||
log?: unknown;
|
||||
upstreamExtraHeaders?: Record<string, string> | null;
|
||||
}) => {
|
||||
wrapper.execute = async (input: ExecuteInput) => {
|
||||
let result;
|
||||
try {
|
||||
result = await nativeExec.execute(input);
|
||||
} catch (err) {
|
||||
const errMsg = err instanceof Error ? err.message : String(err);
|
||||
log?.info?.("UPSTREAM_PROXY", `${prov} native error (${errMsg}), retrying via ${backendLabel}`);
|
||||
const errMsg = retainExecutorDiagnostic(err, input);
|
||||
log?.info?.(
|
||||
"UPSTREAM_PROXY",
|
||||
`${prov} native error (${errMsg}), retrying via ${backendLabel}`
|
||||
);
|
||||
try {
|
||||
return await proxyExec.execute(input);
|
||||
} catch (proxyErr) {
|
||||
const proxyMsg = proxyErr instanceof Error ? proxyErr.message : String(proxyErr);
|
||||
const proxyMsg = retainExecutorDiagnostic(proxyErr, input);
|
||||
log?.error?.("UPSTREAM_PROXY", `${prov} ${backendLabel} fallback also failed: ${proxyMsg}`);
|
||||
throw proxyErr;
|
||||
}
|
||||
@@ -189,7 +191,7 @@ export async function resolveExecutorWithProxy(
|
||||
try {
|
||||
return await proxyExec.execute(input);
|
||||
} catch (proxyErr) {
|
||||
const proxyMsg = proxyErr instanceof Error ? proxyErr.message : String(proxyErr);
|
||||
const proxyMsg = retainExecutorDiagnostic(proxyErr, input);
|
||||
log?.error?.("UPSTREAM_PROXY", `${prov} ${backendLabel} fallback also failed: ${proxyMsg}`);
|
||||
throw proxyErr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user