mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
Add new relative time skills for ' ago' and 'last ' (#927)
### Motivation and Context The change enables the planner to make use of time references like "last wednesday" or "three days ago" which currently cause issues. This enables better use of SequentialPlanner when servicing user intent. Issue: https://github.com/microsoft/semantic-kernel/issues/922 ### Description This adds two new functions to the core TimeSkill class in both .net and python. 1. DaysAgo(str days) - takes an argument representing a number of days and offsets it from the current date to return the resultant date as the answer. 2. LastMatchingDay(str dayName) - takes the name of a day of the week and works backwards from yesterday to give it the first matching date of that day (e.g. "last wednesday"). Currently it only works with English day names, and this is reflected in the prompt description. Simple unit tests are added for each function. Co-authored-by: Devis Lucato <[email protected]>
This commit is contained in:
@@ -24,6 +24,8 @@ class TimeSkill:
|
||||
{{time.dayOfWeek}} => Sunday
|
||||
{{time.hour}} => 9 PM
|
||||
{{time.hourNumber}} => 21
|
||||
{{time.days_ago $days}} => Sunday, 7 May, 2023
|
||||
{{time.last_matching_day $dayName}} => Sunday, 7 May, 2023
|
||||
{{time.minute}} => 15
|
||||
{{time.minutes}} => 15
|
||||
{{time.second}} => 7
|
||||
@@ -174,6 +176,50 @@ class TimeSkill:
|
||||
now = datetime.datetime.now()
|
||||
return now.strftime("%M")
|
||||
|
||||
@sk_function(
|
||||
description="Get the date of offset from today by a provided number of days"
|
||||
)
|
||||
def days_ago(self, days: str) -> str:
|
||||
"""
|
||||
Get the date a provided number of days in the past
|
||||
|
||||
params:
|
||||
days: The number of days to offset from today
|
||||
returns:
|
||||
The date of the offset day.
|
||||
|
||||
Example:
|
||||
SKContext["input"] = "3"
|
||||
{{time.days_ago $input}} => Sunday, 7 May, 2023
|
||||
"""
|
||||
d = datetime.date.today() - datetime.timedelta(days=int(days))
|
||||
return d.strftime("%A, %d %B, %Y")
|
||||
|
||||
@sk_function(
|
||||
description="""Get the date of the last day matching the supplied week day name in English.
|
||||
Example: Che giorno era 'Martedi' scorso -> dateMatchingLastDayName 'Tuesday' => Tuesday,
|
||||
16 May, 2023"""
|
||||
)
|
||||
def date_matching_last_day_name(self, day_name: str) -> str:
|
||||
"""
|
||||
Get the date of the last day matching the supplied day name
|
||||
|
||||
params:
|
||||
day_name: The day name to match with.
|
||||
returns:
|
||||
The date of the matching day.
|
||||
|
||||
Example:
|
||||
SKContext["input"] = "Sunday"
|
||||
{{time.date_matching_last_day_name $input}} => Sunday, 7 May, 2023
|
||||
"""
|
||||
d = datetime.date.today()
|
||||
for i in range(1, 8):
|
||||
d = d - datetime.timedelta(days=1)
|
||||
if d.strftime("%A") == day_name:
|
||||
return d.strftime("%A, %d %B, %Y")
|
||||
raise ValueError("day_name is not recognized")
|
||||
|
||||
@sk_function(description="Get the seconds on the current minute")
|
||||
def second(self) -> str:
|
||||
"""
|
||||
|
||||
@@ -5,6 +5,7 @@ import semantic_kernel as sk
|
||||
from semantic_kernel.core_skills.time_skill import TimeSkill
|
||||
|
||||
test_mock_now = datetime.datetime(2031, 1, 12, 12, 24, 56, tzinfo=datetime.timezone.utc)
|
||||
test_mock_today = datetime.date(2031, 1, 12)
|
||||
|
||||
|
||||
def test_can_be_instantiated():
|
||||
@@ -33,6 +34,22 @@ def test_now():
|
||||
assert skill.now() == "Sunday, January 12, 2031 12:24 PM"
|
||||
|
||||
|
||||
def test_days_ago():
|
||||
skill = TimeSkill()
|
||||
|
||||
with mock.patch("datetime.date", wraps=datetime.date) as dt:
|
||||
dt.today.return_value = test_mock_today
|
||||
assert skill.days_ago(1) == "Saturday, 11 January, 2031"
|
||||
|
||||
|
||||
def test_date_matching_last_day_name():
|
||||
skill = TimeSkill()
|
||||
|
||||
with mock.patch("datetime.date", wraps=datetime.date) as dt:
|
||||
dt.today.return_value = test_mock_today
|
||||
assert skill.date_matching_last_day_name("Friday") == "Friday, 10 January, 2031"
|
||||
|
||||
|
||||
def test_utc_now():
|
||||
skill = TimeSkill()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user