diff --git a/role-model-router/apps/runtime-host-bridge/src/remote-health-probe.ts b/role-model-router/apps/runtime-host-bridge/src/remote-health-probe.ts index 3e977b8f..d49e7b74 100644 --- a/role-model-router/apps/runtime-host-bridge/src/remote-health-probe.ts +++ b/role-model-router/apps/runtime-host-bridge/src/remote-health-probe.ts @@ -138,6 +138,20 @@ export function buildChatCompletionsProbeUrl(apiBase: string): string { return trimmed.endsWith("/v1") ? `${trimmed}/chat/completions` : `${trimmed}/v1/chat/completions`; } +/** + * Resolve the wire model id used by the chat-completions admission probe. + * + * Catalog model ids are provider-prefixed (e.g. ``deepseek/deepseek-v4-flash``), + * but OpenAI-compatible vendors expect the bare upstream id on the wire + * (``deepseek-v4-flash``). Sending the prefixed form makes the vendor reject + * the probe with a 400 that we previously misclassified as ``vendor-down``. + * Mirrors ``resolveProviderLocalModelId`` in the OpenAI execution adapter. + */ +function resolveProbeModelId(modelId: string): string { + const trimmed = modelId.trim(); + return trimmed.includes("/") ? trimmed.split("/").slice(1).join("/") : trimmed; +} + function isTimeoutError(error: unknown): boolean { return ( error instanceof Error && @@ -337,7 +351,7 @@ export async function probeRemoteEndpointAdmission( const probeUrl = buildChatCompletionsProbeUrl(context.apiBase); const body = { - model: context.modelId, + model: resolveProbeModelId(context.modelId), messages: [{ role: "user", content: "role-model admission readiness probe" }], max_tokens: 1, stream: false, diff --git a/role-model-router/apps/runtime-host-bridge/test/remote-endpoint-admission-probe.test.ts b/role-model-router/apps/runtime-host-bridge/test/remote-endpoint-admission-probe.test.ts index 59713d91..562c5f51 100644 --- a/role-model-router/apps/runtime-host-bridge/test/remote-endpoint-admission-probe.test.ts +++ b/role-model-router/apps/runtime-host-bridge/test/remote-endpoint-admission-probe.test.ts @@ -41,7 +41,7 @@ describe("remote endpoint admission probes", () => { }), ); expect(JSON.parse(String(calls[0]?.init?.body))).toEqual({ - model: "deepseek/deepseek-v4-flash", + model: "deepseek-v4-flash", messages: [{ role: "user", content: "role-model admission readiness probe" }], max_tokens: 1, stream: false,