mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 12:52:11 +03:00
fix(cpa): isolate credential-pool failures (#8308)
* fix(cpa): isolate credential pool failures Co-Authored-By: Claude <noreply@anthropic.com> * fix(cpa): forward transport through the chatCore key-health wrapper The local recordKeyHealthStatus wrapper in handleChatCore only declared (status, creds), so the transport argument added for CPA credential-pool isolation was silently dropped at the call site (TS2554 "Expected 2 arguments, but got 3" once chatCore.ts is typechecked with tsc directly — this file is not in tsconfig.typecheck-core.json's file list, so `npm run typecheck:core` did not surface it). The CPA isolation guard in keyHealth.ts never received `transport`, so it never fired. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -428,7 +428,7 @@ export class CliproxyapiExecutor extends BaseExecutor {
|
||||
input.log?.warn?.("CPA", `CLIProxyAPI rate limited: ${response.status}`);
|
||||
}
|
||||
|
||||
return { response, url, headers, transformedBody };
|
||||
return { response, url, headers, transformedBody, transport: "cliproxyapi" as const };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -549,8 +549,9 @@ export async function handleChatCore({
|
||||
// and delegate so the existing call sites stay byte-identical.
|
||||
const recordKeyHealthStatus = (
|
||||
status: number,
|
||||
creds: Record<string, unknown> | null | undefined
|
||||
): void => recordKeyHealthStatusFor(status, creds, log);
|
||||
creds: Record<string, unknown> | null | undefined,
|
||||
transport?: string
|
||||
): void => recordKeyHealthStatusFor(status, creds, log, transport);
|
||||
|
||||
const persistCodexQuotaState = async (headers: Record<string, string> | null, status = 0) => {
|
||||
const currentConnectionId = getCurrentConnectionId();
|
||||
@@ -2988,7 +2989,11 @@ export async function handleChatCore({
|
||||
rawResult._executionCredentials?.connectionId &&
|
||||
rawResult._executionCredentials?.apiKey
|
||||
) {
|
||||
recordKeyHealthStatus(status, rawResult._executionCredentials);
|
||||
recordKeyHealthStatus(
|
||||
status,
|
||||
rawResult._executionCredentials,
|
||||
rawResult.transport
|
||||
);
|
||||
}
|
||||
releaseRawResultAccountSemaphore =
|
||||
typeof rawResult._accountSemaphoreRelease === "function"
|
||||
|
||||
@@ -31,8 +31,13 @@ type KeyHealthLog = {
|
||||
export function recordKeyHealthStatus(
|
||||
status: number,
|
||||
creds: Record<string, unknown> | null | undefined,
|
||||
log?: KeyHealthLog
|
||||
log?: KeyHealthLog,
|
||||
transport?: string
|
||||
): void {
|
||||
// CLIProxyAPI owns a shared external credential pool. Its auth failures cannot be
|
||||
// attributed to the native OmniRoute connection selected before proxy dispatch.
|
||||
if (transport === "cliproxyapi") return;
|
||||
|
||||
const connId = creds?.connectionId as string | undefined;
|
||||
if (!connId) return;
|
||||
|
||||
|
||||
@@ -106,8 +106,15 @@ export function normalizeExecutorResult(
|
||||
url?: string;
|
||||
headers?: Record<string, string>;
|
||||
transformedBody?: unknown;
|
||||
transport?: string;
|
||||
}
|
||||
): { response: Response; url: string; headers: Record<string, string>; transformedBody: unknown } {
|
||||
): {
|
||||
response: Response;
|
||||
url: string;
|
||||
headers: Record<string, string>;
|
||||
transformedBody: unknown;
|
||||
transport?: string;
|
||||
} {
|
||||
if (result instanceof Response) {
|
||||
return { response: result, url: "", headers: {}, transformedBody: null };
|
||||
}
|
||||
@@ -116,6 +123,7 @@ export function normalizeExecutorResult(
|
||||
url: result.url || "",
|
||||
headers: result.headers || {},
|
||||
transformedBody: result.transformedBody ?? null,
|
||||
transport: result.transport,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -68,3 +68,9 @@ test("non-401 / non-2xx status does not touch key health", () => {
|
||||
recordKeyHealthStatus(500, creds(conn), noopLog);
|
||||
assert.equal(getAllKeyHealth()[`${conn}:primary`], undefined);
|
||||
});
|
||||
|
||||
test("CPA pool failures do not poison the selected native connection key", () => {
|
||||
const conn = "kh-cpa-pool-isolation";
|
||||
recordKeyHealthStatus(401, creds(conn), noopLog, "cliproxyapi");
|
||||
assert.equal(getAllKeyHealth()[`${conn}:primary`], undefined);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user