Validate at both sides of the provider call
Use one schema for your application request and another for the normalized decision result. This prevents provider-specific optional fields from spreading through UI and business logic.
Return a typed fallback state
Timeouts, missing answers, and confidence below your threshold should resolve to an explicit fallback variant. The caller can then handle review or retry without guessing why normal data is missing.
Keep model configuration on the server
Provider keys, endpoints, model IDs, and usage metadata should stay in a server route or worker. The browser only needs the application-level result and any safe explanation you choose to expose.
typescript / server route
const response = await fetch("/api/jev/evaluate", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ state, questions }),
})
if (!response.ok) return { status: "fallback" as const }
const decision = await response.json()