Source code for quackamollie.model_manager.llama_index.llama_index_model_manager

# -*- coding: utf-8 -*-
__all__ = ["LlamaIndexQuackamollieModelManager"]
__author__ = "QuacktorAI"
__copyright__ = "Copyright 2024, Forge of Absurd Ducks"
__credits__ = ["QuacktorAI"]

from llama_index.core.base.llms.types import MessageRole, ChatMessage as LlamaIndexChatMessage
from quackamollie.core.database.model import ChatMessage
from quackamollie.core.enum.model_family_icon import ModelFamilyIcon
from quackamollie.core.meta.model_manager.meta_quackamollie_model_manager import MetaQuackamollieModelManager
from typing import Dict, List, Optional, Type

from quackamollie.model.meta.llama_index.llama_index_meta_model import MetaLlamaIndexQuackamollieModel
from quackamollie.model_manager.llama_index.helpers.llama_index_model_entry_point import (
    get_llama_index_models_from_entrypoints
)


[docs] class LlamaIndexQuackamollieModelManager(MetaQuackamollieModelManager): """ Model manager managed by the `QuackamollieModelManagerRegistry` and serving models using Llama-Index """ families: List[ModelFamilyIcon] = [ModelFamilyIcon.LLAMA_INDEX] LLAMA_INDEX_ENTRYPOINT_GROUP: str = "quackamollie.model.llama_index" _entrypoint_model_dict: Optional[Dict[str, Type[MetaLlamaIndexQuackamollieModel]]] = None
[docs] @classmethod async def get_entrypoint_model_dict(cls) -> Optional[Dict[str, Type[MetaLlamaIndexQuackamollieModel]]]: if cls._entrypoint_model_dict is None: cls._entrypoint_model_dict = get_llama_index_models_from_entrypoints(cls.LLAMA_INDEX_ENTRYPOINT_GROUP) return cls._entrypoint_model_dict
[docs] @classmethod async def get_model_list(cls) -> Optional[List[str]]: """ Discover the models available for the model manager at runtime asynchronously :return: A list of available models for the model manager :rtype: List[str] """ if cls._model_list is None: entrypoint_model_dict = await cls.get_entrypoint_model_dict() if entrypoint_model_dict is not None: cls._model_list = list(entrypoint_model_dict.keys()) return cls._model_list
[docs] @classmethod async def get_model_families(cls) -> Dict[str, List[ModelFamilyIcon]]: """ Discover the models families available for the model manager at runtime asynchronously :return: A dict with values the list of families indexed by model name :rtype: Dict[str, List[ModelFamilyIcon]] """ if cls._model_families is None: entrypoint_model_dict = await cls.get_entrypoint_model_dict() if cls._entrypoint_model_dict is not None: cls._model_families = {} for entrypoint_name, model_class in entrypoint_model_dict.items(): cls._model_families[entrypoint_name] = model_class.model_families return cls._model_families
[docs] @classmethod def parse_chat_history(cls, chat_messages: Optional[List[ChatMessage]]) -> List[LlamaIndexChatMessage]: """ Parse the chat history given as a list of `ChatMessage` from the database model to a list compatible with the model manager's models. :param chat_messages: A list of `ChatMessage` from the database model :param chat_messages: Optional[List[ChatMessage]] :return: A list of messages formatted to be compatible with the model manager's models. :rtype: List[LlamaIndexChatMessage] """ chat_history: List[LlamaIndexChatMessage] = [] # Construct the list of messages in a format supported by Llama Index if chat_messages: for past_msg in chat_messages: chat_history.append(LlamaIndexChatMessage(role=MessageRole(past_msg.user.user_type.value.lower()), content=past_msg.content)) return chat_history
[docs] @classmethod async def get_model_class(cls, model_name: str) -> Optional[Type[MetaLlamaIndexQuackamollieModel]]: """ Get the model class from the model name :param model_name: Name of the model as listed by `cls.get_model_list` :type model_name: str :return: A subclass of MetaQuackamollieModel :rtype: Optional[Type[MetaLlamaIndexQuackamollieModel]] """ entrypoint_model_dict = await cls.get_entrypoint_model_dict() if entrypoint_model_dict is None: return None else: return entrypoint_model_dict.get(model_name, None)
[docs] @classmethod def reset(cls): """ Reset the model manager dynamic fields to force reloading models. Be careful if used asynchronously """ cls._entrypoint_model_dict = None cls._model_list = None cls._model_families = None