2026-05-08-openai-catalog-ingestor

2026-05-08 — OpenAI catalog ingestor (closes ingestor coverage 1/7 → 2/7)

Summary

R20 risk register, flagged by 2/10 agents (A3, A7): catalog ingestor coverage is 1/7 providers; LiteLLM auto-discovers 100+. PR #218 introduced the first concrete ingestor (Anthropic). This PR adds OpenAI, repeating the same ModelIngestor pattern.

After this PR, ingestor coverage is 2/7 providers with the four remaining providers (Google, DeepSeek, Perplexity, Moonshot, x-AI, Groq) following the same pattern when their respective /v1/models-style endpoints are validated.

Changes

  • src/router/intelligence/openai-ingestor.ts (new, 110 lines) — implements ModelIngestor, polls OpenAI's /v1/models with Authorization: Bearer ${OPENAI_API_KEY}, returns liveness + createdAt patches. OpenAI's /v1/models exposes created as unix seconds; this is converted to ISO string to match the ModelIntelligencePatch type. Pricing intentionally NOT supplied (OpenAI's /v1/models doesn't include it; provider-catalog-pricing.ts remains the curated source).
  • src/router/intelligence/openai-ingestor.test.ts (new, 6 regression tests): liveness shape with epoch→ISO conversion, no-API-key skip, HTTP error path, network error path, no-pricing assertion, key-rotation safety (resolver called fresh each cycle, both calls observed with their respective keys).
  • src/router/model-router-init.ts — registers the OpenAI ingestor hourly when OPENAI_API_KEY is set; logs the disabled state when missing.

Verification

pnpm test:fast       # 821 files / 7496 tests / 0 failed (was 7490 before; +6 from the new tests)
pnpm check           # format/types/lint clean

Will verify post-deploy via CW Logs:

[router/model-router-init] OpenAI catalog ingestor registered (hourly)
[router/openai-ingestor] openai ingest: N models reported alive

Lockstep checklist

  • [x] Sourceopenai-ingestor.ts implementing ModelIngestor
  • [x] Test — 6 paired regression tests
  • [x] Wiringmodel-router-init.ts registers when OPENAI_API_KEY is set
  • [x] Ship log — this file
  • [x] R20 risk register — coverage advanced from 1/7 to 2/7

Follow-ups (separate PRs)

  • Google /v1/models ingestor (different auth: ?key= query param + service account flavor)
  • DeepSeek /v1/models (Bearer auth, OpenAI-compatible response shape)
  • x-AI /v1/models (Bearer auth)
  • Perplexity, Moonshot — verify endpoint shape first