fix: stabilize sub2api codex pool operations

This commit is contained in:
Codex
2026-07-01 15:52:22 +00:00
parent 8f54b591d7
commit 113b6809d1
16 changed files with 509 additions and 59 deletions
@@ -24,7 +24,7 @@ import { runSshCommandCapture, type SshCaptureResult } from "../ssh";
import type { CodexPoolConfig, CodexPoolRuntimeTarget, CodexProfile, CodexTempUnschedulablePolicy } from "./types";
import { desiredAccountCapacityTotal } from "./accounts";
import { fingerprint, isRecord } from "./config-utils";
import { manualBindingSourcePlan, targetPublicExposureSummary } from "./public-exposure";
import { manualBindingSourcePlan, protectedManualAccountsForTarget, targetPublicExposureSummary } from "./public-exposure";
export function readAuthAPIKey(authPath: string): { apiKey: string | null; shape: string } {
if (!existsSync(authPath)) return { apiKey: null, shape: "missing" };
@@ -148,12 +148,22 @@ export function codexPoolConfigSummary(pool: CodexPoolConfig, target: CodexPoolR
manualAccounts: {
bindingSources: pool.manualAccounts.bindingSources.items.map(manualBindingSourcePlan),
protectedCount: pool.manualAccounts.protected.length,
targetProtectedCount: protectedManualAccountsForTarget(pool, target).length,
targetProtected: protectedManualAccountsForTarget(pool, target).map((account) => ({
accountName: account.accountName,
targetIds: account.targetIds,
proxyBindingEnabled: account.proxyBinding?.enabled ?? false,
groupBindingEnabled: account.groupBinding?.enabled ?? false,
})),
protected: pool.manualAccounts.protected,
controlPolicy: "manual accounts are not created, credential-updated, pruned, probed, or frozen by UniDesk codex-pool sync/sentinel; optional proxy_id and pool group membership bindings are narrow YAML-controlled exceptions",
},
publicExposure: targetPublicExposureSummary(target),
localCodex: pool.localCodex,
sentinel: codexPoolSentinelSummary(pool.sentinel),
sentinel: {
...codexPoolSentinelSummary(pool.sentinel),
runtimeImage: codexPoolSentinelRuntimeImage(pool.sentinel).runtimeImage,
},
disclosure: {
full: "bun scripts/cli.ts platform-infra sub2api codex-pool plan --full",
},
@@ -650,11 +660,24 @@ export function compactSentinelStatus(block: unknown): unknown {
export function compactSentinelProbeResult(parsed: Record<string, unknown> | null): Record<string, unknown> | null {
if (parsed === null) return null;
const probe = isRecord(parsed.probe) ? parsed.probe : {};
const summary = isRecord(probe.summary) ? probe.summary : {};
const probe = isRecord(parsed.probe) ? parsed.probe : parsed;
const summary = isRecord(parsed.summary) ? parsed.summary : isRecord(probe.summary) ? probe.summary : {};
const state = isRecord(parsed.sentinelState) ? parsed.sentinelState : {};
const lastRun = isRecord(state.lastRun) ? state.lastRun : {};
const requestedAccounts = Array.isArray(parsed.requestedAccounts) ? parsed.requestedAccounts.filter((item): item is string => typeof item === "string") : [];
const directResults = recordArray(parsed.results).length > 0 ? recordArray(parsed.results) : recordArray(probe.results);
const lastRunResults = recordArray(lastRun.results);
const results = directResults.length > 0
? directResults
: requestedAccounts.length === 0
? lastRunResults
: lastRunResults.filter((item) => requestedAccounts.includes(String(item.accountName ?? "")));
const allRequestedOk = requestedAccounts.length > 0
&& requestedAccounts.every((account) => results.some((item) => item.accountName === account && item.markerMatched === true));
return {
ok: parsed.ok,
ok: parsed.ok === true || allRequestedOk,
jobExecutionOk: parsed.jobExecutionOk,
markerOk: parsed.markerOk === true || allRequestedOk,
mode: parsed.mode,
namespace: parsed.namespace,
job: parsed.job,
@@ -672,7 +695,7 @@ export function compactSentinelProbeResult(parsed: Record<string, unknown> | nul
gatewayFailureMonitor: summary.gatewayFailureMonitor,
selection: summary.selection,
},
results: recordArray(probe.results).map((item) => pickSummaryFields(item, [
results: results.map((item) => pickSummaryFields(item, [
"accountName",
"purpose",
"ok",
@@ -691,16 +714,29 @@ export function compactSentinelProbeResult(parsed: Record<string, unknown> | nul
"sdk",
"requestShape",
])),
actions: recordArray(probe.actions).map((item) => pickSummaryFields(item, [
actions: recordArray(parsed.actions).concat(recordArray(probe.actions)).map((item) => pickSummaryFields(item, [
"accountName",
"taken",
"type",
"error",
])),
sentinelState: {
quarantined: state.quarantined,
recentAccounts: state.recentAccounts,
lastRun: state.lastRun,
quarantinedCount: recordArray(state.quarantined).length,
recentAccountCount: recordArray(state.recentAccounts).length,
lastRun: {
at: lastRun.at,
selected: lastRun.selected,
okCount: lastRun.okCount,
markerMismatchCount: lastRun.markerMismatchCount,
transportFailureCount: lastRun.transportFailureCount,
actionsTaken: lastRun.actionsTaken,
runtimeSchedulable: isRecord(lastRun.runtimeSchedulable) ? {
ok: lastRun.runtimeSchedulable.ok,
schedulableCount: Array.isArray(lastRun.runtimeSchedulable.schedulableAccounts) ? lastRun.runtimeSchedulable.schedulableAccounts.length : undefined,
unschedulableCount: recordArray(lastRun.runtimeSchedulable.unschedulableAccounts).length,
missingCount: Array.isArray(lastRun.runtimeSchedulable.missingAccounts) ? lastRun.runtimeSchedulable.missingAccounts.length : undefined,
} : undefined,
},
},
valuesPrinted: false,
};