diff --git a/README.md b/README.md index aca148b..1aa9f30 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ You need to configure a `key`, get it at https://platform.openai.com/api-keys Or use a LocalAI (see example below) - ## About Capabilities: @@ -23,21 +22,29 @@ Limitations: ## Configuration Under skill settings (`.config/mycroft/skills/skill-ovos-fallback-chatgpt.openvoiceos/settings.json`) you can tweak some parameters for chatGPT. -- `key` - your api_key to access OpenAI -- `persona` - can be used to create a "persona", give a personality to chatGPT -- `model` - LLM model to use, eg `gpt-3.5-turbo`, see all options [here](https://platform.openai.com/docs/models) -- `api_url: ` - an optional setting. For the use of OpenAI / ChatGPT it is not necessary. For the use of a LocalAI server instead of OpenAI, the URL can be pointed to an alternative/local server. When using LocalAI, the "key" can be anything, but it has to exist. Read more about it in the OVOS technical manual, page [persona server](https://openvoiceos.github.io/ovos-technical-manual/persona_server/#compatible-projects) -- `memory_enable` - true or false -- `memory_size` - default = 15 +| Option | Value | Description | +| --------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| `key` | `sk-XXXYYYZZZAAABBB123` | Your `api_key` to access OpenAI API | +| `persona` | `You are a helpful assistant who gives very short but factual answers.` | Give a personality to chatGPT | +| `model` | `gpt-3.5-turbo` | LLM model to use, see all the options [here](https://platform.openai.com/docs/models) | +| `api_url` | `https://llama.smartgic.io/v1` | Optional and **only** required with a local AI server | +| `enable_memory` | `true` | Remember the last generated outputs | +| `memory_size` | `15` | How many memories to keep | +| `name` | `Chat G.P.T.` | Name to give to the AI assistant | +| `confirmation` | `true` | Spoken confirmation will be triggered when a request is sent to the AI | -The default persona is `helpful, creative, clever, and very friendly.` +When using a local AI server instead of OpenAI, the `api_url`has to redirect to an alternative/local server compatible with OpenAI API. When using local AI, the `key` can be anything, but it has to exist. Read more about it in the OVOS technical manual, page [persona server](https://openvoiceos.github.io/ovos-technical-manual/persona_server/#compatible-projects) -### Example for use with OpenAI/ ChatGPT: +The default persona is `You are a helpful voice assistant with a friendly tone and fun sense of humor. You respond in 40 words or fewer.` -`cat ~/.config/mycroft/skills/skill-ovos-fallback-chatgpt.openvoiceos/settings.json` +## Configurations -``` +The skill utilizes the `~/.config/mycroft/skills/skill-ovos-fallback-chatgpt.openvoiceos/settings.json` file which allows you to configure it. + +### Configuration for use with OpenAI **(ChatGPT)** + +```json { "key": "sk-XXXYYYZZZAAABBB123", "model": "gpt-3.5-turbo", @@ -48,21 +55,21 @@ The default persona is `helpful, creative, clever, and very friendly.` } ``` -### Example for use with LocalAI: -`cat ~/.config/mycroft/skills/skill-ovos-fallback-chatgpt.openvoiceos/settings.json` +### Configuration for use with Local AI -``` +```json { "api_url": "https://llama.smartgic.io/v1", "key": "sk-xxx", "persona": "You are a helpful voice assistant with a friendly tone and fun sense of humor", "enable_memory": true, "memory_size": 15, + "name": "A.I.", + "confirmation": false, "__mycroft_skill_firstrun": false } ``` - ## Examples - "Explain quantum computing in simple terms" diff --git a/__init__.py b/__init__.py index 4886497..0e3c742 100644 --- a/__init__.py +++ b/__init__.py @@ -10,6 +10,7 @@ "model": "gpt-3.5-turbo", } + class ChatGPTSkill(FallbackSkill): sessions = {} @@ -19,7 +20,7 @@ def runtime_requirements(self): internet_before_load=True, network_before_load=True, requires_internet=True, - requires_network=True + requires_network=True, ) def initialize(self): @@ -28,6 +29,14 @@ def initialize(self): self.add_event("recognizer_loop:utterance", self.handle_utterance) self.register_fallback(self.ask_chatgpt, 85) + @property + def ai_name(self): + return self.settings.get("name", "Chat G.P.T.") + + @property + def confirmation(self): + return self.settings.get("confirmation", True) + @property def chat(self): """created fresh to allow key/url rotation when settings.json is edited""" @@ -36,7 +45,7 @@ def chat(self): except Exception as err: self.log.error(err) return None - + def handle_utterance(self, message): utt = message.data.get("utterances")[0] sess = SessionManager.get(message) @@ -85,17 +94,21 @@ def _async_ask(self, message): for utt in self.chat.stream_utterances(utterance): answered = True self.speak(utt) - except Exception as err: # speak error on any network issue / no credits etc + except Exception as err: # speak error on any network issue / no credits etc self.log.error(err) if not answered: - self.speak_dialog("gpt_error") + self.speak_dialog("gpt_error", data={"name": self.ai_name}) def ask_chatgpt(self, message): if "key" not in self.settings: - self.log.error("ChatGPT not configured yet, please set your API key in %s", self.settings.path) + self.log.error( + "ChatGPT not configured yet, please set your API key in %s", + self.settings.path, + ) return False # ChatGPT not configured yet utterance = message.data["utterance"] - self.speak_dialog("asking") + if self.confirmation: + self.speak_dialog("asking", data={"name": self.ai_name}) # ask in a thread so fallback doesnt timeout self.bus.once("async.chatgpt.fallback", self._async_ask) self.bus.emit( diff --git a/locale/en-us/asking.dialog b/locale/en-us/asking.dialog index 88ef878..474e8d5 100644 --- a/locale/en-us/asking.dialog +++ b/locale/en-us/asking.dialog @@ -1,2 +1,2 @@ -Let me ask Chat G.P.T. -Asking Chat G.P.T. +Let me ask {name} +Asking {name} diff --git a/locale/en-us/gpt_error.dialog b/locale/en-us/gpt_error.dialog index a8d1921..6b2f88a 100644 --- a/locale/en-us/gpt_error.dialog +++ b/locale/en-us/gpt_error.dialog @@ -1,2 +1,2 @@ -I was not able to get an answer from Chat G.P.T. -Sorry but something went wrong with the Chat G.P.T. request. +I was not able to get an answer from {name} +Sorry but something went wrong with the {name} request. diff --git a/locale/fr-fr/asking.dialog b/locale/fr-fr/asking.dialog index 86432ec..166f95d 100644 --- a/locale/fr-fr/asking.dialog +++ b/locale/fr-fr/asking.dialog @@ -1,2 +1,2 @@ -Laissez moi poser la question à Chat G.P.T. -Je demande à Chat G.P.T. +Laissez moi poser la question à {name} +Je demande à {name} diff --git a/locale/fr-fr/gpt_error.dialog b/locale/fr-fr/gpt_error.dialog index 98279c7..c9d9663 100644 --- a/locale/fr-fr/gpt_error.dialog +++ b/locale/fr-fr/gpt_error.dialog @@ -1,2 +1,2 @@ -Je n'ai pas pu obtenir de réponse venant de Chat G.P.T. -Désolé, mais quelque chose s'est mal passé avec la demande à Chat G.P.T. +Je n'ai pas pu obtenir de réponse venant de {name} +Désolé, mais quelque chose s'est mal passé avec la demande à {name} diff --git a/locale/nl-nl/asking.dialog b/locale/nl-nl/asking.dialog index cbdd306..77ddb89 100644 --- a/locale/nl-nl/asking.dialog +++ b/locale/nl-nl/asking.dialog @@ -1,2 +1,2 @@ -Ik vraag het Chat GPT. -ChatGPT weet het antwoord. \ No newline at end of file +Ik vraag het {name} +{name} weet het antwoord. \ No newline at end of file diff --git a/locale/nl-nl/gpt_error.dialog b/locale/nl-nl/gpt_error.dialog index c25d211..078c71e 100644 --- a/locale/nl-nl/gpt_error.dialog +++ b/locale/nl-nl/gpt_error.dialog @@ -1,2 +1,2 @@ -Ik kon geen antwoord krijgen van Chat GPT. -Sorry, maar er is iets misgegaan met het verzoek aan Chat GPT. \ No newline at end of file +Ik kon geen antwoord krijgen van {name} +Sorry, maar er is iets misgegaan met het verzoek aan {name} \ No newline at end of file