Source code for oarepo_config.llm

#
# Copyright (c) 2025 CESNET z.s.p.o.
#
# This file is a part of oarepo-checks (see https://github.com/oarepo/oarepo-checks).
#
# oarepo-checks is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
#
"""Configuration for oarepo-checks."""

from __future__ import annotations

from .base import get_constant_from_caller, set_constants_in_caller

OAREPO_CHECKS_DEFAULT_CHAT_EINFRA_CLIENT = "chat_einfra"


[docs] def configure_llm( # noqa: PLR0913 api_token: str | None = None, *, enabled: bool = True, client_name: str = OAREPO_CHECKS_DEFAULT_CHAT_EINFRA_CLIENT, api_url: str = "https://llm.ai.e-infra.cz/v1/chat/completions", model: str = "gpt-oss-120b", fallback_community: str | None = None, as_default: bool = True, ) -> None: """Set up the LLM client(s) used by oarepo-checks' AI-assisted record validation. ``oarepo-checks`` can validate a record's metadata by sending it to a Large Language Model and checking the response (its ``"llm"`` check, shown to users as "AI validation") before a record may be published. This registers one such LLM client (built-in support is for chat.ai.e-infra.cz) that the check can use. Call it once per LLM client/token you want available - each call reads back and extends whatever a previous call already registered (via :func:`get_constant_from_caller`), it does not replace it. This also means, when calling it more than once, that **whichever call has ``as_default=True`` last wins** as the default client. Requires the optional ``oarepo-checks`` package to be installed; without it, calling this raises an ``ImportError`` explaining that the package needs to be installed first. Args: api_token: Bearer token for the ``ChatEInfraClient`` (chat.ai.e-infra.cz). If not given, this call only touches ``CHECKS_ENABLED``/``CHECKS_GENERIC_COMMUNITY``/the default client marker below, without registering a new client under ``client_name``. Typically read from the deployment's ``variables``/``.env``/environment via :func:`load_configuration_variables`, not hardcoded. enabled: Set to ``False`` to skip configuring the LLM subsystem entirely (nothing else below is set). client_name: The key this client is registered under in ``OAREPO_CHECKS_LLM_CLIENTS``. Use a different name per call if you are registering more than one client. api_url: The ``ChatEInfraClient`` API endpoint to send requests to. model: The model name the ``ChatEInfraClient`` requests. fallback_community: Slug of the community used for checks that aren't tied to a specific community. If given, overrides whatever a previous call already set; if not given, an already-set value is kept, defaulting to ``"llm-settings-community"`` if no call has provided one yet. as_default: Mark ``client_name`` as the client checks use when they don't request one by name (``OAREPO_CHECKS_DEFAULT_LLM_CLIENT``). Invenio configuration variables set: * ``CHECKS_ENABLED`` - the ``enabled`` argument above. * ``OAREPO_CHECKS_LLM_CLIENTS`` - only if ``enabled``; extended (not replaced) with a ``ChatEInfraClient`` entry under ``client_name``, only if ``api_token`` was given. * ``OAREPO_CHECKS_DEFAULT_LLM_CLIENT`` - only if ``enabled`` and ``as_default``; set to ``client_name``. * ``CHECKS_GENERIC_COMMUNITY`` - only if ``enabled``; ``fallback_community`` if given, else an already-set value, else ``"llm-settings-community"``. Example: .. code-block:: python env = config.load_configuration_variables() config.configure_llm( api_token=env.get( "INVENIO_LLM_API_TOKEN" ) ) # registering a second, non-default client: config.configure_llm( api_token=env.get( "INVENIO_LLM_BACKUP_API_TOKEN" ), client_name="chat_einfra_backup", as_default=False, ) """ try: from oarepo_checks.llm_client import ChatEInfraClient except ImportError as e: raise ImportError("Please install oarepo-checks to use llm configuration") from e CHECKS_ENABLED = enabled if CHECKS_ENABLED: OAREPO_CHECKS_LLM_CLIENTS = dict(get_constant_from_caller("OAREPO_CHECKS_LLM_CLIENTS") or {}) if as_default: OAREPO_CHECKS_DEFAULT_LLM_CLIENT = client_name if fallback_community: CHECKS_GENERIC_COMMUNITY = fallback_community else: CHECKS_GENERIC_COMMUNITY = get_constant_from_caller("CHECKS_GENERIC_COMMUNITY") or "llm-settings-community" if api_token and client_name not in OAREPO_CHECKS_LLM_CLIENTS: OAREPO_CHECKS_LLM_CLIENTS[client_name] = ChatEInfraClient( api_token=api_token, api_url=api_url, model=model, ) set_constants_in_caller(locals())