@@ -322,44 +322,59 @@ function manifest(value: unknown, id: string, kind: string | undefined) {
322322 return { row, counts : counts as number [ ] }
323323}
324324
325+ /**
326+ * Region fetches are independent provider reads; running them together keeps a full read inside
327+ * the live read deadline. Validation walks them in page and region order, and a fetch is only
328+ * scheduled once the region this many places before it has been validated, so a rejected or
329+ * oversized document stops further reads and holds at most this many responses.
330+ */
331+ const REGION_FETCH_CONCURRENCY = 4
332+
325333/** Complete, bounded provider pages preserve graph data; no returned URL is fetched. */
326334export async function readLucidMcp (
327335 client : ManagedSearchMcpClient ,
328336 reference : Pick < NativeDocument , 'id' | 'kind' | 'revision' >
329337) : Promise < NativeDocument > {
330- const before = await metadata ( client , reference . id )
338+ const [ before , initialRaw ] = await Promise . all ( [
339+ metadata ( client , reference . id ) ,
340+ client . call ( 'fetch' , { id : reference . id , metadata_only : true } ) ,
341+ ] )
331342 if ( ! before ) invalid ( 'Lucid document metadata is incomplete or no longer readable.' )
332343 if (
333344 ( reference . kind && reference . kind !== before . kind ) ||
334345 ( reference . revision && reference . revision !== before . revision )
335346 )
336347 invalid ( 'Lucid document changed since this result was issued. Search again before reading.' )
337- const initial = manifest (
338- await client . call ( 'fetch' , { id : before . id , metadata_only : true } ) ,
339- before . id ,
340- before . kind
341- )
348+ const initial = manifest ( initialRaw , before . id , before . kind )
342349 if (
343350 initial . counts . length !== before . accessMetadata ?. pageCount ||
344351 initial . row . title !== before . title
345352 )
346353 invalid ( 'Lucid document coverage changed before reading. Search again.' )
347354 const pages : Record < string , unknown > [ ] = [ ]
348355 const output = ( ) => JSON . stringify ( { document_id : before . id , title : before . title , pages } )
349- for ( let pageIndex = 0 ; pageIndex < initial . counts . length ; pageIndex ++ ) {
350- const count = initial . counts [ pageIndex ] !
356+ const requests = initial . counts . flatMap ( ( count , pageIndex ) =>
357+ Array . from ( { length : Math . max ( 1 , count ) } , ( _ , region ) => ( {
358+ id : before . id ,
359+ page_index : pageIndex + 1 ,
360+ ...( count ? { region_index : [ region + 1 ] } : { } ) ,
361+ } ) )
362+ )
363+ const responses : Promise < unknown > [ ] = [ ]
364+ const schedule = ( index : number ) => {
365+ if ( index >= requests . length ) return
366+ const response = client . call ( 'fetch' , requests [ index ] )
367+ // An invalid earlier region abandons in-flight fetches; their rejections must not go unhandled.
368+ response . catch ( ( ) => { } )
369+ responses [ index ] = response
370+ }
371+ for ( let index = 0 ; index < REGION_FETCH_CONCURRENCY ; index ++ ) schedule ( index )
372+ let next = 0
373+ for ( const [ pageIndex , count ] of initial . counts . entries ( ) ) {
351374 let assembled : Record < string , unknown > | undefined
352375 const chunks : Record < string , unknown > [ ] = [ ]
353376 for ( let region = 0 ; region < Math . max ( 1 , count ) ; region ++ ) {
354- const fetched = manifest (
355- await client . call ( 'fetch' , {
356- id : before . id ,
357- page_index : pageIndex + 1 ,
358- ...( count ? { region_index : [ region + 1 ] } : { } ) ,
359- } ) ,
360- before . id ,
361- before . kind
362- )
377+ const fetched = manifest ( await responses [ next ] , before . id , before . kind )
363378 if (
364379 fetched . counts . some ( ( value , index ) => value !== initial . counts [ index ] ) ||
365380 fetched . counts . length !== initial . counts . length ||
@@ -404,6 +419,8 @@ export async function readLucidMcp(
404419 chunks . push ( ...returnedChunks )
405420 if ( Buffer . byteLength ( output ( ) , 'utf8' ) > MAX_CONTENT_BYTES )
406421 invalid ( 'Lucid document exceeds the 512 KiB complete-read limit. Open the source document.' )
422+ schedule ( next + REGION_FETCH_CONCURRENCY )
423+ next ++
407424 }
408425 }
409426 const after = await metadata ( client , before . id )
0 commit comments