Files
shockbot/test/agnostic/byokFallback.ts
T
Colin McDonnell e52206b8ca test: switch opus defaults to sonnet/kimi for cheaper coverage
- opencode test default: claude-sonnet-4-6 → moonshotai/kimi-k2. claude-code
  default stays on sonnet (the agent-under-test for that path is Claude
  Code); the opencode path doesn't need an Anthropic model.
- byok-no-keys-fallback fixture: anthropic/claude-opus → moonshotai/kimi-k2.
  test verifies fallback to opencode/big-pickle, so the configured model
  is never invoked; picking a non-opus alias avoids burning credits if
  the fallback ever regresses.
- BEDROCK_MODEL_ID in both test workflows: us.anthropic.claude-opus-4-6-v1
  → us.anthropic.claude-sonnet-4-6. env var is required by the ci.test
  invariant that every provider's env vars are wired into the workflow.
2026-05-23 01:07:20 +00:00

76 lines
2.6 KiB
TypeScript

import type { AgentResult, TestRunnerOptions, ValidationCheck } from "../utils.ts";
import { defineFixture, getAgentOutput } from "../utils.ts";
/**
* BYOK-no-keys fallback test — proves that an account configured for a
* BYOK model (here: `moonshotai/kimi-k2`) but with no provider API
* keys present in the runner env still gets a successful run by falling
* back to a free OpenCode model.
*
* This was the structural failure that took out 15 accounts post-launch
* before the fallback shipped: GH Actions secret references resolved to
* empty strings (because the secrets didn't exist), the action launched
* Claude Code with no key, the LLM provider 401'd, and the run died in
* 20s with a synthesized "Invalid API key" message.
*
* The env block below empty-strings every known provider key — that's
* exactly what GitHub Actions does when a `${{ secrets.X }}` reference
* resolves to a missing secret. We verify:
* 1. the run succeeded
* 2. the fallback log line was emitted (proves the swap happened)
*/
const fixture = defineFixture(
{
prompt: "Reply with exactly the single character: 4",
timeout: "5m",
},
{ localOnly: true }
);
function validator(result: AgentResult): ValidationCheck[] {
const output = getAgentOutput(result);
const fellBack = /fell back from .* to opencode\/big-pickle/.test(output);
return [
{ name: "run_succeeded", passed: result.success },
{ name: "fallback_logged", passed: fellBack },
];
}
export const test: TestRunnerOptions = {
name: "byok-no-keys-fallback",
fixture,
validator,
env: {
// simulate every BYOK provider's secret being absent — same shape as
// a fresh-install account whose user never configured any keys.
ANTHROPIC_API_KEY: "",
CLAUDE_CODE_OAUTH_TOKEN: "",
OPENAI_API_KEY: "",
OPENROUTER_API_KEY: "",
GEMINI_API_KEY: "",
GOOGLE_GENERATIVE_AI_API_KEY: "",
XAI_API_KEY: "",
DEEPSEEK_API_KEY: "",
MOONSHOT_API_KEY: "",
OPENCODE_API_KEY: "",
AWS_BEARER_TOKEN_BEDROCK: "",
AWS_ACCESS_KEY_ID: "",
AWS_SECRET_ACCESS_KEY: "",
BEDROCK_MODEL_ID: "",
// configure a model that requires a BYOK key — the fallback only
// engages when there's a configured model whose provider key is
// absent, so we have to pin one. any BYOK alias works; we pick
// a cheap non-Anthropic model so the test doesn't burn opus
// credits if the fallback ever regresses.
PULLFROG_MODEL: "moonshotai/kimi-k2",
},
tags: ["agnostic"],
coverage: [
"action/utils/byokFallback.ts",
"action/utils/apiKeys.ts",
"action/utils/agent.ts",
"action/main.ts",
"action/models.ts",
],
};