82 lines
3.7 KiB
TypeScript
82 lines
3.7 KiB
TypeScript
// SPEC: PJ2026-01060307 控制面模块化 draft-2026-06-25-p0. accounts module for scripts/src/platform-infra-sub2api-codex.ts.
|
|
|
|
// Moved mechanically from scripts/src/platform-infra-sub2api-codex.ts:4209-4264 for #903.
|
|
|
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
import { homedir } from "node:os";
|
|
import { join } from "node:path";
|
|
import type { UniDeskConfig } from "../config";
|
|
import { rootPath } from "../config";
|
|
import type { RenderedCliResult } from "../output";
|
|
import { applyPk01CaddyBlock, prepareFrpcSecret, renderFrpcManifest, type PublicServiceExposure, type PublicServiceTarget } from "../platform-infra-public-service";
|
|
import { shortSha256Fingerprint } from "../platform-infra-ops-library";
|
|
import {
|
|
codexPoolSentinelSummary,
|
|
codexPoolSentinelRuntimeImage,
|
|
readCodexPoolSentinelConfig,
|
|
renderCodexPoolSentinelManifest,
|
|
type CodexPoolSentinelConfig,
|
|
type CodexPoolSentinelProfileSecret,
|
|
} from "../platform-infra-sub2api-codex-sentinel";
|
|
import { parseEnvFile, readTextFile, redactRepoPath, requiredEnvValue } from "../secrets";
|
|
import { runSshCommandCapture, type SshCaptureResult } from "../ssh";
|
|
|
|
import type { CodexPoolConfig, OpenAIResponsesWebSocketsV2Mode } from "./types";
|
|
import { renderSub2ApiTempUnschedulableCredentials, uniqueAccountName } from "./redaction";
|
|
|
|
export function desiredAccountNames(pool: CodexPoolConfig): string[] {
|
|
return Object.keys(desiredAccountCapacityMap(pool)).sort();
|
|
}
|
|
|
|
export function desiredAccountCapacityTotal(pool: CodexPoolConfig): number {
|
|
return Object.values(desiredAccountCapacityMap(pool)).reduce((total, value) => total + value, 0);
|
|
}
|
|
|
|
export function desiredAccountCapacityMap(pool: CodexPoolConfig): Record<string, number> {
|
|
const codexDir = join(homedir(), ".codex");
|
|
const seenAccountNames = new Set<string>();
|
|
const capacities: Record<string, number> = {};
|
|
for (const entry of pool.profiles) {
|
|
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
|
|
seenAccountNames.add(accountName);
|
|
capacities[accountName] = entry.capacity ?? pool.defaultAccountCapacity;
|
|
}
|
|
return capacities;
|
|
}
|
|
|
|
export function desiredAccountLoadFactorMap(pool: CodexPoolConfig): Record<string, number> {
|
|
const codexDir = join(homedir(), ".codex");
|
|
const seenAccountNames = new Set<string>();
|
|
const loadFactors: Record<string, number> = {};
|
|
for (const entry of pool.profiles) {
|
|
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
|
|
seenAccountNames.add(accountName);
|
|
loadFactors[accountName] = entry.loadFactor ?? pool.defaultAccountLoadFactor;
|
|
}
|
|
return loadFactors;
|
|
}
|
|
|
|
export function desiredAccountWebSocketsV2ModeMap(pool: CodexPoolConfig): Record<string, OpenAIResponsesWebSocketsV2Mode | null> {
|
|
const codexDir = join(homedir(), ".codex");
|
|
const seenAccountNames = new Set<string>();
|
|
const modes: Record<string, OpenAIResponsesWebSocketsV2Mode | null> = {};
|
|
for (const entry of pool.profiles) {
|
|
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
|
|
seenAccountNames.add(accountName);
|
|
modes[accountName] = entry.openaiResponsesWebSocketsV2Mode;
|
|
}
|
|
return modes;
|
|
}
|
|
|
|
export function desiredAccountTempUnschedulableMap(pool: CodexPoolConfig): Record<string, unknown> {
|
|
const codexDir = join(homedir(), ".codex");
|
|
const seenAccountNames = new Set<string>();
|
|
const policies: Record<string, unknown> = {};
|
|
for (const entry of pool.profiles) {
|
|
const accountName = entry.accountName ?? uniqueAccountName(entry.profile, seenAccountNames);
|
|
seenAccountNames.add(accountName);
|
|
policies[accountName] = renderSub2ApiTempUnschedulableCredentials(entry.tempUnschedulable);
|
|
}
|
|
return policies;
|
|
}
|