CODEX // oaoisme wiki

§ unswayed-backend · API contract & docs

AI model seam — per-call model selection (ADR-0042)

updated 2026-06-17

What it is

A small but load-bearing upgrade to AiCompletionPort — the single seam every LLM call in the backend goes through (Lexi, the resume AI, and the three Lenux LLM calls). It used to send one hard-coded model + sampling for everyone; now each call site picks the right model, temperature, and response format for its task, and the whole thing can be pointed at a different OpenAI-compatible provider with one env var.

The shape

complete(messages: ChatMessage[], options?: AiCompletionOptions): Promise<string>

interface AiCompletionOptions {
  model?: string;
  maxTokens?: number;
  temperature?: number;
  topP?: number;
  frequencyPenalty?: number;
  presencePenalty?: number;
  responseFormat?: 'text' | 'json'; // 'json' → response_format:{type:'json_object'}
}

Omitting options reproduces the exact previous behaviour (Lexi's tuned conversational params), so nothing that didn't opt in changed.

Config — openaiConfig

Two additions:

  • baseURL (OPENAI_BASE_URL) — point the OpenAI SDK at any OpenAI-API-compatible endpoint (e.g. a zero-retention DeepSeek/Kimi host). Unset ⇒ OpenAI itself.
  • models — a per-purpose map, each env-overridable:
    • default (OPENAI_MODEL, gpt-4o) — Lexi
    • resume (OPENAI_RESUME_MODEL, defaults to the base model) — resume extract/enhance
    • lenux (OPENAI_LENUX_MODEL, gpt-4o-mini) — interview questions + JD optimization
    • intent (OPENAI_INTENT_MODEL, gpt-4o-mini) — Lenux chat intent classification

How each call is routed

Call Model Sampling JSON mode
Lexi assistant models.default (gpt-4o) tuned defaults no (unchanged)
Resume extract/enhance models.resume (gpt-4o) enhance temp/tokens extract: yes
Interview questions, JD bias/skills/SEO models.lenux (gpt-4o-mini) temp 0.2 yes
Chat intent classification models.intent (gpt-4o-mini) temp 0, max 400 yes

Why these defaults

The Lenux tasks are short structured generation / classification, not reasoning — so a cheap fast small tier (gpt-4o-mini, ~16–40× cheaper output than gpt-4o) is the right tool; a "more powerful" reasoning model would be slower, pricier, and worse at JSON/tool reliability. Chat-intent is on the request path, so it gets the lowest temperature and a small token cap for latency. Lexi and the resume rewrite stay on gpt-4o because they're user-facing quality surfaces — they're not silently downgraded. JSON mode is the reliability win; the existing retry-once parsers stay as defence (json_object can still occasionally return empty content).

A newer/cheaper SKU (or a different provider via baseURL) is now a config flip, not a code change. Compliance caveat (ADR-0041): candidate data must not go to a China-jurisdiction first-party API — if DeepSeek/Kimi is ever used it must be the open weights on a Western SOC2/zero-retention host. Default is OpenAI.

See ADR-0042.