Agent: add the corrective tools the toolbox was missing (#85 item 3) #122
@@ -2,7 +2,6 @@ package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gitea.stevedudenhoeffer.com/steve/majordomo/llm"
|
||||
|
||||
@@ -218,8 +217,9 @@ func (a *adapter) readJournal(ctx context.Context, args struct {
|
||||
ObjectID *int64 `json:"objectId" description:"optional bed to narrow to; omit for the whole garden"`
|
||||
From string `json:"from" description:"optional earliest observed date, YYYY-MM-DD"`
|
||||
To string `json:"to" description:"optional latest observed date, YYYY-MM-DD"`
|
||||
Offset int `json:"offset" description:"how many entries to skip; pass the count you've already seen to page when hasMore is true"`
|
||||
}) (any, error) {
|
||||
q := service.JournalQuery{ObjectID: args.ObjectID, Limit: 50}
|
||||
q := service.JournalQuery{ObjectID: args.ObjectID, Limit: 50, Offset: args.Offset}
|
||||
|
|
||||
if args.From != "" {
|
||||
q.From = &args.From
|
||||
}
|
||||
@@ -230,6 +230,7 @@ func (a *adapter) readJournal(ctx context.Context, args struct {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// hasMore is actionable now: re-call with offset += len(entries) to page.
|
||||
return map[string]any{"entries": entries, "hasMore": hasMore}, nil
|
||||
}
|
||||
|
||||
@@ -261,11 +262,9 @@ func (a *adapter) removePlanting(ctx context.Context, args struct {
|
||||
PlantingID int64 `json:"plantingId" description:"plop to remove (its id from describe_garden)"`
|
||||
Version int64 `json:"version" description:"the plop's current version (from describe_garden)"`
|
||||
}) (any, error) {
|
||||
// Soft-remove: set removed_at to today, mirroring clear_object, so the plop
|
||||
// stays in the planting history and the change is undoable.
|
||||
today := time.Now().UTC().Format("2006-01-02")
|
||||
return a.svc.UpdatePlanting(ctx, a.actor, args.PlantingID,
|
||||
service.PlantingPatch{SetRemovedAt: true, RemovedAt: &today}, args.Version)
|
||||
// Soft-remove via the service, so removed_at is stamped from the same
|
||||
// (injectable) clock clear_object uses rather than the adapter's wall clock.
|
||||
|
gitea-actions
commented
🟠 remove_planting stamps removed_at from wall-clock time.Now() instead of the service's injectable s.now(), diverging from the clear_object path it claims to mirror correctness, error-handling, maintainability · flagged by 3 models
🪰 Gadfly · advisory 🟠 **remove_planting stamps removed_at from wall-clock time.Now() instead of the service's injectable s.now(), diverging from the clear_object path it claims to mirror**
_correctness, error-handling, maintainability · flagged by 3 models_
- `internal/agent/tools.go:266` — `removePlanting` computes `today := time.Now().UTC().Format("2006-01-02")` from the **wall clock**, but every other date-stamping path in the service uses the injectable clock (`s.now().UTC().Format(dateLayout)`): `CreatePlanting` at `internal/service/plantings.go:104`, `ClearObjectPlantings`'s soft-remove path at `internal/service/ops.go:413`, and the fill path at `internal/service/ops.go:238`. `now` is an injectable `func() time.Time` on `Service` (`internal/s…
<sub>🪰 Gadfly · advisory</sub>
|
||||
return a.svc.RemovePlanting(ctx, a.actor, args.PlantingID, args.Version)
|
||||
}
|
||||
|
||||
func (a *adapter) listSeedLots(ctx context.Context, args struct {
|
||||
|
||||
@@ -178,6 +178,17 @@ func (s *Service) UpdatePlanting(ctx context.Context, actorID, plantingID int64,
|
||||
return updated, nil
|
||||
}
|
||||
|
||||
// RemovePlanting soft-removes a single plop — the one-plop counterpart to
|
||||
// ClearObject, used by the agent's remove_planting tool. It stamps removed_at
|
||||
// from the service clock (s.now()), same as ClearObject and the fill path, so the
|
||||
// removal date can't diverge by which caller set it; then delegates to
|
||||
// UpdatePlanting for the editor-role check, version guard and history record.
|
||||
func (s *Service) RemovePlanting(ctx context.Context, actorID, plantingID, version int64) (*domain.Planting, error) {
|
||||
today := s.now().UTC().Format(dateLayout)
|
||||
return s.UpdatePlanting(ctx, actorID, plantingID,
|
||||
PlantingPatch{SetRemovedAt: true, RemovedAt: &today}, version)
|
||||
}
|
||||
|
||||
// plantingEditSummary describes a plop edit for the history list. Soft-removal
|
||||
// ("clear bed", harvested) is the one edit worth naming specifically — it reads
|
||||
// as a removal to the person who did it, not as an edit.
|
||||
|
||||
Reference in New Issue
Block a user
🟠 read_journal exposes hasMore without offset parameter, making pagination impossible
correctness, maintainability · flagged by 3 models
internal/agent/tools.go:222— Theread_journaltool hardcodesLimit: 50and returnshasMoreto the LLM, but does not expose theoffsetparameter that the underlyingservice.JournalQuerysupports. Because the tool adapter omitsoffset, an LLM that seeshasMore: truehas no way to request the next page, making the pagination signal functionally useless. The tool should either accept anoffsetargument so the LLM can page, or not returnhasMoreat all.🪰 Gadfly · advisory