@@ -71,6 +71,18 @@ function encodeAssetPath(raw: string): string {
7171 }
7272}
7373
74+ function normalizeGeneratedAssetUrls ( input : unknown ) : string [ ] {
75+ if ( ! Array . isArray ( input ) ) return [ ] ;
76+ const out : string [ ] = [ ] ;
77+ for ( const u of input ) {
78+ if ( typeof u !== "string" ) continue ;
79+ const trimmed = u . trim ( ) ;
80+ if ( ! trimmed ) continue ;
81+ out . push ( trimmed ) ;
82+ }
83+ return out ;
84+ }
85+
7486export function createOpenAiStreamFromGrokNdjson (
7587 grokResp : Response ,
7688 opts : {
@@ -241,11 +253,10 @@ export function createOpenAiStreamFromGrokNdjson(
241253 if ( isImage ) {
242254 const modelResp = grok . modelResponse ;
243255 if ( modelResp ) {
244- const urls = Array . isArray ( modelResp . generatedImageUrls ) ? modelResp . generatedImageUrls : [ ] ;
256+ const urls = normalizeGeneratedAssetUrls ( ( modelResp as any ) . generatedImageUrls ) ;
245257 if ( urls . length ) {
246258 const linesOut : string [ ] = [ ] ;
247259 for ( const u of urls ) {
248- if ( typeof u !== "string" ) continue ;
249260 const imgPath = encodeAssetPath ( u ) ;
250261 const imgUrl = toImgProxyUrl ( global , origin , imgPath ) ;
251262 linesOut . push ( `` ) ;
@@ -379,14 +390,16 @@ export async function parseOpenAiFromGrokNdjson(
379390 if ( typeof modelResp . model === "string" && modelResp . model ) model = modelResp . model ;
380391 if ( typeof modelResp . message === "string" ) content = modelResp . message ;
381392
382- const urls = Array . isArray ( modelResp . generatedImageUrls ) ? modelResp . generatedImageUrls : [ ] ;
393+ const urls = normalizeGeneratedAssetUrls ( ( modelResp as any ) . generatedImageUrls ) ;
383394 for ( const u of urls ) {
384- if ( typeof u !== "string" ) continue ;
385395 const imgPath = encodeAssetPath ( u ) ;
386396 const imgUrl = toImgProxyUrl ( global , origin , imgPath ) ;
387397 content += `\n` ;
388398 }
389- break ;
399+
400+ // For image generation responses, Grok may emit intermediate modelResponse frames with empty/placeholder URLs.
401+ // Keep scanning until we see at least one usable URL; otherwise the caller gets a broken `/images/p_Lw` link.
402+ if ( urls . length ) break ;
390403 }
391404
392405 return {
0 commit comments