Files
OmniRoute/open-sse/executors/default/zaiFormatOverride.ts
Diego Rodrigues de Sa e Souza 265d00c0e1 fix(sse): honor per-model targetFormat override for zai/glm-coding-apikey (#7364) (#7584)
DefaultExecutor.buildUrl()'s "zai"/"glm-coding-apikey" case always returned
the Anthropic Messages URL, ignoring a per-model targetFormat override
(custom-model dropdown, #2905) that resolves to "openai" — e.g. for a vision
model like glm-4.6v. chatCore/executionCredentials.ts now threads the
resolved override onto providerSpecificData.targetFormat so buildUrl (via
the new default/zaiFormatOverride.ts helper, extracted to respect the
file-size ratchet) can route to the OpenAI-compatible endpoint instead.

Separately, custom-model id lookup (lookupCustomModelMeta in
src/sse/services/model.ts, getCustomModelRow in src/lib/db/models.ts) did an
exact, case-sensitive match, so a model saved as "glm-4.6v" was invisible
when looked up as "glm-4.6V". Both now fall back to a case-insensitive match
after the exact match fails.

Regression tests: tests/unit/zai-glm-target-format-override.test.ts (reused
from the triage plan-file's RED probe) and
tests/unit/zai-execution-credentials-target-format-7364.test.ts (production
wiring in executionCredentials.ts).

Gates run: check-file-size, check-complexity, check-cognitive-complexity,
typecheck:core, eslint (suppressions), tests/unit/zai-glm-target-format-override.test.ts,
tests/unit/zai-execution-credentials-target-format-7364.test.ts,
tests/unit/executor-default-base.test.ts, tests/unit/custom-model-target-format.test.ts,
tests/unit/chatcore-execution-credentials.test.ts, tests/unit/chatcore-target-format.test.ts,
tests/unit/model-resolver.test.ts, tests/unit/model-alias-provider-resolution.test.ts,
tests/unit/combo-custom-provider-resolution.test.ts — all green.

Refs #7364
2026-07-17 06:46:50 -03:00

26 lines
1.1 KiB
TypeScript

import { GLM_DEFAULT_BASE_URLS } from "../../config/glmProvider.ts";
type ZaiCredentialsLike = {
providerSpecificData?: { targetFormat?: unknown } | null;
} | null;
/**
* #7364: "zai"/"glm-coding-apikey" default to the Anthropic Messages wire format
* (registry format:"claude"), but a per-model `targetFormat` override (custom-model
* dropdown, #2905) can resolve to "openai" — e.g. for a vision model like glm-4.6v
* that the operator wants routed through the OpenAI-compatible endpoint instead.
* chatCore/executionCredentials.ts threads that resolved override onto
* `providerSpecificData.targetFormat`; DefaultExecutor.buildUrl() has no other way
* to see it, so without this check every zai/glm-coding-apikey request silently hit
* the Claude-format endpoint regardless of the override.
*/
export function resolveZaiUrl(
credentials: ZaiCredentialsLike,
resolveBaseUrl: (fallback?: string) => string
): string {
if (credentials?.providerSpecificData?.targetFormat === "openai") {
return resolveBaseUrl(GLM_DEFAULT_BASE_URLS.international);
}
return `${resolveBaseUrl()}?beta=true`;
}