ask
suspend fun ask(prompt: String, generate: suspend (String) -> AiResult<String>): AiResult<T>(source)
Runs prompt (with a schema hint appended) through generate. Parses the reply as T; on a malformed reply, retries once with the bad reply and a "fix your JSON" nudge appended. A failure from generate itself (network, timeout, no key) is not a parse problem and is returned as-is with no retry — retrying a call that already told you why it failed just spends another round trip for the same answer.