Skip to content

Commit

Permalink
some improvements to embeddings
Browse files Browse the repository at this point in the history
- made calendar events and shopping list themselves be part of the document
- made the media player return the list of devices (but not their states) as part of the document
  • Loading branch information
JohnTheNerd committed Jun 14, 2024
1 parent 5fd3e2c commit 5a86544
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 39 deletions.
59 changes: 33 additions & 26 deletions plugins/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,10 @@ def __init__(self, config, utils):
self.example_count = config.get('example_count', 1)
self.local_tz = tzlocal.get_localzone()
self.calendars = {}
self.calendar_events = []
self.documents = []

def update(self):
# for now, let's only give one category for the calendar events
title = "All calendar events (meetings, appointments, tasks) for the next week."
self.documents = [
{
"title": title,
"embedding": self.utils['get_embedding'](title)
}
]
for calendar in self.calendar_configuration:
caldav_url = calendar.get('url')
username = calendar.get('username')
Expand All @@ -35,12 +28,8 @@ def update(self):
calendar_object = icalendar.Calendar.from_ical(response.text)
self.calendars[caldav_url] = calendar_object

def get_documents(self):
return self.documents

def get_llm_prompt_addition(self, selected_categories, user_prompt):
examples = []
calendar_events = []
self.calendar_events = []
title = "All calendar events (meetings, appointments, tasks) for the next week:"
for calendar in self.calendars.keys():
calendar_obj = self.calendars[calendar]
# localize the date time
Expand All @@ -55,27 +44,47 @@ def get_llm_prompt_addition(self, selected_categories, user_prompt):
event_start = component.get("DTSTART").dt.astimezone(self.local_tz)
event_end = component.get("DTEND").dt.astimezone(self.local_tz)
if start <= event_start < end:
calendar_events.append(component)
self.calendar_events.append(component)

if calendar_events:
llm_prompt = "Calendar events for the next week:\n"
for event in calendar_events:
if self.calendar_events:
self.calendar_events.sort(key=lambda x: x.get('DTSTART').dt.astimezone(self.local_tz))
llm_prompt = f"{title}\n"
for event in self.calendar_events:
event_start = event.get("DTSTART").dt.astimezone(self.local_tz)
event_end = event.get("DTEND").dt.astimezone(self.local_tz)
event_day_of_week = event_start.strftime("%A")
event_start_formatted = event_start.strftime('%I:%M %p')
event_end_formatted = event_end.strftime('%I:%M %p')
event_start_date_formatted = event_start.strftime('%B %-d')
event_summary = event.get('SUMMARY')
if not event_summary:
event_summary = event.get('TITLE')
llm_prompt = llm_prompt + '\n- ' + (f"{event_summary} at {event_start_formatted} on {event_day_of_week}, {event_end_formatted}")
llm_prompt = llm_prompt + '\n- ' + (f"{event_summary} between {event_start_formatted} and {event_end_formatted} on {event_day_of_week}, {event_start_date_formatted}")

else:
llm_prompt = f"{title}\n\nThere are no calendar events in the next week."

self.llm_prompt = llm_prompt
self.documents = [
{
"title": self.llm_prompt,
"embedding": self.utils['get_embedding'](self.llm_prompt)
}
]

def get_documents(self):
return self.documents

def get_llm_prompt_addition(self, selected_categories, user_prompt):
examples = []
if self.calendar_events:
now = datetime.now(self.local_tz)
# we can only reliably create three examples, so let's cap there for now
# also, why would you want more than 3 calendar examples anyway?
number_of_samples = min(self.example_count, 3)

days_with_events = {}
for event in calendar_events:
for event in self.calendar_events:
event_start = event.get("DTSTART").dt.astimezone(self.local_tz)
event_day_of_week = event_start.strftime("%A")
event_start_formatted = event_start.strftime('%I:%M %p')
Expand All @@ -88,12 +97,12 @@ def get_llm_prompt_addition(self, selected_categories, user_prompt):

days_without_events = []
days_excluding_today = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
days_excluding_today.remove(datetime.now().strftime("%A"))
days_excluding_today.remove(now.strftime("%A"))
for day in days_excluding_today:
if day not in days_with_events:
days_without_events.append(day)

closest_event = min(calendar_events, key=lambda x: abs((x.get("DTSTART").dt.astimezone(self.local_tz) - now).total_seconds()))
closest_event = min(self.calendar_events, key=lambda x: abs((x.get("DTSTART").dt.astimezone(self.local_tz) - now).total_seconds()))

closest_event_start = closest_event.get("DTSTART").dt.astimezone(self.local_tz)
closest_event_start_formatted = closest_event_start.strftime('%I:%M %p')
Expand All @@ -106,7 +115,7 @@ def get_llm_prompt_addition(self, selected_categories, user_prompt):
examples.append(
(
f"What's my schedule for {day_with_event}?",
f"You have {schedule} on {day_with_event}, {closest_event_start.strftime('%B %d')}."
f"You have {schedule} on {day_with_event}, {closest_event_start.strftime('%B %-d')}."
)
)

Expand Down Expand Up @@ -137,10 +146,8 @@ def get_llm_prompt_addition(self, selected_categories, user_prompt):
)

examples = random.sample(examples, number_of_samples)
else:
llm_prompt = "There are no calendar events in the next week."

return {
"prompt": llm_prompt,
"prompt": self.llm_prompt,
"examples": examples
}
38 changes: 25 additions & 13 deletions plugins/homeassistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def __init__(self, config, utils):
self.media_player_enabled = config.get('media_player_enabled', False)
self.person_enabled = config.get('person_enabled', False)
self.color_loop_enabled = config.get('color_loop_enabled', False)
self.shopping_list = ""
self.areas_template = """
{%- for area in areas() %}
{
Expand Down Expand Up @@ -95,6 +96,11 @@ def __init__(self, config, utils):
{%- if is_state(player.entity_id, 'playing') %}
{{ state_attr(player.entity_id, 'friendly_name') }} is playing {{ state_attr(player.entity_id, 'media_title') }} by {{ state_attr(player.entity_id, 'media_artist') }}.
{%- endif %}
{%- endfor %}"""
self.media_player_title_template = """
States of all media players (songs, movies, shows, videos) in the household
{%- for player in states.media_player %}
- {{ state_attr(player.entity_id, 'friendly_name') }}
{%- endfor %}"""
self.laundry_template = """
{%- macro time_diff_in_words(timediff) %}
Expand Down Expand Up @@ -213,11 +219,14 @@ def update(self):
current_initial_values.append(area)

if self.shopping_list_enabled:
shopping_list_title = 'Shopping list for the entire household'
self.shopping_list = self.get_shopping_list()
shopping_list_text = 'Shopping list for the entire household:\n'
for shopping_list_item in self.shopping_list:
shopping_list_text = shopping_list_text + f"- {shopping_list_item['name']}\n"
current_initial_values.append({
"type": "shopping_list",
"title": shopping_list_title,
"embedding": self.utils['get_embedding'](shopping_list_title)
"title": shopping_list_text,
"embedding": self.utils['get_embedding'](shopping_list_text)
})

if self.laundry_enabled:
Expand All @@ -229,12 +238,16 @@ def update(self):
})

if self.media_player_enabled:
media_player_title = 'States of all media players (songs, movies, shows, videos) in the household'
current_initial_values.append({
"type": "media_player",
"title": media_player_title,
"embedding": self.utils['get_embedding'](media_player_title)
})
summary = requests.post(f'{self.base_url}/api/template',
json={"template": self.media_player_title_template},
headers={"Authorization": f"Bearer {self.access_token}"},
timeout=10).text
if summary.strip():
current_initial_values.append({
"type": "media_player",
"title": summary.strip(),
"embedding": self.utils['get_embedding'](summary.strip())
})

if self.person_enabled:
person_title = 'All people in HomeAssistant and whether if any of them are home'
Expand Down Expand Up @@ -286,9 +299,8 @@ def get_llm_prompt_addition(self, document, user_prompt):
llm_prompt = ""
match document['type']:
case "shopping_list":
shopping_list = self.get_shopping_list()
llm_prompt = llm_prompt + 'Shopping list contents:\n'
for shopping_list_item in shopping_list:
for shopping_list_item in self.shopping_list:
llm_prompt = llm_prompt + f"- {shopping_list_item['name']}\n"
examples.append(
(
Expand All @@ -297,8 +309,8 @@ def get_llm_prompt_addition(self, document, user_prompt):
)
)
sample_shopping_list_item = 'chicken'
if shopping_list:
sample_shopping_list_item = random.choice(shopping_list)['name']
if self.shopping_list:
sample_shopping_list_item = random.choice(self.shopping_list)['name']
examples.append(
(
'Remove ' + sample_shopping_list_item + ' from the shopping list.',
Expand Down

0 comments on commit 5a86544

Please sign in to comment.