ai.clients.resolve

Resolve a `Selector` to the client to call, at CALL time.

Reference version

Signature

function ai.clients.resolve<__effect_param_0>(
providers: (string, string) -> ai.Client | null throws __effect_param_0,
prefixes: string[]
) -> ai.Client throws baml.errors.Io | baml.errors.ParseError | ai.errors.InvalidRequest | __effect_param_0

Resolve a Selector to the client to call, at CALL time.

  • a ai.Client is returned unchanged (identity);
  • a string is the "provider/model" shorthand, constructed through providers — the runtime twin of the compiler's literal-client: lowering. An unknown prefix throws ai.errors.InvalidRequest listing the valid ones;
  • a baml.env.Ref is read now and its value takes the string path. An UNSET variable is a typed ai.errors.InvalidRequest naming it — not a panic, so a catch_all at the call boundary can still fall back.

Write it as ai.clients.resolve(selector): the call is compiler-assisted. Only the compiler knows every provider (each provider package depends on this one, so this package cannot name them), so at every call site it appends providers — constructing the client for a prefix and model, or null for a prefix it does not know — and prefixes, the prefixes it knows, both synthesized from the one provider table the literal client "provider/model" lowering reads.

This is what makes client: env.MODEL.get() ?? "openai/gpt-4o-mini" work: nothing about the selection is decided until the call happens.

Source:<builtin>/ai/ns_clients/clients.bamlbytes 20793045