发布

  • [OPIK-5019] [BE] feat: add LLM model registry service and API endpoint (#5691)

    frostbyte_neo 发布于 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

    下载附件