Agent: catalog and garden tools, and a ready date on every describe group
- update_seed_lot / delete_seed_lot: correct or drop a recorded purchase
("it was three packets, not two"); the plant a lot is for stays fixed.
- delete_plant: remove a duplicate from the user's catalog. The service
already refuses while plantings (past seasons included) or a lot reference
it; the tool turns that sentinel into words the model can pass on, and
tells it not to clear those references to get its way.
- create_garden: a new place, with the service's defaults; the prompt says a
plan is still a copy_garden.
- describe_garden groups carry readyAround — planting date plus days to
maturity for the plops still in the ground — so "what can I pick this
week?" is a lookup rather than arithmetic the model got wrong live.
Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"log/slog"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.stevedudenhoeffer.com/steve/pansy/internal/domain"
|
||||
)
|
||||
@@ -614,6 +615,11 @@ type DescribeGroup struct {
|
||||
// DaysToMaturity is the plant's, when the catalog knows it — with PlantedAt,
|
||||
// enough to say when the harvest is due.
|
||||
DaysToMaturity *int `json:"daysToMaturity,omitempty"`
|
||||
// ReadyAround is that arithmetic done: planting date plus days to maturity
|
||||
// for the plops still in the ground, as one date or "first…last". Absent
|
||||
// when the catalog has no days for the plant or nothing is dated. The
|
||||
// model was asked "what can I pick this week?" and got the sums wrong.
|
||||
ReadyAround string `json:"readyAround,omitempty"`
|
||||
// Removed counts the plops in the group that have been pulled, and RemovedAt
|
||||
// is when ("first…last" when they differ). Only a season view lists pulled
|
||||
// plops, so both are absent from a describe of what is growing now.
|
||||
@@ -746,6 +752,15 @@ func describeGroups(o *domain.GardenObject, plops []domain.Planting, plantByID m
|
||||
DaysToMaturity: plant.DaysToMaturity,
|
||||
RemovedAt: dateRangeOf(members, func(pl domain.Planting) *string { return pl.RemovedAt }),
|
||||
}
|
||||
if plant.DaysToMaturity != nil {
|
||||
days := *plant.DaysToMaturity
|
||||
g.ReadyAround = dateRangeOf(members, func(pl domain.Planting) *string {
|
||||
if pl.RemovedAt != nil {
|
||||
return nil // pulled already; its harvest is not ahead of us
|
||||
}
|
||||
return readyDate(pl.PlantedAt, days)
|
||||
})
|
||||
}
|
||||
for _, pl := range members {
|
||||
g.Plants += effectiveCount(pl)
|
||||
if pl.RemovedAt != nil {
|
||||
@@ -778,6 +793,20 @@ func describePlanting(pl domain.Planting, plantName string) DescribePlanting {
|
||||
return d
|
||||
}
|
||||
|
||||
// readyDate is plantedAt plus days to maturity, or nil when the plop is undated
|
||||
// (or its date is not one the store should have accepted).
|
||||
func readyDate(plantedAt *string, days int) *string {
|
||||
if plantedAt == nil || *plantedAt == "" {
|
||||
return nil
|
||||
}
|
||||
t, err := time.Parse(dateLayout, *plantedAt)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
d := t.AddDate(0, 0, days).Format(dateLayout)
|
||||
return &d
|
||||
}
|
||||
|
||||
// effectiveCount is the plant count a plop stands for: its explicit count, else
|
||||
// the one derived from its area and the plant's spacing.
|
||||
func effectiveCount(pl domain.Planting) int {
|
||||
|
||||
Reference in New Issue
Block a user