diff --git a/internal/agent/dsh.go b/internal/agent/dsh.go index 9173e158..6e82bbe3 100644 --- a/internal/agent/dsh.go +++ b/internal/agent/dsh.go @@ -114,10 +114,11 @@ func dsh(home string) *Agent { Get: func() string { return dshGetEffort(dir) }, Set: func(v string) error { return dshSetEffort(dir, v) }, Options: func(cur map[string]string) []Option { + // a model through magpie that lists no levels has none in + // dsh (its route gives it no reasoningEfforts), so none is + // offered: dsh's own four were, and each was turned away if ref, ok := strings.CutPrefix(cur["model"], magpieID+"/"); ok && len(dshProfiles(dir)) > 0 { - if levels := dshLevels(ref); len(levels) > 0 { - return static(levels...) - } + return static(dshLevels(ref)...) } return static(dshEfforts...) }, @@ -1125,6 +1126,9 @@ func dshSetEffort(dir, v string) error { if viaGateway { levels = dshLevels(ref) } + if v != "" && len(levels) == 0 { + return fmt.Errorf("DeepSeek Harness has no thinking levels for %s: magpie knows of none the model takes", ref) + } if v != "" && !contains(levels, v) { return fmt.Errorf("DeepSeek Harness takes an effort of %s for this model, not %q", strings.Join(levels, ", "), v) } diff --git a/internal/agent/effort_test.go b/internal/agent/effort_test.go index 7674d0ea..a0270b90 100644 --- a/internal/agent/effort_test.go +++ b/internal/agent/effort_test.go @@ -151,6 +151,49 @@ func TestCommandCodeEffort(t *testing.T) { } } +// #473: a model through magpie listing no levels (LongCat-2.5-Preview) had +// dsh's own off, low, high and max offered on the Agents page, and each was +// turned away with "takes an effort of for this model". It has none in dsh: +// none is offered, and one asked for says so. +func TestDshEffortModelWithoutLevels(t *testing.T) { + home := effortHome(t) + if err := catalog.SaveLive("deepseek", "https://api.deepseek.com/v1", []catalog.Model{ + {ID: "pro", Name: "pro", Efforts: []string{"none", "low", "high", "max"}}, + {ID: "plain", Name: "plain"}, + }); err != nil { + t.Fatal(err) + } + patch := filepath.Join(home, ".dsh", "profiles", "web", "cordis.patch.yml") + writeFile(t, patch, "[]\n") + a := dsh(home) + f := a.Field("effort") + if err := a.Field("model").Set("magpie/deepseek/plain"); err != nil { + t.Fatal(err) + } + cur := map[string]string{"model": "magpie/deepseek/plain"} + if got := f.Options(cur); len(got) != 0 { + t.Fatalf("offered %+v for a model with no levels", got) + } + err := f.Set("low") + if err == nil || strings.Contains(err.Error(), "of for") || !strings.Contains(err.Error(), "deepseek/plain") { + t.Fatalf("low: %v", err) + } + if err := f.Set(""); err != nil || f.Get() != "" { + t.Fatalf("default: %v %q", err, f.Get()) + } + // every level offered for any model is one dsh takes + for _, m := range []string{"magpie/deepseek/pro", "magpie/deepseek/plain", "deepseek-v4-pro"} { + if err := a.Field("model").Set(m); err != nil { + t.Fatal(err) + } + for _, o := range f.Options(map[string]string{"model": m}) { + if err := f.Set(o.Value); err != nil { + t.Fatalf("%s offered %q and turned it away: %v", m, o.Value, err) + } + } + } +} + func TestDshEffort(t *testing.T) { home := effortHome(t) if err := catalog.SaveLive("deepseek", "https://api.deepseek.com/v1", []catalog.Model{