resolveEffectiveCliArgs function
Provider/model restoration. Precedence: an explicit --provider flag
(full manual control, preconfigs disabled) > the FA_PROVIDER_* env
declaration (faProviderPreconfig) > the saved provider: (the
persisted /provider switch) > the parsed default. Only kinds the legacy
single-model path can build are restored (chatgpt-codex keeps the
openai-completions default; its OAuth flow re-establishes on demand).
The preconfig supplies model/baseUrl too, so the saved restore never
leaks through while it is active (--model/--base-url flags still
override individual fields). No env-key auto-pick: a bare API key in
the environment never activates a provider — the model would be an
implicit default, and providers carry none by design. FA_PROVIDER_*
stays: it names the model explicitly.
The environment is injected (env is required): the CLI passes
Platform.environment, tests pass exactly the map they mean —
resolution never reads ambient process state.
Returns the effective CliArgs, the resolved provider kind — the same
value, the explicit record field saves the caller a re-derivation — and
the FA_PROVIDER_* declaration when one is active (the caller needs it
for the roles pinning, the key decision and the extra redaction).
Implementation
({CliArgs args, String provider, EnvProviderPreconfig? faPreconfig})
resolveEffectiveCliArgs(
CliArgs parsed,
CliConfig saved, {
required Map<String, String> env,
}) {
const restorableKinds = {
'openai-completions',
'anthropic',
'google',
'dial',
'minimax',
'zai',
};
final faPreconfig = faProviderPreconfig(parsed, saved, env: env);
final provider = parsed.providerExplicit
? parsed.provider
: faPreconfig?.spec.kind ??
(restorableKinds.contains(saved.providerKind)
? saved.providerKind
: parsed.provider);
final modelId = parsed.model ?? faPreconfig?.modelId ?? saved.modelId;
final baseUrl = parsed.baseUrl ?? faPreconfig?.baseUrl ?? saved.baseUrl;
final effective = CliArgs(
model: modelId,
provider: provider,
baseUrl: baseUrl,
visionModel: parsed.visionModel,
visionBaseUrl: parsed.visionBaseUrl,
transcribeModel: parsed.transcribeModel,
transcribeBaseUrl: parsed.transcribeBaseUrl,
plugins: parsed.plugins,
promptTemplateDirs: parsed.promptTemplateDirs,
mode: parsed.mode ?? saved.mode,
tools: parsed.tools,
redact: parsed.redact ?? saved.redact,
cwd: parsed.cwd,
sessionRoot: parsed.sessionRoot,
session: parsed.session,
);
return (args: effective, provider: provider, faPreconfig: faPreconfig);
}