Files
bot-agents/profiles.ts
T
Danny Kim 7bae0d7237
Check / deno (pull_request) Successful in 36s
Centralize encrypted bot profiles
2026-09-24 05:00:02 +09:00

84 lines
2.1 KiB
TypeScript

export type BotProfile = {
type: "claude" | "codex";
model: string;
token?: string;
};
function isUsageExhausted(error: unknown): boolean {
return /(?:usage|rate) limit|hit your limit|insufficient_quota|exceeded your current quota|too many requests|(?:api error|http error|http|status(?: code)?)[ :]+4(?:02|29)\b/i
.test(String(error));
}
export async function runProfiles<
T,
P extends Pick<BotProfile, "type" | "model">,
>(
profiles: P[],
attempt: (profile: P) => Promise<T>,
): Promise<T> {
for (const [index, profile] of profiles.entries()) {
try {
return await attempt(profile);
} catch (error) {
if (!isUsageExhausted(error) || index === profiles.length - 1) {
throw error;
}
console.error(`${profile.type} usage exhausted; trying next profile`);
}
}
throw new Error("profiles must contain at least one profile");
}
export function sanitizedEnvironment(
environment: Record<string, string>,
): Record<string, string> {
const result: Record<string, string> = {};
for (
const name of [
"PATH",
"HOME",
"LANG",
"LANGUAGE",
"LC_ALL",
"TERM",
"COLORTERM",
"CI",
"TMPDIR",
"GITEA_TOKEN",
"GITEA_API_URL",
"GITEA_REPOSITORY",
"GITHUB_WORKSPACE",
"HTTP_PROXY",
"HTTPS_PROXY",
"ALL_PROXY",
"NO_PROXY",
"http_proxy",
"https_proxy",
"all_proxy",
"no_proxy",
"SSL_CERT_FILE",
"SSL_CERT_DIR",
"NODE_EXTRA_CA_CERTS",
]
) {
if (environment[name] !== undefined) result[name] = environment[name];
}
return result;
}
export function agentEnvironment(
environment: Record<string, string>,
profile: Pick<BotProfile, "type"> & { home: string },
token?: string,
): Record<string, string> {
const result = sanitizedEnvironment(environment);
result.HOME = profile.home;
if (profile.type === "codex") result.CODEX_HOME = `${profile.home}/.codex`;
if (token) {
result[
profile.type === "claude" ? "CLAUDE_CODE_OAUTH_TOKEN" : "OPENAI_API_KEY"
] = token;
}
return result;
}