fix(core): harden env loading, OpenAI compatibility, and runtime recovery

This commit is contained in:
William Valentin
2026-02-22 15:56:21 -08:00
parent 387906ce4d
commit dafe9b4d3d
11 changed files with 450 additions and 21 deletions
+46
View File
@@ -484,6 +484,52 @@ models:
}
});
it('loads env vars from FLYNN_ENV_FILE before env-var checks', async () => {
const originalEnvFile = process.env.FLYNN_ENV_FILE;
const originalOpenAIKey = process.env.OPENAI_API_KEY;
delete process.env.OPENAI_API_KEY;
try {
mkdirSync(testDir, { recursive: true });
const envPath = join(testDir, 'cloud.env');
writeFileSync(envPath, 'OPENAI_API_KEY=sk-test-from-env-file\n');
process.env.FLYNN_ENV_FILE = envPath;
const configPath = join(testDir, 'openai-env-file.yaml');
writeFileSync(configPath, `
telegram:
bot_token: "test-token"
allowed_chat_ids: [123]
models:
default:
provider: openai
model: gpt-5.2
auth_mode: api_key
api_key: \${OPENAI_API_KEY}
`);
const ctx: DoctorContext = { configPath, dataDir: testDir };
const results = await runChecks(ctx);
const envCheck = results.find((r) => r.label.includes('Env vars resolved')) as CheckResult | undefined;
const modelCheck = results.find((r) => r.label.includes('Model connectivity')) as CheckResult | undefined;
expect(envCheck?.status).toBe('pass');
expect(modelCheck?.status).toBe('pass');
expect(modelCheck?.detail).toContain('api_key=config+env');
} finally {
if (originalEnvFile !== undefined) {
process.env.FLYNN_ENV_FILE = originalEnvFile;
} else {
delete process.env.FLYNN_ENV_FILE;
}
if (originalOpenAIKey !== undefined) {
process.env.OPENAI_API_KEY = originalOpenAIKey;
} else {
delete process.env.OPENAI_API_KEY;
}
}
});
it('reports WARN when Vercel AI Gateway has no available API key sources', async () => {
const originalKey = process.env.AI_GATEWAY_API_KEY;
delete process.env.AI_GATEWAY_API_KEY;