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.
The saved kind restores whenever it resolves through the catalog
(resolveCliProviderSpec — every catalog name AND adapter kind,
chatgpt-codex included; coverage by construction, issue #760) and
restores AS THE RESOLVED SPEC'S KIND: a saved catalog name (openai,
chatgpt) resolves to its adapter kind here, because everything
downstream (AgentCliConfig.providerKind → providerStreamFunction)
speaks kinds only. A
saved id NO version knows must never brick the boot: it is reported
back as unknownSavedProvider and the parsed default (a known
provider) takes over — the executable prints the loud named warning
(bad value, file, fallback taken) and keeps booting.
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 — the
FA_PROVIDER_* declaration when one is active (the caller needs it
for the roles pinning, the key decision and the extra redaction), the
saved provider id when it was unrecognizable, and the saved provider id
when the persisted provider/baseUrl pair was unservable (endpoint-locked
kind, foreign baseUrl — the caller degrades it with a named warning).
Both report fields are null otherwise.
Implementation
({
CliArgs args,
String provider,
EnvProviderPreconfig? faPreconfig,
String? unknownSavedProvider,
String? incompatibleSavedEndpoint,
})
resolveEffectiveCliArgs(
CliArgs parsed,
CliConfig saved, {
required Map<String, String> env,
}) {
final faPreconfig = faProviderPreconfig(parsed, saved, env: env);
final restore = _judgeSavedRestore(saved);
final restoredKind = restore.endpointConflict ? null : restore.spec?.kind;
final provider = _bootProvider(
parsed: parsed,
faPreconfig: faPreconfig,
restoredKind: restoredKind,
);
final reports = _savedRestoreReports(
savedRaw: restore.raw,
savedSpec: restore.spec,
endpointConflict: restore.endpointConflict,
explicitOverride: parsed.providerExplicit || faPreconfig != null,
);
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,
unknownSavedProvider: reports.unknownSavedProvider,
incompatibleSavedEndpoint: reports.incompatibleSavedEndpoint,
);
}