feat(routines): add minimize_products option for batch suggestions
This commit is contained in:
parent
40f9a353bb
commit
609995732b
4 changed files with 26 additions and 4 deletions
|
|
@ -97,6 +97,7 @@ class SuggestBatchRequest(SQLModel):
|
||||||
to_date: date
|
to_date: date
|
||||||
notes: Optional[str] = None
|
notes: Optional[str] = None
|
||||||
include_minoxidil_beard: bool = False
|
include_minoxidil_beard: bool = False
|
||||||
|
minimize_products: Optional[bool] = None
|
||||||
|
|
||||||
|
|
||||||
class DayPlan(SQLModel):
|
class DayPlan(SQLModel):
|
||||||
|
|
@ -273,7 +274,9 @@ def _build_products_context(session: Session, time_filter: Optional[str] = None)
|
||||||
product_ids = [p.id for p in products]
|
product_ids = [p.id for p in products]
|
||||||
inventory_rows = (
|
inventory_rows = (
|
||||||
session.exec(
|
session.exec(
|
||||||
select(ProductInventory).where(col(ProductInventory.product_id).in_(product_ids))
|
select(ProductInventory).where(
|
||||||
|
col(ProductInventory.product_id).in_(product_ids)
|
||||||
|
)
|
||||||
).all()
|
).all()
|
||||||
if product_ids
|
if product_ids
|
||||||
else []
|
else []
|
||||||
|
|
@ -291,7 +294,7 @@ def _build_products_context(session: Session, time_filter: Optional[str] = None)
|
||||||
p.inventory = inv_by_product.get(p.id, [])
|
p.inventory = inv_by_product.get(p.id, [])
|
||||||
ctx = p.to_llm_context()
|
ctx = p.to_llm_context()
|
||||||
entry = (
|
entry = (
|
||||||
f" - id={ctx['id']} name=\"{ctx['name']}\" brand=\"{ctx['brand']}\""
|
f' - id={ctx["id"]} name="{ctx["name"]}" brand="{ctx["brand"]}"'
|
||||||
f" category={ctx.get('category', '')} recommended_time={ctx.get('recommended_time', '')}"
|
f" category={ctx.get('category', '')} recommended_time={ctx.get('recommended_time', '')}"
|
||||||
f" targets={ctx.get('targets', [])}"
|
f" targets={ctx.get('targets', [])}"
|
||||||
)
|
)
|
||||||
|
|
@ -552,12 +555,17 @@ def suggest_batch(
|
||||||
dates_str = "\n".join(date_range_lines)
|
dates_str = "\n".join(date_range_lines)
|
||||||
|
|
||||||
notes_line = f"\nKONTEKST OD UŻYTKOWNIKA: {data.notes}\n" if data.notes else ""
|
notes_line = f"\nKONTEKST OD UŻYTKOWNIKA: {data.notes}\n" if data.notes else ""
|
||||||
|
minimize_line = (
|
||||||
|
"\nOGRANICZENIA:\n - Minimalizuj liczbę unikalnych produktów (używaj tych samych produktów wielokrotnie)\n"
|
||||||
|
if data.minimize_products
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
|
||||||
prompt = (
|
prompt = (
|
||||||
f"Zaproponuj plan pielęgnacji AM + PM dla każdego dnia z zakresu:\n{dates_str}\n\n"
|
f"Zaproponuj plan pielęgnacji AM + PM dla każdego dnia z zakresu:\n{dates_str}\n\n"
|
||||||
"DANE WEJŚCIOWE:\n"
|
"DANE WEJŚCIOWE:\n"
|
||||||
f"{skin_ctx}\n{grooming_ctx}\n{history_ctx}\n{products_ctx}\n{objectives_ctx}"
|
f"{skin_ctx}\n{grooming_ctx}\n{history_ctx}\n{products_ctx}\n{objectives_ctx}"
|
||||||
f"{notes_line}\n"
|
f"{notes_line}{minimize_line}"
|
||||||
"\nZwróć JSON zgodny ze schematem."
|
"\nZwróć JSON zgodny ze schematem."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,7 @@ export const suggestBatch = (body: {
|
||||||
to_date: string;
|
to_date: string;
|
||||||
notes?: string;
|
notes?: string;
|
||||||
include_minoxidil_beard?: boolean;
|
include_minoxidil_beard?: boolean;
|
||||||
|
minimize_products?: boolean;
|
||||||
}): Promise<BatchSuggestion> => api.post('/routines/suggest-batch', body);
|
}): Promise<BatchSuggestion> => api.post('/routines/suggest-batch', body);
|
||||||
|
|
||||||
export const getGroomingSchedule = (): Promise<GroomingSchedule[]> =>
|
export const getGroomingSchedule = (): Promise<GroomingSchedule[]> =>
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ export const actions: Actions = {
|
||||||
const to_date = form.get('to_date') as string;
|
const to_date = form.get('to_date') as string;
|
||||||
const notes = (form.get('notes') as string) || undefined;
|
const notes = (form.get('notes') as string) || undefined;
|
||||||
const include_minoxidil_beard = form.get('include_minoxidil_beard') === 'on';
|
const include_minoxidil_beard = form.get('include_minoxidil_beard') === 'on';
|
||||||
|
const minimize_products = form.get('minimize_products') === 'on';
|
||||||
|
|
||||||
if (!from_date || !to_date) {
|
if (!from_date || !to_date) {
|
||||||
return fail(400, { error: 'Daty początkowa i końcowa są wymagane.' });
|
return fail(400, { error: 'Daty początkowa i końcowa są wymagane.' });
|
||||||
|
|
@ -54,7 +55,7 @@ export const actions: Actions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const batch = await suggestBatch({ from_date, to_date, notes, include_minoxidil_beard });
|
const batch = await suggestBatch({ from_date, to_date, notes, include_minoxidil_beard, minimize_products });
|
||||||
return { batch, from_date, to_date };
|
return { batch, from_date, to_date };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return fail(502, { error: (e as Error).message });
|
return fail(502, { error: (e as Error).message });
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,18 @@
|
||||||
<p class="text-xs text-muted-foreground">{m["suggest_minoxidilToggleHint"]()}</p>
|
<p class="text-xs text-muted-foreground">{m["suggest_minoxidilToggleHint"]()}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-start gap-3 rounded-md border border-border px-3 py-2">
|
||||||
|
<input
|
||||||
|
id="batch_minimize_products"
|
||||||
|
name="minimize_products"
|
||||||
|
type="checkbox"
|
||||||
|
class="mt-0.5 h-4 w-4 rounded border-input"
|
||||||
|
/>
|
||||||
|
<div class="space-y-0.5">
|
||||||
|
<Label for="batch_minimize_products" class="font-medium">Minimalizuj produkty</Label>
|
||||||
|
<p class="text-xs text-muted-foreground">Ogranicz liczbę różnych produktów</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button type="submit" disabled={loadingBatch} class="w-full">
|
<Button type="submit" disabled={loadingBatch} class="w-full">
|
||||||
{#if loadingBatch}
|
{#if loadingBatch}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue