@@ -18,6 +18,7 @@ import {
1818 resetGlobalHookRunner ,
1919} from "openclaw/plugin-sdk/hook-runtime" ;
2020import { createMockPluginRegistry } from "openclaw/plugin-sdk/plugin-test-runtime" ;
21+ import { withTempDir } from "openclaw/plugin-sdk/test-env" ;
2122import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
2223import {
2324 CodexAppServerEventProjector ,
@@ -743,6 +744,47 @@ describe("CodexAppServerEventProjector", () => {
743744 expect ( result . toolMediaUrls ?. [ 0 ] ) . not . toBe ( savedPath ) ;
744745 } ) ;
745746
747+ it ( "prefers gateway-managed image media when the typed event arrives first" , async ( ) => {
748+ await withTempDir ( "openclaw-codex-media-state-" , async ( stateDir ) => {
749+ vi . stubEnv ( "OPENCLAW_STATE_DIR" , stateDir ) ;
750+ const projector = await createProjector ( ) ;
751+ const savedPath = "/home/dev-user/.codex/generated_images/session-1/ig_123.png" ;
752+
753+ await projector . handleNotification (
754+ forCurrentTurn ( "item/completed" , {
755+ item : {
756+ type : "imageGeneration" ,
757+ id : "ig_123" ,
758+ status : "completed" ,
759+ revisedPrompt : "A tiny blue square" ,
760+ result : tinyPngBase64 ,
761+ savedPath,
762+ } ,
763+ } ) ,
764+ ) ;
765+ await projector . handleNotification (
766+ forCurrentTurn ( "rawResponseItem/completed" , {
767+ item : {
768+ type : "image_generation_call" ,
769+ id : "ig_123" ,
770+ status : "generating" ,
771+ result : tinyPngBase64 ,
772+ } ,
773+ } ) ,
774+ ) ;
775+
776+ const result = projector . buildResult ( buildEmptyToolTelemetry ( ) ) ;
777+ const mediaUrl = result . toolMediaUrls ?. [ 0 ] ;
778+
779+ expect ( result . toolMediaUrls ) . toHaveLength ( 1 ) ;
780+ expect ( mediaUrl ) . not . toBe ( savedPath ) ;
781+ expect ( mediaUrl ) . toContain ( `${ path . sep } media${ path . sep } tool-image-generation${ path . sep } ` ) ;
782+ await expect ( fs . readFile ( mediaUrl ?? "" ) ) . resolves . toEqual (
783+ Buffer . from ( tinyPngBase64 , "base64" ) ,
784+ ) ;
785+ } ) ;
786+ } ) ;
787+
746788 it ( "preserves distinct raw image-generation items with identical image bytes" , async ( ) => {
747789 const stateDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , "openclaw-codex-media-state-" ) ) ;
748790 tempDirs . add ( stateDir ) ;
0 commit comments