Address #127 review: quote the garden name, validate rectangles, require plantId
Build image / build-and-push (push) Successful in 17s
Build image / build-and-push (push) Successful in 17s
- The plan-name line of the system prompt interpolates the garden's name with %q like the rest of the prompt: any editor can rename a garden, and a name with a newline in it must not read as an instruction. - fill_region refuses an inverted rectangle with its corners named, and a rectangle that misses the bed (or only touches its edge) is an error from the service rather than a successful fill of nothing. - remove_plantings requires plantId; omitted it would remove plant 0 and report success. - historyEntry.Undo → UndoOf (it holds the reverted change set's id). - remove_planting's description names list_plantings as an id source. - RemovePlanting takes the removal date itself; the dateless wrapper had no callers left. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
+13
-6
@@ -72,8 +72,8 @@ func NewToolbox(svc *service.Service, actorID int64, today string) *llm.Toolbox
|
||||
llm.DefineTool("remove_planting",
|
||||
"Remove ONE plop from a bed, leaving the rest — the single-plant answer to clear_object's "+
|
||||
"all-or-nothing. Soft-removes it (kept for planting history, undoable), like clearing a "+
|
||||
"bed does. Needs the plop's id and version from describe_garden. Use for \"pull the "+
|
||||
"basil out of the corner\".",
|
||||
"bed does. Needs the plop's id and version (describe_garden or list_plantings). Use "+
|
||||
"for \"pull the basil out of the corner\".",
|
||||
a.removePlanting),
|
||||
llm.DefineTool("remove_plantings",
|
||||
"Remove every plop of ONE plant from an object, leaving the other plants in it — \"take the "+
|
||||
@@ -261,6 +261,9 @@ func (a *adapter) fillRegion(ctx context.Context, args struct {
|
||||
}
|
||||
switch {
|
||||
case given == 4 && strings.TrimSpace(args.Region) == "":
|
||||
if !(*args.X0CM < *args.X1CM && *args.Y0CM < *args.Y1CM) {
|
||||
return nil, fmt.Errorf("%w: x0Cm must be west of x1Cm and y0Cm north of y1Cm (-y is north)", domain.ErrInvalidInput)
|
||||
}
|
||||
spec.Region = service.Region{MinX: *args.X0CM, MinY: *args.Y0CM, MaxX: *args.X1CM, MaxY: *args.Y1CM}
|
||||
case given == 0 && strings.TrimSpace(args.Region) != "":
|
||||
// the named region
|
||||
@@ -352,6 +355,10 @@ func (a *adapter) removePlantings(ctx context.Context, args struct {
|
||||
ObjectID int64 `json:"objectId" description:"object to remove the plant from"`
|
||||
PlantID int64 `json:"plantId" description:"the plant to remove every plop of (from describe_garden)"`
|
||||
}) (any, error) {
|
||||
if args.PlantID == 0 {
|
||||
// Left out, it would "remove" plant 0 — nothing — and report success.
|
||||
return nil, fmt.Errorf("%w: plantId is required — say which plant to remove, or use clear_object for all of them", domain.ErrInvalidInput)
|
||||
}
|
||||
n, err := a.svc.ClearPlantings(ctx, a.actor, args.ObjectID,
|
||||
service.ClearOptions{PlantID: &args.PlantID, RemovedAt: a.day("")})
|
||||
if err != nil {
|
||||
@@ -392,8 +399,8 @@ type historyEntry struct {
|
||||
Summary string `json:"summary"`
|
||||
Changes string `json:"changes"`
|
||||
Undone bool `json:"undone,omitempty"`
|
||||
// Undo is set when this entry is itself an undo of an earlier one.
|
||||
Undo *int64 `json:"undoOf,omitempty"`
|
||||
// UndoOf is the earlier entry this one reverted, when it is itself an undo.
|
||||
UndoOf *int64 `json:"undoOf,omitempty"`
|
||||
}
|
||||
|
||||
func (a *adapter) readHistory(ctx context.Context, args struct {
|
||||
@@ -414,7 +421,7 @@ func (a *adapter) readHistory(ctx context.Context, args struct {
|
||||
entries = append(entries, historyEntry{
|
||||
ID: cs.ID, When: cs.CreatedAt, Source: cs.Source, Who: cs.ActorName,
|
||||
Summary: cs.Summary, Changes: describeCounts(cs.Counts),
|
||||
Undone: cs.RevertedByID != nil, Undo: cs.RevertsID,
|
||||
Undone: cs.RevertedByID != nil, UndoOf: cs.RevertsID,
|
||||
})
|
||||
}
|
||||
return map[string]any{"entries": entries, "hasMore": hasMore}, nil
|
||||
@@ -467,7 +474,7 @@ func (a *adapter) removePlanting(ctx context.Context, args struct {
|
||||
}) (any, error) {
|
||||
// Soft-remove via the service, dated the gardener's local day like every
|
||||
// other tool here (the service clock's UTC day when that isn't known).
|
||||
return a.svc.RemovePlantingOn(ctx, a.actor, args.PlantingID, args.Version, a.day(""))
|
||||
return a.svc.RemovePlanting(ctx, a.actor, args.PlantingID, args.Version, a.day(""))
|
||||
}
|
||||
|
||||
func (a *adapter) listSeedLots(ctx context.Context, args struct {
|
||||
|
||||
Reference in New Issue
Block a user