@@ -133,6 +133,51 @@ test('recallForTask returns no-matches when semantic hits are fully filtered out
133133 assert . deepEqual ( result . global_memories , [ ] ) ;
134134} ) ;
135135
136+ test ( 'recallForTask returns an empty recall with warning when semantic search backend is unavailable' , async ( ) => {
137+ const db = {
138+ exec ( sql : string ) {
139+ if ( sql . includes ( 'SELECT canonical_key FROM project_key_aliases' ) ) {
140+ return [ { columns : [ 'canonical_key' ] , values : [ ] } ] ;
141+ }
142+ if ( sql . includes ( 'FROM project_key_aliases' ) ) {
143+ return [ {
144+ columns : [ 'alias_key' ] ,
145+ values : [ [ 'git:project-a' ] ] ,
146+ } ] ;
147+ }
148+ throw new Error ( `Unexpected SQL: ${ sql } ` ) ;
149+ } ,
150+ } ;
151+
152+ const result = await recallForTask (
153+ {
154+ mode : 'task' ,
155+ task : {
156+ goal : 'Evaluate Glama MCP listing quality' ,
157+ task_kind : 'config' ,
158+ project_key : 'git:project-a' ,
159+ } ,
160+ options : {
161+ project_limit : 3 ,
162+ global_limit : 0 ,
163+ include_relations : false ,
164+ } ,
165+ } ,
166+ {
167+ db : db as never ,
168+ semanticSearch : async ( ) => {
169+ throw new Error ( 'Cannot connect to API: connect ECONNREFUSED 127.0.0.1:11434' ) ;
170+ } ,
171+ } ,
172+ ) ;
173+
174+ assert . equal ( result . reason , 'no-matches' ) ;
175+ assert . deepEqual ( result . project_memories , [ ] ) ;
176+ assert . deepEqual ( result . global_memories , [ ] ) ;
177+ assert . match ( result . warnings . join ( '\n' ) , / S e m a n t i c m e m o r y r e c a l l u n a v a i l a b l e / ) ;
178+ assert . match ( result . warnings . join ( '\n' ) , / E C O N N R E F U S E D / ) ;
179+ } ) ;
180+
136181test ( 'recallForTask derives project_key from project_dir when the caller does not provide one' , async ( ) => {
137182 const projectDir = process . cwd ( ) . replace ( / \\ / g, '/' ) ;
138183 const derivedProjectKey = deriveProjectKey (
0 commit comments