fix(providers): route diagnostics through buildGatewayConfig so file-plane keys are visible (#3000)

configureFromEnv() hand-assembled its own AIGatewayConfig instead of calling
buildGatewayConfig(), the single seam that folds file-plane API keys
(openrouter_api_key, zeroentropy_api_key, ...) into the gateway env. That let
`gbrain providers list`/`test` report a provider as missing env even when it
was correctly set in ~/.gbrain/config.json and the real gateway path resolved
it fine. Both configureFromEnv() and runList() now build their env through
buildGatewayConfig() (falling back to a bare process.env passthrough
pre-init), matching what init-provider-picker.ts already does.
This commit is contained in:
hhamilton-fv
2026-07-20 13:07:27 -07:00
committed by GitHub
parent 4528bfa79c
commit f3e78fd2fb
+20 -11
View File
@@ -9,6 +9,7 @@ import { listRecipes, getRecipe } from '../core/ai/recipes/index.ts';
import { configureGateway, embedOne, isAvailable as gwIsAvailable, chat as gwChat } from '../core/ai/gateway.ts';
import { probeOllama, probeLMStudio } from '../core/ai/probes.ts';
import { loadConfig } from '../core/config.ts';
import { buildGatewayConfig } from '../core/ai/build-gateway-config.ts';
import { AIConfigError, AITransientError } from '../core/ai/errors.ts';
import type { Recipe } from '../core/ai/types.ts';
@@ -33,16 +34,19 @@ interface ProviderOption {
function configureFromEnv(): void {
const config = loadConfig();
configureGateway({
embedding_model: config?.embedding_model,
embedding_dimensions: config?.embedding_dimensions,
expansion_model: config?.expansion_model,
chat_model: config?.chat_model,
chat_fallback_chain: config?.chat_fallback_chain,
base_urls: config?.provider_base_urls,
provider_chat_options: config?.provider_chat_options,
env: { ...process.env },
});
// Route through buildGatewayConfig — the single ownership seam that folds
// file-plane API keys (openrouter_api_key, zeroentropy_api_key, ...) into
// the gateway env — instead of hand-assembling AIGatewayConfig field by
// field. Hand-building it here let this diagnostic report a provider as
// missing env even when ~/.gbrain/config.json had it and the real gateway
// path resolved it fine (#2728). Pre-init (no file-plane config yet) falls
// back to a bare env passthrough so the command still works before
// `gbrain init`.
if (config) {
configureGateway(buildGatewayConfig(config));
return;
}
configureGateway({ env: { ...process.env } });
}
export function envReady(recipe: Recipe, env: NodeJS.ProcessEnv = process.env): boolean {
@@ -137,7 +141,12 @@ EXAMPLES
}
function runList(_args: string[]): void {
console.log(formatRecipeTable(listRecipes()));
// Same env the gateway actually sees (file-plane keys folded in), not bare
// process.env — keeps this table's STATUS column honest with what
// `providers test` (and the real init/gateway path) would report.
const cfg = loadConfig();
const env = cfg ? buildGatewayConfig(cfg).env : process.env;
console.log(formatRecipeTable(listRecipes(), env));
}
async function runTest(args: string[]): Promise<void> {