diff --git a/cmd/logos/memory.go b/cmd/logos/memory.go index f25b661..b6579f3 100644 --- a/cmd/logos/memory.go +++ b/cmd/logos/memory.go @@ -103,9 +103,14 @@ func memoryCmd(args []string) error { } var local *provider.Provider var embed string - if rt == nil { + // LOGOS_EMBED=off is asked here as `logos index` and search ask it: the + // hook relies on it to keep the work local and fast, and the router's + // T0 choice alone embedded the fact anyway whenever a runtime was up. + _, embedOn := embedModel() + switch { + case rt == nil: fmt.Fprintln(os.Stderr, "· no model runtime — storing without embedding; duplicates match by exact text") - } else { + case embedOn: local = rt.Local() embed, _ = rt.Model(router.T0) } diff --git a/cmd/logos/memory_test.go b/cmd/logos/memory_test.go index 4ac32fa..06e0140 100644 --- a/cmd/logos/memory_test.go +++ b/cmd/logos/memory_test.go @@ -48,3 +48,21 @@ func TestMemoryAddStoresAFactWithNoModelRuntimeRunning(t *testing.T) { t.Errorf("the fact was not stored:\n%s", out) } } + +// #235: LOGOS_EMBED=off is what the hook relies on to keep its work local and +// fast, and `logos index` and search honour it. `memory add` took its model +// from the router and never asked, so with a runtime up the fact was embedded +// anyway. +func TestMemoryAddDoesNotEmbedWithEmbeddingsOff(t *testing.T) { + rr := newRecordingRuntime(t, "nomic-embed-text", "gemma3:4b") + t.Setenv("LOGOS_VAULT", t.TempDir()) + t.Setenv("LOGOS_RUNTIME", rr.URL) + t.Setenv("LOGOS_EMBED", "off") + + if err := memoryCmd([]string{"add", "the release runner keeps its cache on the second disk"}); err != nil { + t.Fatal(err) + } + if got := rr.embedded(); len(got) != 0 { + t.Errorf("memory add with LOGOS_EMBED=off sent %d embeddings request(s): %v", len(got), got) + } +}