Show the selected bot profile and add OpenRouter fallback (#18)

Uses Codex first, then Claude, then OpenCode through OpenRouter when quota is exhausted.

Every generated comment and review now identifies the selected profile and model in a final quote. The dependent action interface remains one master key.

Verified formatting, lint, type checks, encrypted profile decryption, current OpenCode CLI flags, and 45 tests.

Reviewed-on: #18
Reviewed-by: bot <noreply@capsulizers.com>
Co-authored-by: Danny Kim <temeddix@gmail.com>
Co-committed-by: Danny Kim <temeddix@gmail.com>
This commit was merged in pull request #18.
This commit is contained in:
Danny Kim
2026-09-24 01:39:49 +00:00
committed by temeddix
parent 4ecdf5adc0
commit ea20f6d629
13 changed files with 429 additions and 78 deletions
+20 -4
View File
@@ -1,9 +1,22 @@
export type BotProfile = {
type: "claude" | "codex";
type: "claude" | "codex" | "opencode";
model: string;
token?: string;
};
export function profileFooter(
profile: Pick<BotProfile, "type" | "model">,
): string {
return `> Profile: \`${profile.type}\` · \`${profile.model}\``;
}
export function withProfile(
body: string,
profile: Pick<BotProfile, "type" | "model">,
): string {
return `${body}\n\n${profileFooter(profile)}`;
}
function isUsageExhausted(error: unknown): boolean {
return /(?:usage|rate) limit|hit your (?:weekly )?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));
@@ -75,9 +88,12 @@ export function agentEnvironment(
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;
const tokenName = {
claude: "CLAUDE_CODE_OAUTH_TOKEN",
codex: "OPENAI_API_KEY",
opencode: "OPENROUTER_API_KEY",
}[profile.type];
result[tokenName] = token;
}
return result;
}