fix: default codex sentinel protect retries

This commit is contained in:
Codex
2026-06-13 06:57:35 +00:00
parent 8ac952c7a6
commit e78cc9a16d
4 changed files with 28 additions and 18 deletions
+18 -9
View File
@@ -141,6 +141,7 @@ interface CodexPoolConfig {
defaultAccountCapacity: number;
defaultAccountLoadFactor: number;
defaultTempUnschedulable: CodexTempUnschedulablePolicy;
defaultSentinelProtect: CodexSentinelProtectPolicy;
profiles: CodexPoolProfileConfig[];
publicExposure: CodexPoolPublicExposureConfig;
localCodex: CodexPoolLocalCodexConfig;
@@ -703,6 +704,7 @@ async function codexPoolSync(config: UniDeskConfig, options: SyncOptions): Promi
defaultAccountPriority: pool.defaultAccountPriority,
defaultAccountCapacity: pool.defaultAccountCapacity,
defaultAccountLoadFactor: pool.defaultAccountLoadFactor,
defaultSentinelProtect: pool.defaultSentinelProtect,
},
profiles: profiles.map((profile) => ({
profile: profile.profile,
@@ -1085,7 +1087,7 @@ function collectCodexProfiles(): CodexProfile[] {
const seenAccountNames = new Set<string>();
const configs = pool.profiles.length > 0
? pool.profiles
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultAccountPriority);
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultSentinelProtect, pool.defaultAccountPriority);
return configs.map((entry) => {
const resolved = resolveProfileFiles(codexDir, entry);
const profile = entry.profile;
@@ -1162,6 +1164,7 @@ function collectCodexProfiles(): CodexProfile[] {
function discoverCodexProfileConfigs(
codexDir: string,
defaultTempUnschedulable = defaultCodexTempUnschedulablePolicy(),
defaultSentinelProtect = defaultCodexSentinelProtectPolicy(),
defaultPriority = defaultAccountPriority,
): CodexPoolProfileConfig[] {
return readdirSync(codexDir)
@@ -1184,7 +1187,7 @@ function discoverCodexProfileConfigs(
openaiResponsesWebSocketsV2Mode: null,
upstreamUserAgent: null,
trustUpstream: false,
sentinelProtect: defaultCodexSentinelProtectPolicy(),
sentinelProtect: defaultSentinelProtect,
priority: defaultPriority,
capacity: null,
loadFactor: null,
@@ -1215,10 +1218,12 @@ function readCodexPoolConfig(): CodexPoolConfig {
const defaultAccountPriorityValue = readAccountPriority(pool.defaultAccountPriority, "pool.defaultAccountPriority");
const defaultAccountCapacityValue = readAccountCapacity(pool.defaultAccountCapacity, "pool.defaultAccountCapacity");
const defaultAccountLoadFactorValue = readAccountLoadFactor(pool.defaultAccountLoadFactor, "pool.defaultAccountLoadFactor");
const defaultSentinelProtect = readSentinelProtectPolicy(pool.defaultSentinelProtect, "pool.defaultSentinelProtect", defaults.defaultSentinelProtect);
const profiles = readProfileConfig(
parsed.profiles,
defaults.profiles,
defaultTempUnschedulable,
defaultSentinelProtect,
defaultAccountPriorityValue,
);
const declaredAccountCapacity = desiredProfileCapacityTotal(profiles, defaultAccountCapacityValue);
@@ -1238,6 +1243,7 @@ function readCodexPoolConfig(): CodexPoolConfig {
defaultAccountCapacity: defaultAccountCapacityValue,
defaultAccountLoadFactor: defaultAccountLoadFactorValue,
defaultTempUnschedulable,
defaultSentinelProtect,
profiles,
publicExposure: readPublicExposureConfig(parsed.publicExposure, defaults.publicExposure),
localCodex: readLocalCodexConfig(parsed.localCodex, defaults.localCodex),
@@ -1268,6 +1274,7 @@ function defaultCodexPoolConfig(): CodexPoolConfig {
defaultAccountCapacity: 5,
defaultAccountLoadFactor: 1,
defaultTempUnschedulable: defaultCodexTempUnschedulablePolicy(),
defaultSentinelProtect: defaultCodexSentinelProtectPolicy(),
profiles: [],
publicExposure: {
enabled: false,
@@ -1329,6 +1336,7 @@ function readProfileConfig(
value: unknown,
defaults: CodexPoolProfileConfig[],
defaultTempUnschedulable: CodexTempUnschedulablePolicy,
defaultSentinelProtect: CodexSentinelProtectPolicy,
defaultPriority: number,
): CodexPoolProfileConfig[] {
if (!isRecord(value)) return defaults;
@@ -1354,7 +1362,7 @@ function readProfileConfig(
const openaiResponsesWebSocketsV2Mode = readOpenAIResponsesWebSocketsV2Mode(entry.openaiResponsesWebSocketsV2Mode, `profiles.entries[${index}].openaiResponsesWebSocketsV2Mode`);
const upstreamUserAgent = readUpstreamUserAgent(entry.upstreamUserAgent, `profiles.entries[${index}].upstreamUserAgent`);
const trustUpstream = readTrustUpstream(entry.trustUpstream, `profiles.entries[${index}].trustUpstream`);
const sentinelProtect = readSentinelProtectPolicy(entry.sentinelProtect, `profiles.entries[${index}].sentinelProtect`);
const sentinelProtect = readSentinelProtectPolicy(entry.sentinelProtect, `profiles.entries[${index}].sentinelProtect`, defaultSentinelProtect);
const priority = readAccountPriority(entry.priority, `profiles.entries[${index}].priority`, defaultPriority);
const capacity = entry.capacity === undefined || entry.capacity === null ? null : readAccountCapacity(entry.capacity, `profiles.entries[${index}].capacity`);
const loadFactor = entry.loadFactor === undefined || entry.loadFactor === null ? null : readAccountLoadFactor(entry.loadFactor, `profiles.entries[${index}].loadFactor`);
@@ -1422,8 +1430,7 @@ export function defaultCodexSentinelProtectPolicy(): CodexSentinelProtectPolicy
};
}
function readSentinelProtectPolicy(value: unknown, key: string): CodexSentinelProtectPolicy {
const fallback = defaultCodexSentinelProtectPolicy();
function readSentinelProtectPolicy(value: unknown, key: string, fallback = defaultCodexSentinelProtectPolicy()): CodexSentinelProtectPolicy {
if (value === undefined || value === null) return fallback;
if (!isRecord(value)) throw new Error(`${codexPoolConfigPath}.${key} must be a YAML object`);
const enabled = readBooleanConfig(value.enabled, `${key}.enabled`, fallback.enabled);
@@ -1857,6 +1864,7 @@ function codexPoolConfigSummary(pool: CodexPoolConfig): Record<string, unknown>
defaultAccountCapacity: pool.defaultAccountCapacity,
defaultAccountLoadFactor: pool.defaultAccountLoadFactor,
defaultTempUnschedulable: tempUnschedulableSummary(pool.defaultTempUnschedulable),
defaultSentinelProtect: pool.defaultSentinelProtect,
profileCount: pool.profiles.length,
publicExposure: publicExposureSummary(pool),
localCodex: pool.localCodex,
@@ -2744,6 +2752,7 @@ function poolTarget(pool = readCodexPoolConfig(), target = codexPoolRuntimeTarge
defaultAccountPriority: pool.defaultAccountPriority,
defaultAccountCapacity: pool.defaultAccountCapacity,
defaultAccountLoadFactor: pool.defaultAccountLoadFactor,
defaultSentinelProtect: pool.defaultSentinelProtect,
sentinel: {
monitorEnabled: pool.sentinel.monitor.enabled,
actionsEnabled: pool.sentinel.actions.enabled,
@@ -3875,7 +3884,7 @@ function desiredAccountCapacityMap(pool: CodexPoolConfig): Record<string, number
const seenAccountNames = new Set<string>();
const configs = pool.profiles.length > 0
? pool.profiles
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultAccountPriority);
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultSentinelProtect, pool.defaultAccountPriority);
const capacities: Record<string, number> = {};
for (const entry of configs) {
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
@@ -3890,7 +3899,7 @@ function desiredAccountLoadFactorMap(pool: CodexPoolConfig): Record<string, numb
const seenAccountNames = new Set<string>();
const configs = pool.profiles.length > 0
? pool.profiles
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultAccountPriority);
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultSentinelProtect, pool.defaultAccountPriority);
const loadFactors: Record<string, number> = {};
for (const entry of configs) {
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
@@ -3905,7 +3914,7 @@ function desiredAccountWebSocketsV2ModeMap(pool: CodexPoolConfig): Record<string
const seenAccountNames = new Set<string>();
const configs = pool.profiles.length > 0
? pool.profiles
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultAccountPriority);
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultSentinelProtect, pool.defaultAccountPriority);
const modes: Record<string, OpenAIResponsesWebSocketsV2Mode | null> = {};
for (const entry of configs) {
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
@@ -3920,7 +3929,7 @@ function desiredAccountTempUnschedulableMap(pool: CodexPoolConfig): Record<strin
const seenAccountNames = new Set<string>();
const configs = pool.profiles.length > 0
? pool.profiles
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultAccountPriority);
: discoverCodexProfileConfigs(codexDir, pool.defaultTempUnschedulable, pool.defaultSentinelProtect, pool.defaultAccountPriority);
const policies: Record<string, unknown> = {};
for (const entry of configs) {
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);