fix: keep h2 patch repair on direct codex

This commit is contained in:
thanhnv
2026-07-18 12:20:22 +07:00
parent 1e5cfb341c
commit 850be145d7
3 changed files with 26 additions and 4 deletions
@@ -175,6 +175,11 @@ export class GoalsService {
const gatewayModels = gateway
? [gateway.defaultModel, ...gateway.models].filter((model, index, rows) => Boolean(model) && rows.indexOf(model) === index).slice(0, 5).map((model) => `openai-compatible:${model}`)
: [];
// A gateway is useful for conversational fallback, but code-patch repair
// must not silently change provider/model after a direct OpenAI repair
// fails. Gateways can have their own transport and model-specific output
// contracts; an operator can explicitly opt in after validating one.
const gatewayPatchRepairModels = process.env.CASAN_GOAL_ENABLE_GATEWAY_PATCH_REPAIR === '1' ? gatewayModels : [];
const preferredCloudModel = cloudCandidates[0]?.model || '';
const preferredCloudProvider = preferredCloudModel.startsWith('openai:') ? 'openai' : preferredCloudModel.startsWith('anthropic:') ? 'anthropic' : (cloud?.id || 'unavailable');
const cloudModel = preferredCloudModel || gateway?.defaultModel || gateway?.models[0] || '';
@@ -222,8 +227,9 @@ export class GoalsService {
CASAN_GOAL_CLOUD_FALLBACK_MODEL: String(cloudRuntime.CASAN_CHAT_SELECTED_MODEL || ''),
CASAN_GOAL_CLOUD_MODELS: cloudCandidates.map(({ model }) => model).join(','),
CASAN_GOAL_OMNIROUTE_MODELS: gatewayModels.join(','),
// H2 recovery tries direct cloud credentials before gateway and local.
CASAN_GOAL_PATCH_REPAIR_MODELS: [...cloudCandidates.map(({ model }) => model), ...gatewayModels, String(localRuntime.CASAN_CHAT_SELECTED_MODEL || `ollama:${localModel}`)].filter((model, index, rows) => rows.indexOf(model) === index).join(','),
// H2 repair stays on the direct provider by default. OmniRoute is an
// explicit opt-in because it must not disguise a Codex patch failure.
CASAN_GOAL_PATCH_REPAIR_MODELS: [...cloudCandidates.map(({ model }) => model), ...gatewayPatchRepairModels, String(localRuntime.CASAN_CHAT_SELECTED_MODEL || `ollama:${localModel}`)].filter((model, index, rows) => rows.indexOf(model) === index).join(','),
CASAN_GOAL_LOCAL_REVIEWER_MODEL: String(localRuntime.CASAN_CHAT_SELECTED_MODEL || `ollama:${localModel}`),
CASAN_GOAL_REVIEWER_MAX_ATTEMPTS: process.env.CASAN_GOAL_REVIEWER_MAX_ATTEMPTS || '8',
CASAN_GOAL_REVIEWER_DEADLINE_SEC: process.env.CASAN_GOAL_REVIEWER_DEADLINE_SEC || '600',