



























@@ -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}
155156157+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: {
157184apiKey: string;
158185cacheRetention: "none" | "short" | "long";
@@ -242,14 +269,35 @@ async function completeCacheProbe(params: {
242269apiKey: params.apiKey,
243270cacheRetention: params.cacheRetention,
244271sessionId: params.sessionId,
245-maxTokens: params.maxTokens ?? 64,
272+maxTokens: resolveCacheProbeMaxTokens({
273+maxTokens: params.maxTokens,
274+providerTag: params.providerTag,
275+}),
246276temperature: 0,
247277 ...(params.providerTag === "openai" ? { reasoning: OPENAI_CACHE_REASONING } : {}),
248278},
249279`${params.providerTag} cache lane ${params.suffix}`,
250280timeoutMs,
251281);
252282const 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+}
253301if (shouldRetryCacheProbeText({ attempt, suffix: params.suffix, text })) {
254302logLiveCache(
255303`${params.providerTag} cache lane ${params.suffix} response mismatch; retrying: ${JSON.stringify(text)}`,
@@ -262,7 +310,6 @@ async function completeCacheProbe(params: {
262310if (!responseTextLower.includes(markerLower)) {
263311throw new CacheProbeTextMismatchError(params.suffix, text);
264312}
265-const usage = normalizeCacheUsage(response.usage);
266313return {
267314suffix: 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
562611provider: "openai",
563612api: "openai-responses",
564613envVar: "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});
567616const anthropic = await resolveLiveDirectModel({
568617provider: "anthropic",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。