MemberJunction / MemberJunction/MJ
vwAIModels flattened APIName is a cross-vendor footgun: adding an AIModelVendor row can silently change every consumer's model id
- Dominant language
- TSQL
- Stars
- 29
- Forks
- 6
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 323
Description
## Summary
`vwAIModels` flattens `APIName` to the single vendor row that wins the priority sort (`ORDER BY Priority DESC` as of v5.44). Any consumer that reads `Model.APIName` and hands it to a **specific** vendor's SDK is one metadata row away from breakage: adding a higher-priority `AIModelVendor` row for a different vendor silently swaps the id format for everyone.
## Real incident (2026-07-06)
- A model had a Google vendor row (`APIName='gemini-3.1-pro-preview'`, Priority 0).
- An OpenRouter vendor row was added (`APIName='google/gemini-3.1-pro-preview'`, Priority 50).
- After the v5.44 view change, the flattened `APIName` flipped to the OpenRouter format.
- A consumer that resolved the model id from `AIEngine.Instance.Models[].APIName` and called the `@google/genai` SDK directly began 404ing on every call (`models/google/gemini-3.1-pro-preview:generateContent`). Nothing in the model's own configuration had changed.
## The footgun
`APIName` only has meaning **relative to a vendor** (`AIModelVendor.APIName`), but the flattened view field presents it as a property of the model. There is no warning that its value depends on the priority ordering of unrelated vendor rows.
Our fix was to stop reading the flattened field and pin `{ modelId, vendorId }` via `AIPromptParams.override`, letting `AIPromptRunner` pair `APIName` + `DriverClass` + credentials from the same `AIModelVendor` row atomically — which is structurally immune. But other consumers (in MJ and downstream) may still read the flattened field.
## Suggestions (any of)
1. Document prominently (TSDoc on the generated entity field + view extended property) that `vwAIModels.APIName` is "highest-priority vendor's API name" and must not be fed to a vendor-specific SDK.
2. Audit MJ-internal consumers of the flattened `APIName` for the same pattern.
3. Longer term: expose API names only through vendor-scoped accessors (model+vendor pair) and deprecate the flattened field.
## Version
MJ v5.44.0
Contributor guide
Research direction
Start with the vwAIModels view and the generated entity field for APIName; review how its Priority ordering selects a vendor value. Then inspect AIEngine.Instance.Models, AIPromptParams.override, and AIPromptRunner for consumers and vendor-pinned behavior. Done means the affected consumers are audited and the chosen documentation, accessor, or deprecation scope is agreed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sql
- Domain
- ai, backend-api-design, database
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100