Skip to content

Commit

Permalink
Support Anyscale LLM (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
gritaro authored Feb 21, 2024
1 parent c50d09f commit 75a5c78
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 33 deletions.
4 changes: 4 additions & 0 deletions README-ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* [GigaChat](#GigaChat) (<a href="https://developers.sber.ru/docs/ru/gigachat/overview">русскоязычная (но не только) нейросеть от Сбера</a>)
* [YandexGPT](#YandexGPT)
* [OpenAI](#OpenAI) ака ChatGPT (не тестируется)
* [Anyscale](#Anyscale)

## Установка
Устанавливается как и любая HACS интеграция.
Expand Down Expand Up @@ -70,6 +71,9 @@
### OpenAI
Для генерации ключа проследуйте по ссылке https://platform.openai.com/account/api-keys

### Anyscale
[Зарегистрируйтесь](https://app.endpoints.anyscale.com/welcome) и создайте API ключ [здесь](https://app.endpoints.anyscale.com/credentials)

## Конфигурация

* _Темплейт промпта_ (template, Home Assistant <a href=https://www.home-assistant.io/docs/configuration/templating/>`template`</a>)
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Currently supported LMMs:
* [GigaChat](#GigaChat) (<a href="https://developers.sber.ru/docs/ru/gigachat/overview">Sber LLM</a>)
* [YandexGPT](#YandexGPT)
* [OpenAI](#OpenAI) aka ChatGPT (not tested)
* [Anyscale](#Anyscale)

## Installation
Install it like any other HACS integration.
Expand Down Expand Up @@ -65,6 +66,9 @@ You can find Folder ID using this <a href="https://console.cloud.yandex.com/fold
### OpenAI
Create API key here https://platform.openai.com/account/api-keys

### Anyscale
[Register account](https://app.endpoints.anyscale.com/welcome) and create API key [here](https://app.endpoints.anyscale.com/credentials)

## Configuration

* _Prompt template_ (template, Home Assistant <a href=https://www.home-assistant.io/docs/configuration/templating/>`template`</a>)
Expand Down
6 changes: 3 additions & 3 deletions custom_components/gigachain/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if max_tokens is not None:
common_args["max_tokens"] = max_tokens

_client = await get_client(engine, common_args, entry)
_client = await get_client(hass, engine, entry, common_args)

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = _client
_agent = GigaChatAI(hass, entry)
Expand Down Expand Up @@ -126,11 +126,11 @@ async def async_process(

messages.append(res)
self.history[conversation_id] = messages
LOGGER.info(messages)
LOGGER.debug(messages)

response = intent.IntentResponse(language=user_input.language)
response.async_set_speech(res.content)
LOGGER.info(response)
LOGGER.debug(response)
return agent.ConversationResult(
conversation_id=conversation_id, response=response
)
Expand Down
33 changes: 28 additions & 5 deletions custom_components/gigachain/client_util.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import logging
from typing import Set

from homeassistant.core import HomeAssistant
from langchain.schema import SystemMessage
from langchain_community.chat_models import ChatOpenAI, ChatYandexGPT, GigaChat
from langchain_community.chat_models import ChatOpenAI, ChatYandexGPT, GigaChat, ChatAnyscale

from .const import (CONF_API_KEY, CONF_ENGINE, CONF_FOLDER_ID, CONF_PROFANITY,
CONF_SKIP_VALIDATION, DEFAULT_PROFANITY, ID_GIGACHAT,
ID_YANDEX_GPT)
ID_YANDEX_GPT, ID_OPENAI, ID_ANYSCALE, DEFAULT_MODEL, MODELS_ANYSCALE)

LOGGER = logging.getLogger(__name__)

Expand All @@ -33,18 +34,25 @@ async def validate_client(
api_key=user_input[CONF_API_KEY],
folder_id=user_input[CONF_FOLDER_ID],
)
elif engine == ID_ANYSCALE:
client = LocalChatAnyscale(
max_tokens=10,
max_retries=2,
model=DEFAULT_MODEL[ID_ANYSCALE],
anyscale_api_key=user_input[CONF_API_KEY]
)
else:
credentials = user_input[CONF_API_KEY]
client = ChatOpenAI(
max_tokens=10,
model="gpt-3.5-turbo",
model=DEFAULT_MODEL[ID_ANYSCALE],
openai_api_key=credentials,
)
res = client([SystemMessage(content="{}")])
LOGGER.debug(res)


async def get_client(engine, common_args, entry):
async def get_client(hass: HomeAssistant, engine, entry, common_args):
if engine == ID_GIGACHAT:
common_args["credentials"] = entry.data[CONF_API_KEY]
common_args["verify_ssl_certs"] = False
Expand All @@ -55,9 +63,24 @@ async def get_client(engine, common_args, entry):
common_args["folder_id"] = entry.data[CONF_FOLDER_ID]
common_args["max_retries"] = 2
client = ChatYandexGPT(**common_args)
elif engine == ID_ANYSCALE:
common_args["anyscale_api_key"] = entry.data[CONF_API_KEY]
if common_args["model"] is None:
common_args["model"] = DEFAULT_MODEL[ID_ANYSCALE]
client = LocalChatAnyscale(**common_args)
else:
if common_args["model"] is None:
common_args["model"] = "gpt-3.5-turbo"
common_args["model"] = DEFAULT_MODEL[ID_OPENAI]
common_args["openai_api_key"] = entry.data[CONF_API_KEY]
client = ChatOpenAI(**common_args)
return client


class LocalChatAnyscale(ChatAnyscale):
@staticmethod
def get_available_models(
anyscale_api_key: str = None,
anyscale_api_base: str = None,
) -> Set[str]:
"""Get available models from configuration."""
return MODELS_ANYSCALE
12 changes: 9 additions & 3 deletions custom_components/gigachain/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
CONF_ENGINE, CONF_ENGINE_OPTIONS, CONF_FOLDER_ID,
CONF_MAX_TOKENS, CONF_PROFANITY, CONF_PROMPT,
CONF_SKIP_VALIDATION, CONF_TEMPERATURE, DEFAULT_CHAT_MODEL,
DEFAULT_MODELS, DEFAULT_PROFANITY, DEFAULT_PROMPT,
ENGINE_MODELS, DEFAULT_PROFANITY, DEFAULT_PROMPT,
DEFAULT_SKIP_VALIDATION, DEFAULT_TEMPERATURE, DOMAIN,
ID_GIGACHAT, ID_OPENAI, ID_YANDEX_GPT, UNIQUE_ID,
CONF_PROCESS_BUILTIN_SENTENCES, DEFAULT_PROCESS_BUILTIN_SENTENCES,
CONF_CHAT_HISTORY, DEFAULT_CHAT_HISTORY,
UNIQUE_ID_GIGACHAT)
UNIQUE_ID_GIGACHAT, ID_ANYSCALE)

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -61,6 +61,7 @@
ID_GIGACHAT: STEP_API_KEY_SCHEMA,
ID_YANDEX_GPT: STEP_YANDEXGPT_SCHEMA,
ID_OPENAI: STEP_API_KEY_SCHEMA,
ID_ANYSCALE: STEP_API_KEY_SCHEMA,
}

DEFAULT_OPTIONS = types.MappingProxyType(
Expand Down Expand Up @@ -101,6 +102,11 @@ async def async_step_yandexgpt(
) -> FlowResult:
return await self.common_model_async_step(ID_YANDEX_GPT, user_input)

async def async_step_anyscale(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
return await self.common_model_async_step(ID_ANYSCALE, user_input)

async def async_step_openai(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
Expand Down Expand Up @@ -189,7 +195,7 @@ def common_config_option_schema(
},
default="none",
): selector.SelectSelector(
selector.SelectSelectorConfig(mode=SelectSelectorMode("dropdown"), options=DEFAULT_MODELS[unique_id]),
selector.SelectSelectorConfig(mode=SelectSelectorMode("dropdown"), options=ENGINE_MODELS[unique_id]),
),
vol.Optional(
CONF_CHAT_MODEL_USER,
Expand Down
60 changes: 41 additions & 19 deletions custom_components/gigachain/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,44 @@
ID_GIGACHAT = "gigachat"
ID_YANDEX_GPT = "yandexgpt"
ID_OPENAI = "openai"
ID_ANYSCALE = "anyscale"
UNIQUE_ID_GIGACHAT = "GigaChat"
UNIQUE_ID_YANDEX_GPT = "YandexGPT"
UNIQUE_ID_OPENAI = "OpenAI"
UNIQUE_ID_ANYSCALE = "Anyscale"

UNIQUE_ID = {
ID_GIGACHAT: UNIQUE_ID_GIGACHAT,
ID_YANDEX_GPT: UNIQUE_ID_YANDEX_GPT,
ID_OPENAI: UNIQUE_ID_OPENAI,
ID_ANYSCALE: UNIQUE_ID_ANYSCALE
}

CONF_ENGINE_OPTIONS = [
selector.SelectOptionDict(value=ID_GIGACHAT, label=UNIQUE_ID_GIGACHAT),
selector.SelectOptionDict(value=ID_YANDEX_GPT, label=UNIQUE_ID_YANDEX_GPT),
selector.SelectOptionDict(value=ID_OPENAI, label=UNIQUE_ID_OPENAI),
selector.SelectOptionDict(value=ID_ANYSCALE, label=UNIQUE_ID_ANYSCALE),
]
DEFAULT_MODELS_GIGACHAT = [
MODELS_GIGACHAT = [
" ",
"GigaChat",
"GigaChat:latest",
"GigaChat-Plus",
"GigaChat-Pro",
]
DEFAULT_MODELS_YANDEX_GPT = [" ", "YandexGPT", "YandexGPT Lite", "Summary"]
DEFAULT_MODELS_OPENAI = ["gpt-4",
MODELS_ANYSCALE = [" ",
"codellama/CodeLlama-34b-Instruct-hf",
"Open-Orca/Mistral-7B-OpenOrca",
"mistralai/Mixtral-8x7B-Instruct-v0.1",
"HuggingFaceH4/zephyr-7b-beta",
"BAAI/bge-large-en-v1.5",
"mlabonne/NeuralHermes-2.5-Mistral-7B",
"meta-llama/Llama-2-13b-chat-hf", "meta-llama/Llama-2-70b-chat-hf",
"thenlper/gte-large", "Meta-Llama/Llama-Guard-7b", "meta-llama/Llama-2-7b-chat-hf",
"codellama/CodeLlama-70b-Instruct-hf", "mistralai/Mistral-7B-Instruct-v0.1"]
MODELS_OPENAI = ["gpt-4",
"gpt-4-0314",
"gpt-4-0613",
"gpt-4-32k",
Expand All @@ -77,24 +91,32 @@
"gpt-3.5-turbo-0613",
"gpt-3.5-turbo-16k",
"gpt-3.5-turbo-16k-0613",
"gpt-3.5-turbo-instruct",
"text-ada-001",
"ada",
"text-babbage-001",
"babbage",
"text-curie-001",
"curie",
"davinci",
"text-davinci-003",
"text-davinci-002",
"code-davinci-002",
"code-davinci-001",
"code-cushman-002",
"code-cushman-001"]
DEFAULT_MODELS = {
UNIQUE_ID_GIGACHAT: DEFAULT_MODELS_GIGACHAT,
"gpt-3.5-turbo-instruct",
"text-ada-001",
"ada",
"text-babbage-001",
"babbage",
"text-curie-001",
"curie",
"davinci",
"text-davinci-003",
"text-davinci-002",
"code-davinci-002",
"code-davinci-001",
"code-cushman-002",
"code-cushman-001"]
ENGINE_MODELS = {
UNIQUE_ID_GIGACHAT: MODELS_GIGACHAT,
UNIQUE_ID_YANDEX_GPT: DEFAULT_MODELS_YANDEX_GPT,
UNIQUE_ID_OPENAI: DEFAULT_MODELS_OPENAI,
UNIQUE_ID_OPENAI: MODELS_OPENAI,
UNIQUE_ID_ANYSCALE: MODELS_ANYSCALE
}
DEFAULT_MODEL = {
ID_GIGACHAT: None,
ID_OPENAI: "gpt-3.5-turbo",
ID_YANDEX_GPT: None,
ID_ANYSCALE: "meta-llama/Llama-2-7b-chat-hf"
}

CONF_API_KEY = "api_key"
CONF_FOLDER_ID = "folder_id"
6 changes: 3 additions & 3 deletions custom_components/gigachain/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"issue_tracker": "https://github.com/gritaro/gigachain/issues",
"requirements": [
"home-assistant-intents",
"gigachain==0.1.4",
"yandexcloud==0.259.0"
"gigachain==0.1.7.1",
"yandexcloud==0.260.0"
],
"version": "0.1.5"
"version": "0.1.6"
}
7 changes: 7 additions & 0 deletions custom_components/gigachain/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
"skip_validation": "Skip validation"
}
},
"anyscale": {
"title": "Anyscale configuration",
"data": {
"api_key": "Api key",
"skip_validation": "Skip validation"
}
},
"yandexgpt": {
"title": "YandexGPT configuration",
"data": {
Expand Down
7 changes: 7 additions & 0 deletions custom_components/gigachain/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
"skip_validation": "Skip validation"
}
},
"anyscale": {
"title": "Anyscale configuration",
"data": {
"api_key": "Api key",
"skip_validation": "Skip validation"
}
},
"yandexgpt": {
"title": "YandexGPT configuration",
"data": {
Expand Down
7 changes: 7 additions & 0 deletions custom_components/gigachain/translations/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
"skip_validation": "Skip validation"
}
},
"anyscale": {
"title": "Конфигурация Anyscale",
"data": {
"api_key": "Api ключ",
"skip_validation": "Skip validation"
}
},
"yandexgpt": {
"title": "Конфигурация YandexGPT",
"data": {
Expand Down

0 comments on commit 75a5c78

Please sign in to comment.