chore: Update vehicle destination in calculate_route function
Browse files- {core → kitt/core}/__init__.py +8 -2
- kitt/skills/__init__.py +42 -0
- kitt/skills/common.py +62 -0
{core → kitt/core}/__init__.py
RENAMED
@@ -10,6 +10,7 @@ from TTS.api import TTS
|
|
10 |
|
11 |
os.environ["COQUI_TOS_AGREED"] = "1"
|
12 |
|
|
|
13 |
|
14 |
Voice = namedtuple("voice", ["name", "neutral", "angry", "speed"])
|
15 |
|
@@ -181,8 +182,13 @@ def tts(
|
|
181 |
return wavs
|
182 |
|
183 |
|
184 |
-
def tts_gradio(
|
|
|
|
|
|
|
|
|
185 |
voice_path = voice_from_text(voice)
|
|
|
186 |
(gpt_cond_latent, speaker_embedding) = compute_speaker_embedding(
|
187 |
voice_path, tts_pipeline.synthesizer.tts_config, tts_pipeline, cache
|
188 |
)
|
@@ -193,7 +199,7 @@ def tts_gradio(tts_pipeline, text, voice, cache):
|
|
193 |
speaker=None,
|
194 |
gpt_cond_latent=gpt_cond_latent,
|
195 |
speaker_embedding=speaker_embedding,
|
196 |
-
speed=
|
197 |
# file_path="out.wav",
|
198 |
)
|
199 |
return (22050, np.array(out)), dict(text=text, voice=voice)
|
|
|
10 |
|
11 |
os.environ["COQUI_TOS_AGREED"] = "1"
|
12 |
|
13 |
+
tts_pipeline = None
|
14 |
|
15 |
Voice = namedtuple("voice", ["name", "neutral", "angry", "speed"])
|
16 |
|
|
|
182 |
return wavs
|
183 |
|
184 |
|
185 |
+
def tts_gradio(text, voice, cache):
|
186 |
+
global tts_pipeline
|
187 |
+
if not tts_pipeline:
|
188 |
+
tts_pipeline = load_tts_pipeline()
|
189 |
+
|
190 |
voice_path = voice_from_text(voice)
|
191 |
+
speed = speed_from_text(voice)
|
192 |
(gpt_cond_latent, speaker_embedding) = compute_speaker_embedding(
|
193 |
voice_path, tts_pipeline.synthesizer.tts_config, tts_pipeline, cache
|
194 |
)
|
|
|
199 |
speaker=None,
|
200 |
gpt_cond_latent=gpt_cond_latent,
|
201 |
speaker_embedding=speaker_embedding,
|
202 |
+
speed=speed,
|
203 |
# file_path="out.wav",
|
204 |
)
|
205 |
return (22050, np.array(out)), dict(text=text, voice=voice)
|
kitt/skills/__init__.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import datetime
|
2 |
+
import inspect
|
3 |
+
|
4 |
+
from .common import execute_function_call, extract_func_args, vehicle as vehicle_obj
|
5 |
+
from .weather import get_weather, get_forecast
|
6 |
+
from .routing import find_route
|
7 |
+
from .poi import search_points_of_interests, search_along_route_w_coordinates
|
8 |
+
from .vehicle import vehicle_status
|
9 |
+
|
10 |
+
|
11 |
+
|
12 |
+
def date_time_info():
|
13 |
+
"""Get the current date and time."""
|
14 |
+
time = getattr(vehicle_obj, "time")
|
15 |
+
date = getattr(vehicle_obj, "date")
|
16 |
+
datetime_obj = datetime.fromisoformat(f"{date}T{time}")
|
17 |
+
human_readable_datetime = datetime_obj.strftime("%I:%M %p %A, %B %d, %Y")
|
18 |
+
return f"It is {human_readable_datetime}."
|
19 |
+
|
20 |
+
|
21 |
+
def do_anything_else():
|
22 |
+
"""If the user wants to do anything else call this function. If the question doesn't match any of the functions use this one."""
|
23 |
+
return True
|
24 |
+
|
25 |
+
|
26 |
+
def format_functions_for_prompt_raven(*functions):
|
27 |
+
"""Format functions for use in Prompt Raven.
|
28 |
+
|
29 |
+
Args:
|
30 |
+
*functions (function): One or more functions to format.
|
31 |
+
"""
|
32 |
+
formatted_functions = []
|
33 |
+
for func in functions:
|
34 |
+
signature = f"{func.__name__}{inspect.signature(func)}"
|
35 |
+
docstring = inspect.getdoc(func)
|
36 |
+
formatted_functions.append(
|
37 |
+
f"Function:\n<func_start>{signature}<func_end>\n<docstring_start>\n{docstring}\n<docstring_end>"
|
38 |
+
)
|
39 |
+
return "\n".join(formatted_functions)
|
40 |
+
|
41 |
+
|
42 |
+
SKILLS_PROMPT = format_functions_for_prompt_raven(get_weather, get_forecast, find_route, search_points_of_interests)
|
kitt/skills/common.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
from typing import Union
|
3 |
+
|
4 |
+
|
5 |
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
6 |
+
from pydantic import BaseModel
|
7 |
+
|
8 |
+
from .. import skills
|
9 |
+
|
10 |
+
class Settings(BaseSettings):
|
11 |
+
WEATHER_API_KEY: str
|
12 |
+
TOMTOM_API_KEY: str
|
13 |
+
|
14 |
+
model_config = SettingsConfigDict(env_file=".env")
|
15 |
+
|
16 |
+
|
17 |
+
class VehicleStatus(BaseModel):
|
18 |
+
location: str
|
19 |
+
location_coordinates: tuple[float, float] # (latitude, longitude)
|
20 |
+
date: str
|
21 |
+
time: str
|
22 |
+
destination: str
|
23 |
+
|
24 |
+
|
25 |
+
def execute_function_call(text: str, dry_run=False) -> str:
|
26 |
+
function_name_match = re.search(r"Call: (\w+)", text)
|
27 |
+
function_name = function_name_match.group(1) if function_name_match else None
|
28 |
+
arguments = eval(f"dict{text.split(function_name)[1].strip()}")
|
29 |
+
function = getattr(skills, function_name) if function_name else None
|
30 |
+
|
31 |
+
if dry_run:
|
32 |
+
print(f"{function_name}(**{arguments})")
|
33 |
+
return "Dry run successful"
|
34 |
+
|
35 |
+
if function:
|
36 |
+
out = function(**arguments)
|
37 |
+
try:
|
38 |
+
if function:
|
39 |
+
out = function(**arguments)
|
40 |
+
except Exception as e:
|
41 |
+
out = str(e)
|
42 |
+
return out
|
43 |
+
|
44 |
+
|
45 |
+
def extract_func_args(text: str) -> tuple[str, dict]:
|
46 |
+
function_name_match = re.search(r"Call: (\w+)", text)
|
47 |
+
function_name = function_name_match.group(1) if function_name_match else None
|
48 |
+
if not function_name:
|
49 |
+
raise ValueError("No function name found in text")
|
50 |
+
arguments = eval(f"dict{text.split(function_name)[1].strip()}")
|
51 |
+
return function_name, arguments
|
52 |
+
|
53 |
+
|
54 |
+
config = Settings() # type: ignore
|
55 |
+
|
56 |
+
vehicle = VehicleStatus(
|
57 |
+
location="Rue Alphonse Weicker, Luxembourg",
|
58 |
+
location_coordinates=(49.505, 6.28111),
|
59 |
+
date="2025-05-06",
|
60 |
+
time="08:00:00",
|
61 |
+
destination="Rue Alphonse Weicker, Luxembourg"
|
62 |
+
)
|