feat(api): include 7-day upcoming grooming context in routine suggestions
This commit is contained in:
parent
5d69a976c4
commit
1c457d62a3
3 changed files with 73 additions and 2 deletions
|
|
@ -327,6 +327,48 @@ def _build_grooming_context(
|
|||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def _build_upcoming_grooming_context(
|
||||
session: Session,
|
||||
start_date: date,
|
||||
days: int = 7,
|
||||
) -> str:
|
||||
entries = session.exec(
|
||||
select(GroomingSchedule).order_by(col(GroomingSchedule.day_of_week))
|
||||
).all()
|
||||
if not entries:
|
||||
return f"UPCOMING GROOMING (next {days} days): none\n"
|
||||
|
||||
entries_by_weekday: dict[int, list[GroomingSchedule]] = {}
|
||||
for entry in entries:
|
||||
entries_by_weekday.setdefault(entry.day_of_week, []).append(entry)
|
||||
|
||||
lines = [f"UPCOMING GROOMING (next {days} days):"]
|
||||
for offset in range(days):
|
||||
target_date = start_date + timedelta(days=offset)
|
||||
day_entries = entries_by_weekday.get(target_date.weekday(), [])
|
||||
if not day_entries:
|
||||
continue
|
||||
|
||||
if offset == 0:
|
||||
relative_label = "dzisiaj"
|
||||
elif offset == 1:
|
||||
relative_label = "jutro"
|
||||
else:
|
||||
relative_label = f"za {offset} dni"
|
||||
|
||||
day_name = _DAY_NAMES[target_date.weekday()]
|
||||
actions = ", ".join(
|
||||
f"{_ev(entry.action)}" + (f" ({entry.notes})" if entry.notes else "")
|
||||
for entry in day_entries
|
||||
)
|
||||
lines.append(f" {relative_label} ({target_date}, {day_name}): {actions}")
|
||||
|
||||
if len(lines) == 1:
|
||||
lines.append(" (no entries in this window)")
|
||||
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def _build_recent_history(session: Session) -> str:
|
||||
cutoff = date.today() - timedelta(days=7)
|
||||
routines = session.exec(
|
||||
|
|
@ -632,7 +674,11 @@ def suggest_routine(
|
|||
weekday = data.routine_date.weekday()
|
||||
skin_ctx = _build_skin_context(session)
|
||||
profile_ctx = build_user_profile_context(session, reference_date=data.routine_date)
|
||||
grooming_ctx = _build_grooming_context(session, weekdays=[weekday])
|
||||
upcoming_grooming_ctx = _build_upcoming_grooming_context(
|
||||
session,
|
||||
start_date=data.routine_date,
|
||||
days=7,
|
||||
)
|
||||
history_ctx = _build_recent_history(session)
|
||||
day_ctx = _build_day_context(data.leaving_home)
|
||||
available_products = _get_available_products(
|
||||
|
|
@ -675,7 +721,7 @@ def suggest_routine(
|
|||
f"na {data.routine_date} ({day_name}).\n\n"
|
||||
f"{mode_line}\n"
|
||||
"INPUT DATA:\n"
|
||||
f"{profile_ctx}\n{skin_ctx}\n{grooming_ctx}\n{history_ctx}\n{day_ctx}\n{products_ctx}\n{objectives_ctx}"
|
||||
f"{profile_ctx}\n{skin_ctx}\n{upcoming_grooming_ctx}\n{history_ctx}\n{day_ctx}\n{products_ctx}\n{objectives_ctx}"
|
||||
"\nNARZEDZIA:\n"
|
||||
"- Masz dostep do funkcji: get_product_details.\n"
|
||||
"- Wywoluj narzedzia tylko, gdy potrzebujesz detali do decyzji klinicznej/bezpieczenstwa.\n"
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ def test_suggest_routine(client, session):
|
|||
assert data["reasoning"] == "because"
|
||||
kwargs = mock_gemini.call_args.kwargs
|
||||
assert "USER PROFILE:" in kwargs["contents"]
|
||||
assert "UPCOMING GROOMING (next 7 days):" in kwargs["contents"]
|
||||
assert "function_handlers" in kwargs
|
||||
assert "get_product_details" in kwargs["function_handlers"]
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from innercontext.api.routines import (
|
|||
_build_products_context,
|
||||
_build_recent_history,
|
||||
_build_skin_context,
|
||||
_build_upcoming_grooming_context,
|
||||
_contains_minoxidil_text,
|
||||
_ev,
|
||||
_extract_active_names,
|
||||
|
|
@ -121,6 +122,29 @@ def test_build_grooming_context(session: Session):
|
|||
assert "(no entries for specified days)" in ctx2
|
||||
|
||||
|
||||
def test_build_upcoming_grooming_context(session: Session):
|
||||
assert (
|
||||
_build_upcoming_grooming_context(session, start_date=date(2026, 3, 2), days=7)
|
||||
== "UPCOMING GROOMING (next 7 days): none\n"
|
||||
)
|
||||
|
||||
monday = GroomingSchedule(
|
||||
id=uuid.uuid4(), day_of_week=0, action="shaving_oneblade", notes="Morning"
|
||||
)
|
||||
wednesday = GroomingSchedule(id=uuid.uuid4(), day_of_week=2, action="dermarolling")
|
||||
session.add_all([monday, wednesday])
|
||||
session.commit()
|
||||
|
||||
ctx = _build_upcoming_grooming_context(
|
||||
session,
|
||||
start_date=date(2026, 3, 2),
|
||||
days=7,
|
||||
)
|
||||
assert "UPCOMING GROOMING (next 7 days):" in ctx
|
||||
assert "dzisiaj (2026-03-02, poniedziałek): shaving_oneblade (Morning)" in ctx
|
||||
assert "za 2 dni (2026-03-04, środa): dermarolling" in ctx
|
||||
|
||||
|
||||
def test_build_recent_history(session: Session):
|
||||
assert _build_recent_history(session) == "RECENT ROUTINES: none\n"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue