11import { beforeEach , describe , expect , it , vi } from "vitest" ;
22
3- const { collectRetrievalBlocksFromStateMock } = vi . hoisted ( ( ) => ( {
3+ const {
4+ collectRetrievalBlocksFromStateMock,
5+ collectLightweightRetrievalBlocksFromStateMock,
6+ } = vi . hoisted ( ( ) => ( {
47 collectRetrievalBlocksFromStateMock : vi . fn ( async ( ) => [ ] ) ,
8+ collectLightweightRetrievalBlocksFromStateMock : vi . fn ( async ( ) => [ ] ) ,
59} ) ) ;
610
711vi . mock ( "../src/functions/retrieval-blocks.js" , async ( ) => {
@@ -11,6 +15,8 @@ vi.mock("../src/functions/retrieval-blocks.js", async () => {
1115 return {
1216 ...actual ,
1317 collectRetrievalBlocksFromState : collectRetrievalBlocksFromStateMock ,
18+ collectLightweightRetrievalBlocksFromState :
19+ collectLightweightRetrievalBlocksFromStateMock ,
1420 } ;
1521} ) ;
1622
@@ -27,6 +33,7 @@ import type { RetrievalBlock } from "../src/types.js";
2733describe ( "retrieveRelevantBlocks" , ( ) => {
2834 beforeEach ( ( ) => {
2935 collectRetrievalBlocksFromStateMock . mockClear ( ) ;
36+ collectLightweightRetrievalBlocksFromStateMock . mockClear ( ) ;
3037 getRetrievalSearchIndex ( ) . clear ( ) ;
3138 configureRetrievalBlockIndexingRuntime ( {
3239 embeddingProvider : null ,
@@ -77,4 +84,78 @@ describe("retrieveRelevantBlocks", () => {
7784 expect ( result . searchResults ) . toHaveLength ( 1 ) ;
7885 expect ( result . searchResults [ 0 ] ?. block . id ) . toBe ( block . id ) ;
7986 } ) ;
87+
88+ it ( "falls back to lightweight state collection when the retrieval block scope is unavailable" , async ( ) => {
89+ const kv = mockKV ( ) ;
90+ const staleBlock : RetrievalBlock = {
91+ id : "rblk_stale" ,
92+ sourceType : "semantic_memory" ,
93+ sourceId : "sem_stale" ,
94+ project : "global" ,
95+ scope : "global" ,
96+ freshnessLane : "cold" ,
97+ canonicalText : "Unrelated stale retrieval memory" ,
98+ title : "Stale memory" ,
99+ files : [ ] ,
100+ concepts : [ "stale" ] ,
101+ entities : [ "stale" ] ,
102+ sourceObservationIds : [ ] ,
103+ hadFailure : false ,
104+ hadDecision : false ,
105+ hadAssistantConclusion : true ,
106+ isResumeArtifact : false ,
107+ importance : 7 ,
108+ createdAt : "2026-01-01T00:00:00Z" ,
109+ updatedAt : "2026-01-01T00:00:00Z" ,
110+ eventAt : "2026-01-01T00:00:00Z" ,
111+ } ;
112+ const block : RetrievalBlock = {
113+ id : "rblk_theta" ,
114+ sourceType : "memory" ,
115+ sourceId : "mem_theta" ,
116+ project : "global" ,
117+ scope : "global" ,
118+ freshnessLane : "cold" ,
119+ canonicalText : "Codex durable retrieval probe theta retrieval memory" ,
120+ title : "Theta memory" ,
121+ files : [ "/tmp/codex-theta.txt" ] ,
122+ concepts : [ "theta sentinel" ] ,
123+ entities : [ "theta" , "sentinel" ] ,
124+ sourceObservationIds : [ ] ,
125+ hadFailure : false ,
126+ hadDecision : false ,
127+ hadAssistantConclusion : true ,
128+ isResumeArtifact : false ,
129+ importance : 7 ,
130+ createdAt : "2026-01-01T00:00:00Z" ,
131+ updatedAt : "2026-01-01T00:00:00Z" ,
132+ eventAt : "2026-01-01T00:00:00Z" ,
133+ } ;
134+
135+ getRetrievalSearchIndex ( ) . addDocument (
136+ staleBlock . id ,
137+ staleBlock . project ,
138+ buildRetrievalBlockLexicalText ( staleBlock ) ,
139+ ) ;
140+
141+ const listError = new Error ( "retrieval block scope timeout" ) ;
142+ const rawList = kv . list . bind ( kv ) ;
143+ kv . list = ( async < T > ( scope : string ) : Promise < T [ ] > => {
144+ if ( scope === KV . retrievalBlocks ) throw listError ;
145+ return rawList ( scope ) ;
146+ } ) as typeof kv . list ;
147+
148+ collectLightweightRetrievalBlocksFromStateMock . mockResolvedValue ( [ block ] ) ;
149+
150+ const result = await retrieveRelevantBlocks ( kv as never , {
151+ query : "theta sentinel" ,
152+ budget : 300 ,
153+ purpose : "smart-search" ,
154+ } ) ;
155+
156+ expect ( collectLightweightRetrievalBlocksFromStateMock ) . toHaveBeenCalled ( ) ;
157+ expect ( collectRetrievalBlocksFromStateMock ) . not . toHaveBeenCalled ( ) ;
158+ expect ( result . searchResults ) . toHaveLength ( 1 ) ;
159+ expect ( result . searchResults [ 0 ] ?. block . id ) . toBe ( block . id ) ;
160+ } ) ;
80161} ) ;
0 commit comments