Quellcode für sunfounder_voice_assistant.llm

""" Large Language Model (LLM) module

This module provides a base class for large language models (LLMs) and preset LLM classes.

Example:
    import a preset LLM class

    >>> from sunfounder_voice_assistant.llm import Deepseek as LLM
    >>> from sunfounder_voice_assistant.llm import Grok as LLM
    >>> from sunfounder_voice_assistant.llm import Doubao as LLM
    >>> from sunfounder_voice_assistant.llm import Qwen as LLM
    >>> from sunfounder_voice_assistant.llm import OpenAI as LLM

    initialize the LLM instance

    >>> API_KEY = "your_api_key"
    >>> MODEL = "your_model"
    >>> llm = LLM(api_key=API_KEY, model=MODEL)
    
    For Ollama, you don't need api_key, but you might need to set ip.

    >>> from sunfounder_voice_assistant.llm import Ollama as LLM
    >>> llm = LLM(ip="localhost", model="deepseek-r1:1.5b")

    You can also import a basic LLM class.

    >>> from sunfounder_voice_assistant.llm import LLM as LLM

    You will need to set the base url which compatible with OpenAI completion API.

    >>> llm = LLM(
            base_url="https://api.deepseek.com",
            model=MODEL,
            api_key=API_KEY,
        )

    Or set the whole url if it's not ends with "/v1/chat/completions"

    >>> llm = LLM(
            url="https://api.deepseek.com/v1/chat/completions",
            model=MODEL,
            api_key=API_KEY,
        )

    Set instructions

    >>> llm.set_instructions("You are a helpful assistant.")

    Set welcome message

    >>> llm.set_welcome("Hello, I am a helpful assistant. How can I help you?")

    Prompt the LLM with input text

    >>> input_text = "Hello"
    >>> response = llm.prompt(input_text, stream=True)
    >>> for next_word in response:
    >>>     if next_word:
    >>>         print(next_word, end="", flush=True)
    >>> print("")

    Prompt with image

    >>> input_text = "Hello"
    >>> image = "image.jpg"
    >>> response = llm.prompt(input_text, image=image, stream=True)
    >>> for next_word in response:
    >>>     if next_word:
    >>>         print(next_word, end="", flush=True)
    >>> print("")
"""

from .llm import LLM

__all__ = [
    "LLM",
    "Deepseek",
    "Grok",
    "Doubao",
    "Gemini",
    "Qwen",
    "OpenAI",
    "Ollama",
]

[Doku] class Deepseek(LLM): """ Deepseek preset LLM class Args: *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, *args, **kwargs): super().__init__(*args, base_url="https://api.deepseek.com", **kwargs)
[Doku] class Grok(LLM): """ Grok preset LLM class Args: *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, *args, **kwargs): super().__init__(*args, base_url="https://api.x.ai/v1", **kwargs)
[Doku] class Doubao(LLM): """ Doubao preset LLM class Args: *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, *args, **kwargs): super().__init__(*args, base_url="https://ark.cn-beijing.volces.com/api/v3", **kwargs)
[Doku] class Qwen(LLM): """ Qwen preset LLM class Args: *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, *args, **kwargs): super().__init__(*args, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", **kwargs)
[Doku] class OpenAI(LLM): """ OpenAI preset LLM class Args: *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, *args, **kwargs): super().__init__(*args, base_url="https://api.openai.com/v1", **kwargs)
[Doku] class Ollama(LLM): """ Ollama preset LLM class Args: ip (str, optional): IP address of Ollama server. Defaults to "localhost". *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` api_key (str, optional): API key of Ollama server. Defaults to "ollama". **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, ip: str="localhost", *args, api_key: str="ollama", **kwargs): super().__init__(*args, url=f"http://{ip}:11434/api/chat", # base_url=f"http://{ip}:11434/v1", api_key=api_key, **kwargs)
[Doku] def add_message(self, role: str, content: str, image_path: str=None) -> None: """ Add message to messages list Args: role (str): Role of message, e.g. "user", "assistant" content (str): Content of message image_path (str, optional): Image path, default is None Raises: ValueError: Role must be 'user' or 'assistant' """ if role not in ["user", "assistant", "system"]: raise ValueError("Role must be 'user' or 'assistant'") data = {"role": role, "content": content} if image_path is not None: # get base64 from image base64 = self.get_base64_from_image(image_path) # add to content data["images"] = [base64] self.messages.append(data)
[Doku] def decode_stream_response(self, line: str) -> str: """ Decode stream response line Args: line (str): Stream response line Returns: str: Decoded content, None if error """ import json try: data = json.loads(line) except json.JSONDecodeError: return None if "message" in data and "content" in data["message"]: return data["message"]["content"] if "error" in data: raise Exception(data["error"]) return None
[Doku] class Gemini(LLM): """ Gemini preset LLM class Args: *args: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` **kwargs: Passed to :class:`sunfounder_voice_assistant.llm.llm.LLM` """ def __init__(self, *args, **kwargs): super().__init__(*args, base_url="https://generativelanguage.googleapis.com/v1beta/openai", **kwargs)