-
[OPIK-5019] [BE] feat: add LLM model registry service and API endpoint (#5691)
发布于
2026-03-23 14:59:03 +00:00 - [OPIK-5019] [BE] feat: add LLM model registry service and API endpoint
Add a YAML-based model registry that loads supported LLM models at
startup from a classpath resource, with optional local override file
for self-hosted customers. Expose via GET /v1/private/llm/models.- LlmModelDefinition record with id, qualifiedName, structuredOutput, reasoning
- LlmModelRegistryService loads/merges/caches from YAML
- LlmModelsResource REST endpoint
- llm-models-default.yaml with 525 models across 5 providers
- 52 reasoning models tagged (OpenAI o-series, DeepSeek R1, QwQ, :thinking)
- 9 unit tests covering load, merge, override, reload, immutability
- Guice wiring in LlmModule, config in OpikConfiguration + config.yml
No changes to existing routing or frontend — additive only.
Implements OPIK-5019: [BE] Add LLM model registry service and API endpoint
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- fix(registry): narrow reload() catch and guard null lists in merge
- Catch only UncheckedIOException | IllegalStateException in reload()
instead of broad Exception - Skip null/empty override lists in merge() to prevent NPE from
malformed customer YAML
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- fix(registry): make LlmModelRegistryService self-injectable via Guice
Integration tests that disable LlmModule (e.g. AutomationRuleEvaluatorsResourceTest,
ManualEvaluationResourceTest) failed because vyarus auto-config discovered
LlmModelsResource but had no binding for LlmModelRegistryService.Move from @Provides in LlmModule to @Inject @Singleton on the service itself,
with a package-private constructor for unit tests.Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- fix(registry): address PR review feedback
- Remove @JsonProperty annotations that broke global snake_case convention in HTTP responses
- Move LlmModelDefinition to com.comet.opik.api (response DTO, not infrastructure)
- Add null/blank id guard in merge() for both default and override entries
- Add @NonNull on merge() parameters
- Add // visible for testing comment on package-private constructor
- Add comment on volatile explaining scheduled refresh intent (OPIK-5020)
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- fix(registry): deep-copy provider lists for full immutability
Map.copyOf() only makes the outer map immutable; the List values from
Jackson are mutable ArrayLists. Added immutable() helper to wrap each
list with List.copyOf() in the load() fast paths.Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
- fixed formatting
Co-authored-by: Andrei Căutișanu andreicautisanu@Andreis-MacBook-Pro.local
Co-authored-by: Claude Opus 4.6 (1M context) noreply@anthropic.com下载附件