@@ -8,21 +8,20 @@ import { resolveMemorySearchConfig } from "./memory-search.js";
88
99const asConfig = ( cfg : OpenClawConfig ) : OpenClawConfig => cfg ;
1010
11- describe ( "memory search config" , ( ) => {
12- beforeEach ( ( ) => {
13- clearMemoryEmbeddingProviders ( ) ;
14- registerMemoryEmbeddingProvider ( {
15- id : "openai" ,
16- defaultModel : "text-embedding-3-small" ,
17- transport : "remote" ,
18- create : async ( ) => ( { provider : null } ) ,
19- } ) ;
20- registerMemoryEmbeddingProvider ( {
21- id : "local" ,
22- defaultModel : "local-default" ,
23- transport : "local" ,
24- create : async ( ) => ( { provider : null } ) ,
25- } ) ;
11+ function registerBaseMemoryEmbeddingProviders ( options ?: { includeGemini ?: boolean } ) : void {
12+ registerMemoryEmbeddingProvider ( {
13+ id : "openai" ,
14+ defaultModel : "text-embedding-3-small" ,
15+ transport : "remote" ,
16+ create : async ( ) => ( { provider : null } ) ,
17+ } ) ;
18+ registerMemoryEmbeddingProvider ( {
19+ id : "local" ,
20+ defaultModel : "local-default" ,
21+ transport : "local" ,
22+ create : async ( ) => ( { provider : null } ) ,
23+ } ) ;
24+ if ( options ?. includeGemini !== false ) {
2625 registerMemoryEmbeddingProvider ( {
2726 id : "gemini" ,
2827 defaultModel : "gemini-embedding-001" ,
@@ -34,24 +33,31 @@ describe("memory search config", () => {
3433 . replace ( / ^ ( g e m i n i | g o o g l e ) \/ / , "" ) === "gemini-embedding-2-preview" ,
3534 create : async ( ) => ( { provider : null } ) ,
3635 } ) ;
37- registerMemoryEmbeddingProvider ( {
38- id : "voyage" ,
39- defaultModel : "voyage-4-large" ,
40- transport : "remote" ,
41- create : async ( ) => ( { provider : null } ) ,
42- } ) ;
43- registerMemoryEmbeddingProvider ( {
44- id : "mistral" ,
45- defaultModel : "mistral-embed" ,
46- transport : "remote" ,
47- create : async ( ) => ( { provider : null } ) ,
48- } ) ;
49- registerMemoryEmbeddingProvider ( {
50- id : "ollama" ,
51- defaultModel : "nomic-embed-text" ,
52- transport : "remote" ,
53- create : async ( ) => ( { provider : null } ) ,
54- } ) ;
36+ }
37+ registerMemoryEmbeddingProvider ( {
38+ id : "voyage" ,
39+ defaultModel : "voyage-4-large" ,
40+ transport : "remote" ,
41+ create : async ( ) => ( { provider : null } ) ,
42+ } ) ;
43+ registerMemoryEmbeddingProvider ( {
44+ id : "mistral" ,
45+ defaultModel : "mistral-embed" ,
46+ transport : "remote" ,
47+ create : async ( ) => ( { provider : null } ) ,
48+ } ) ;
49+ registerMemoryEmbeddingProvider ( {
50+ id : "ollama" ,
51+ defaultModel : "nomic-embed-text" ,
52+ transport : "remote" ,
53+ create : async ( ) => ( { provider : null } ) ,
54+ } ) ;
55+ }
56+
57+ describe ( "memory search config" , ( ) => {
58+ beforeEach ( ( ) => {
59+ clearMemoryEmbeddingProviders ( ) ;
60+ registerBaseMemoryEmbeddingProviders ( ) ;
5561 } ) ;
5662
5763 afterEach ( ( ) => {
@@ -313,6 +319,29 @@ describe("memory search config", () => {
313319 ) ;
314320 } ) ;
315321
322+ it ( "accepts Gemini multimodal memory even when the runtime registry has not registered Gemini yet" , ( ) => {
323+ clearMemoryEmbeddingProviders ( ) ;
324+ registerBaseMemoryEmbeddingProviders ( { includeGemini : false } ) ;
325+ const cfg = asConfig ( {
326+ agents : {
327+ defaults : {
328+ memorySearch : {
329+ provider : "gemini" ,
330+ model : "gemini-embedding-2-preview" ,
331+ multimodal : { enabled : true , modalities : [ "image" ] } ,
332+ } ,
333+ } ,
334+ } ,
335+ } ) ;
336+ const resolved = resolveMemorySearchConfig ( cfg , "main" ) ;
337+ expect ( resolved ?. provider ) . toBe ( "gemini" ) ;
338+ expect ( resolved ?. multimodal ) . toEqual ( {
339+ enabled : true ,
340+ modalities : [ "image" ] ,
341+ maxFileBytes : 10 * 1024 * 1024 ,
342+ } ) ;
343+ } ) ;
344+
316345 it ( "rejects multimodal memory when fallback is configured" , ( ) => {
317346 const cfg = asConfig ( {
318347 agents : {
0 commit comments