Yolo is Bun's internal typed decision capability. bun:yolo turns named Noul, Choice and Score answers into JavaScript primitives. bun:Yolo resolves to the same module. Rust validates question types, answer names, enum keys and finite numeric bounds before returning a value.
import Yolo, { code, noul } from "bun:yolo";
const provider = code(request => ({
model: "public-access-rule",
answers: {
answer: { type: "noul", noul: (request.state as { visibility: string }).visibility === "public" ? 1 : 0 },
},
usage: null,
}));
if (await Yolo({ visibility: "public" }, noul("Is this resource public?"), { provider })) {
console.log("read allowed");
}
The result is a primitive boolean; false takes the false branch. A Noul becomes true only when its probability is greater than threshold, which defaults to 0.5. Use inspect when the probability itself matters. A judgment does not authorize side effects: deterministic access rules remain in application code.
Named batches
import { decide, noul, choice, score, type Provider } from "bun:yolo";
export async function decideSources(provider: Provider) {
return await decide(
{
state: { query: "How does Bun.Video resize frames?", passage: "Bun.Video provides transformed frames." },
questions: {
relevant: noul("Does `passage` help answer `query`?"),
route: choice("Which public source fits `query`?", {
docs: "API documentation",
graph: "Relationships between source symbols",
none: "Neither source fits",
}),
evidence: score("How much support does `passage` provide for `query`?", [
"No supporting information",
"Information about the API, without the requested details",
"Information directly answering the requested details",
]),
},
},
{ provider, timeout: 10000, maxRetries: 0 },
);
}
// relevant: boolean; route: "docs" | "graph" | "none"; evidence: number in 0..2
Omitting provider selects remote(). A deterministic code fixture demonstrates the protocol; it does not perform a language judgment or qualify a model. All questions for one state share one provider request. Choice supports 2–255 named options. Score supports 2–10 ordered criteria and may return a fractional value between zero and the final index. Batches contain 1–64 questions. Request and response JSON are each limited to 1 MiB. Internal descriptors preserve the full public byte budget. Unknown answer names, choice keys, wrong legends and numbers outside their range throw.
inspect(request, options) returns the validated { model, answers, usage } response. systemOne aliases inspect. value(answer, question, threshold?) validates one answer and returns its primitive.
Request and response model names must contain a non-whitespace character and fit within 256 UTF-8 bytes. Rust validates request overrides before provider I/O, using the same model bounds as response validation.
Application-owned providers
An application can supply a Provider that owns its transport, credentials and model lifetime. code(evaluate) adapts a synchronous or asynchronous callback to this contract. The callback returns the raw named response; Rust still validates the request, answer distributions and primitive conversion. Keep provider configuration in protected server-side stores and inject only the qualified transport needed by the application.
remote({ baseURL?, model?, client? }) uses native HTTP by default. It reads TYPESAFE_API_KEY from the server environment. The endpoint root is baseURL, then TYPESAFE_BASE_URL, then https://api.typesafe.ai. The model is the request's model, the provider's model, TYPESAFE_DEFAULT_MODEL, then jev-latest. Requests use /v1/systemone. Endpoints require HTTPS; loopback HTTP supports local services and tests. URL credentials, query strings, fragments and redirects reject.
Supplying client delegates transport and retries to its systemOne method. Configure the endpoint on that client; baseURL cannot accompany client. Native HTTP retries statuses 408, 429 and 5xx within maxRetries and the operation deadline. Authentication failures reject without retrying. Response bodies are bounded while streaming and must contain valid UTF-8 JSON.
This interface supplies structured decisions, not conversation generation. Native validation does not qualify provider accuracy, calibration, trained weights or a published inference service. See typed decision boundaries for confidence, abstention and the supervised Python bridge.
timeout bounds the whole operation, including serialization and pending retries, to 1–120000 ms. Synchronous callbacks cannot be interrupted; their result rejects once control returns after the deadline. maxRetries is an integer from zero to three, default zero. Providers receive the deadline, retry limit and cancellation signal. Connection and authentication failures reject. An AbortSignal cancels the request and settles the caller even when a custom provider does not complete.
Existing local models
local({ context, model, maxTokens? }) accepts a loaded bun-llama context. The caller selects the protected GGUF path and owns the context/model lifetime. No weights are downloaded or bundled into the core.
The adapter requests strict JSON at temperature zero, caps generation at 1–4096 tokens (default 1024), and sends every answer through the same Rust validator. Markdown, explanatory text and responses outside the schema reject. Local adapters sharing a context accept one active request at a time. After cancellation or timeout, the context remains busy until its complete call settles. Token usage is null because the context does not expose exact accounting. Local probabilities are model outputs; calibration requires separate evidence. Grammar-constrained decoding depends on the local provider's capabilities and is not claimed by this adapter.
Optional providers require their credentials, native library and model to be available. Core validation and deterministic code providers work without those extensions.