initial commit

This commit is contained in:
Rudis Muiznieks 2025-04-02 13:47:46 -05:00
commit 41a60da7b2
Signed by: rudism
GPG key ID: CABF2F86EF7884F9
3 changed files with 123 additions and 0 deletions

7
README.md Normal file
View file

@ -0,0 +1,7 @@
## Kagi FastGPT Fallback Skill for OVOS
### Plans
- Sent utterance directly to FastGPT, strip references from the answer, and speak it.
- Initially configure with API key, call FastGPT API.
- Hopefully configure with session link, call FastGPT via same url the web app uses to avoid the need for API credits if you're already a Kagi subscriber.

50
__init__.py Normal file
View file

@ -0,0 +1,50 @@
# Copyright 2025 Rudis Muiznieks
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ovos_workshop.skills.fallback import FallbackSkill
import requests
import json
class KagiSkill(FallbackSkill):
def initialize(self):
self.register_fallback(self.handle_fallback_kagi, 80)
def handle_fallback_kagi(self, message):
if "kagiApiKey" not in self.settings:
self.log.error(
"Kagi not configured yet, please set your kagiApiKey in %s",
self.settings.path,
)
return False # not configured yet
api_key = self.settings.get("kagiApiKey", "")
header_content = {
'Authorization': f'Bot {api_key}',
'Content-type': 'application/json',
'Accept': 'application/json'
}
utterance = message.data.get('utterance').lower()
message = [utterance]
js_data = json.dumps({'query': message})
read_url = 'https://kagi.com/api/v0/fastgpt'
response = requests.post(read_url,
data=js_data,
headers=header_content,
verify=False)
json_data = json.loads(response.text)
dirty_response = json_data["data"]["output"];
# TODO: remove [n] reference tokens
self.speak(dirty_response)
return True

66
setup.py Normal file
View file

@ -0,0 +1,66 @@
#!/usr/bin/env python3
from setuptools import setup
from os.path import abspath, dirname, join, isfile, isdir
from os import walk
# Define package information
SKILL_CLAZZ = "KagiSkill" # Make sure it matches __init__.py class name
VERSION = "0.0.1"
URL = "https://code.sitosis.com/rudism/skill-ovos-fallback-kagi"
AUTHOR = "Rudism"
EMAIL = "rudis@sitosis.com"
LICENSE = "Apache2.0"
DESCRIPTION = SKILL_CLAZZ # TODO
PYPI_NAME = URL.split("/")[-1] # pip install PYPI_NAME
# Construct entry point for plugin
SKILL_ID = f"{PYPI_NAME.lower()}.{AUTHOR.lower()}"
SKILL_PKG = PYPI_NAME.lower().replace('-', '_')
PLUGIN_ENTRY_POINT = f"{SKILL_ID}={SKILL_PKG}:{SKILL_CLAZZ}"
# Function to parse requirements from file
def get_requirements(requirements_filename: str = "requirements.txt"):
requirements_file = join(abspath(dirname(__file__)), requirements_filename)
if isfile(requirements_file):
with open(requirements_file, 'r', encoding='utf-8') as r:
requirements = r.readlines()
requirements = [r.strip() for r in requirements if r.strip() and not r.strip().startswith("#")]
if 'MYCROFT_LOOSE_REQUIREMENTS' in os.environ:
print('USING LOOSE REQUIREMENTS!')
requirements = [r.replace('==', '>=').replace('~=', '>=') for r in requirements]
return requirements
return []
# Function to find resource files
def find_resource_files():
resource_base_dirs = ("locale", "ui", "vocab", "dialog", "regex", "res", "frotz)
base_dir = abspath(dirname(__file__))
package_data = ["*.json"]
for res in resource_base_dirs:
if isdir(join(base_dir, res)):
for (directory, _, files) in walk(join(base_dir, res)):
if files:
package_data.append(join(directory.replace(base_dir, "").lstrip('/'), '*'))
return package_data
# Setup configuration
setup(
name=PYPI_NAME,
version=VERSION,
description=DESCRIPTION,
url=URL,
author=AUTHOR,
author_email=EMAIL,
license=LICENSE,
package_dir={SKILL_PKG: ""},
package_data={SKILL_PKG: find_resource_files()},
packages=[SKILL_PKG],
include_package_data=True,
install_requires=get_requirements(),
keywords='ovos skill plugin',
entry_points={'ovos.plugin.skill': PLUGIN_ENTRY_POINT}
)