@@ -22,6 +22,7 @@ const ANTHROPIC_TIMEOUT_MS = 120_000;
2222const LIVE_CACHE_LANE_RETRIES = 1 ;
2323const LIVE_CACHE_RESPONSE_RETRIES = 2 ;
2424const OPENAI_CACHE_REASONING = "low" as unknown as never ;
25+ const OPENAI_CACHE_MIN_MAX_TOKENS = 256 ;
2526const OPENAI_PREFIX = buildStableCachePrefix ( "openai" ) ;
2627const OPENAI_MCP_PREFIX = buildStableCachePrefix ( "openai-mcp-style" ) ;
2728const ANTHROPIC_PREFIX = buildStableCachePrefix ( "anthropic" ) ;
@@ -153,6 +154,32 @@ function shouldRetryCacheProbeText(params: {
153154 ) ;
154155}
155156
157+ function resolveCacheProbeMaxTokens ( params : {
158+ maxTokens : number | undefined ;
159+ providerTag : "anthropic" | "openai" ;
160+ } ) : number {
161+ const requested = params . maxTokens ?? 64 ;
162+ if ( params . providerTag !== "openai" ) {
163+ return requested ;
164+ }
165+ return Math . max ( requested , OPENAI_CACHE_MIN_MAX_TOKENS ) ;
166+ }
167+
168+ function shouldAcceptEmptyOpenAICacheProbe ( params : {
169+ providerTag : "anthropic" | "openai" ;
170+ text : string ;
171+ usage : CacheUsage ;
172+ } ) : boolean {
173+ if ( params . providerTag !== "openai" || params . text . trim ( ) . length > 0 ) {
174+ return false ;
175+ }
176+ return (
177+ ( params . usage . input ?? 0 ) > 0 ||
178+ ( params . usage . cacheRead ?? 0 ) > 0 ||
179+ ( params . usage . cacheWrite ?? 0 ) > 0
180+ ) ;
181+ }
182+
156183async function runToolOnlyTurn ( params : {
157184 apiKey : string ;
158185 cacheRetention : "none" | "short" | "long" ;
@@ -242,14 +269,35 @@ async function completeCacheProbe(params: {
242269 apiKey : params . apiKey ,
243270 cacheRetention : params . cacheRetention ,
244271 sessionId : params . sessionId ,
245- maxTokens : params . maxTokens ?? 64 ,
272+ maxTokens : resolveCacheProbeMaxTokens ( {
273+ maxTokens : params . maxTokens ,
274+ providerTag : params . providerTag ,
275+ } ) ,
246276 temperature : 0 ,
247277 ...( params . providerTag === "openai" ? { reasoning : OPENAI_CACHE_REASONING } : { } ) ,
248278 } ,
249279 `${ params . providerTag } cache lane ${ params . suffix } ` ,
250280 timeoutMs ,
251281 ) ;
252282 const text = extractAssistantText ( response ) ;
283+ const usage = normalizeCacheUsage ( response . usage ) ;
284+ if (
285+ shouldAcceptEmptyOpenAICacheProbe ( {
286+ providerTag : params . providerTag ,
287+ text,
288+ usage,
289+ } )
290+ ) {
291+ logLiveCache (
292+ `${ params . providerTag } cache lane ${ params . suffix } accepted empty text with usage ${ formatUsage ( usage ) } ` ,
293+ ) ;
294+ return {
295+ suffix : params . suffix ,
296+ text,
297+ usage,
298+ hitRate : computeCacheHitRate ( usage ) ,
299+ } ;
300+ }
253301 if ( shouldRetryCacheProbeText ( { attempt, suffix : params . suffix , text } ) ) {
254302 logLiveCache (
255303 `${ params . providerTag } cache lane ${ params . suffix } response mismatch; retrying: ${ JSON . stringify ( text ) } ` ,
@@ -262,7 +310,6 @@ async function completeCacheProbe(params: {
262310 if ( ! responseTextLower . includes ( markerLower ) ) {
263311 throw new CacheProbeTextMismatchError ( params . suffix , text ) ;
264312 }
265- const usage = normalizeCacheUsage ( response . usage ) ;
266313 return {
267314 suffix : params . suffix ,
268315 text,
@@ -551,6 +598,8 @@ function appendBaselineFindings(target: BaselineFindings, source: BaselineFindin
551598export const __testing = {
552599 assertAgainstBaseline,
553600 evaluateAgainstBaseline,
601+ resolveCacheProbeMaxTokens,
602+ shouldAcceptEmptyOpenAICacheProbe,
554603 shouldRetryCacheProbeText,
555604 shouldRetryBaselineFindings,
556605} ;
@@ -562,7 +611,7 @@ export async function runLiveCacheRegression(): Promise<LiveCacheRegressionResul
562611 provider : "openai" ,
563612 api : "openai-responses" ,
564613 envVar : "OPENCLAW_LIVE_OPENAI_CACHE_MODEL" ,
565- preferredModelIds : [ "gpt-5.2" , "gpt-5.4-mini" , "gpt-5.4" , "gpt-5.5" ] ,
614+ preferredModelIds : [ "gpt-4.1" , "gpt- 5.2", "gpt-5.4-mini" , "gpt-5.4" , "gpt-5.5" ] ,
566615 } ) ;
567616 const anthropic = await resolveLiveDirectModel ( {
568617 provider : "anthropic" ,
0 commit comments