Address seed-packet review: 413 mapping, deadline, rollback, dedup
Build image / build-and-push (push) Successful in 6s
Build image / build-and-push (push) Successful in 6s
Gadfly findings on #94, the real ones: - scanSeedPacket extends only the READ deadline; a slow upload + a live vision call runs past the server's absolute 30s WriteTimeout and the successful response is silently dropped (the #78 failure mode). Extend the write deadline too (scanWriteTimeout). - An oversized upload tripping MaxBytesReader was mapped to 400; it's 413. Detect *http.MaxBytesError and report IMAGE_TOO_LARGE. - Split imagenorm error mapping: ErrTooLarge->413, ErrUnsupported->400, genuine read/encode faults (and a failed file.Open)->500, not 400. - CreateFromPacket discarded the plant it created when the lot then failed, contradicting its own doc. Roll the new plant back instead so the confirm is all-or-nothing (a fresh plant has no lots/plantings, so the delete is safe; log-and-continue on cleanup failure). - Dedup: packetLotRequest and seedLotCreateRequest shared every lot field. Extract a seedLotFields base both use. validCategory now reuses plantCategories. EffectiveConfig resolves agent+vision from one settings-row read instead of two. - capabilities swallowed an EffectiveVision error silently; log it. - vision test hand-copied Extract's body (drift risk). Split generate() out of Extract so the hermetic test drives the real request builder. Tests: rollback-on-lot-failure (service), oversized->413 (api). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01H3zbym8Doka2d7D48maSgZ
This commit is contained in:
@@ -100,6 +100,13 @@ func (s *Service) EffectiveAgent(ctx context.Context) (EffectiveAgent, error) {
|
||||
if err != nil {
|
||||
return EffectiveAgent{}, err
|
||||
}
|
||||
return s.agentOver(st), nil
|
||||
}
|
||||
|
||||
// agentOver layers a settings row over the env-derived agent defaults. Split out
|
||||
// so EffectiveConfig can resolve agent AND vision from a single row read instead
|
||||
// of fetching the same one-row table twice.
|
||||
func (s *Service) agentOver(st *domain.InstanceSettings) EffectiveAgent {
|
||||
eff := EffectiveAgent{
|
||||
Model: s.cfg.Agent.Model,
|
||||
Enabled: s.cfg.Agent.Enabled,
|
||||
@@ -111,7 +118,7 @@ func (s *Service) EffectiveAgent(ctx context.Context) (EffectiveAgent, error) {
|
||||
if st.AgentEnabled != nil {
|
||||
eff.Enabled = *st.AgentEnabled
|
||||
}
|
||||
return eff, nil
|
||||
return eff
|
||||
}
|
||||
|
||||
// EffectiveVision resolves the vision configuration in force for seed-packet
|
||||
@@ -133,6 +140,12 @@ func (s *Service) EffectiveVision(ctx context.Context) (EffectiveVision, error)
|
||||
if err != nil {
|
||||
return EffectiveVision{}, err
|
||||
}
|
||||
return s.visionOver(st), nil
|
||||
}
|
||||
|
||||
// visionOver layers a settings row over the env-derived vision defaults. See
|
||||
// agentOver for why this is split from EffectiveVision.
|
||||
func (s *Service) visionOver(st *domain.InstanceSettings) EffectiveVision {
|
||||
eff := EffectiveVision{
|
||||
Model: s.cfg.Agent.VisionModel,
|
||||
APIKey: s.cfg.Agent.OllamaCloudAPIKey,
|
||||
@@ -140,5 +153,16 @@ func (s *Service) EffectiveVision(ctx context.Context) (EffectiveVision, error)
|
||||
if st.VisionModel != "" {
|
||||
eff.Model = st.VisionModel
|
||||
}
|
||||
return eff, nil
|
||||
return eff
|
||||
}
|
||||
|
||||
// EffectiveConfig resolves the agent AND vision configuration from ONE settings
|
||||
// read, for callers (the settings view) that need both — the single-row table
|
||||
// would otherwise be fetched twice for one response.
|
||||
func (s *Service) EffectiveConfig(ctx context.Context) (EffectiveAgent, EffectiveVision, error) {
|
||||
st, err := s.store.GetInstanceSettings(ctx)
|
||||
if err != nil {
|
||||
return EffectiveAgent{}, EffectiveVision{}, err
|
||||
}
|
||||
return s.agentOver(st), s.visionOver(st), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user