Resources
JavaScript SDK
The launchables package for Node: install, ask, handle errors.
The launchables package is the JavaScript and TypeScript client for the Decision API. It is ESM, includes TypeScript types, has no runtime dependencies and runs on Node 18 or later (it uses the global fetch). It calls the Myles-G models over HTTP; it does not run the CPU models (see Model types).
npm install launchables
Keep your API key on a server. The client refuses to start in a browser, because a key in a web page or app is public.
Authentication
The client reads your key from the LAUNCHABLES_API_TOKEN environment variable, or you can pass it as apiKey. Get a key in the console.
export LAUNCHABLES_API_TOKEN=launchables_...
Ask a question
import { Launchables, noul } from "launchables";
const client = new Launchables(); // reads LAUNCHABLES_API_TOKEN
const resp = await client.decide(
"Customer bought the item 12 days ago and has no receipt. Policy: refunds within 30 days with proof of purchase.",
{ refund: noul("Is a refund permitted under the policy?") },
);
const answer = resp.answers.refund;
console.log(answer.probability); // probability of yes, e.g. 0.04
console.log(answer.decide({ thresholdYes: 0.9, thresholdNo: 0.1 })); // "yes", "no" or "person"
console.log(resp.usage.input_tokens, resp.model);
decide(state, questions, model?) returns { model, answers, usage, raw }. The state can be a string or an object. Answers are typed from the questions you ask, so resp.answers.refund above is a yes-or-no answer.
Question types
import { noul, choice, score } from "launchables";
const resp = await client.decide(state, {
refund: noul("Is a refund permitted?", { true: "Policy clearly allows it", false: "Policy clearly forbids it" }),
topic: choice("What is this about?", ["billing", "returns", "other"]), // or { label: description }
urgency: score("How urgent is it?", ["not urgent", "low", "medium", "high"]), // lowest level first, numbered from 0
});
resp.answers.topic.choice; // "returns"
resp.answers.topic.probabilities; // { billing: 0.06, returns: 0.89, ... }
resp.answers.urgency.level; // 2
resp.answers.urgency.score; // 1.92
The helpers check your questions before anything is sent and throw ValidationError if a request would be refused: at most 16 questions a request, at most 26 options a choice, and instructions that are not empty. See Question types for what each type returns.
Images
From version 0.4.0, the third argument of decide can be options, { model, assets, imageBudget }, as well as a model name. Pass images in assets under a reference and write the reference where the model should see the image (Myles-G 12B; for Myles-G 31B, also pass model: "myles-g-31b" and construct the client with baseURL set to https://gw.launchables.ai):
import { Launchables, imageFromPath, noul } from "launchables";
const resp = await client.decide(
{ receipt: "receipt_photo" },
{ total_matches: noul("Does the total printed on receipt_photo equal 23.40?") },
{ assets: { receipt_photo: await imageFromPath("receipt.jpg") }, imageBudget: 140 }, // budget: 70, 140 or 280
);
imageFromPath and imageFromBytes detect PNG or JPEG from the bytes and throw ValidationError for anything else or anything over 16 MiB; decide throws it for an imageBudget other than 70, 140 or 280. The server's image errors arrive as InvalidRequestError with a type such as image_dimensions. See Images for references, limits and billing.
Other calls
await client.models(); // [{ id: "myles-g-12b", object: "model", owned_by: "launchables" }]
await client.health(); // { status: "ok" }
models() and health() need no key.
Options
| Option | What it does |
|---|---|
apiKey | Your API key. Defaults to LAUNCHABLES_API_TOKEN. |
baseURL | Set it for an endpoint you host yourself. Defaults to the hosted API. |
timeout | Milliseconds allowed for each attempt. Default 30000. |
maxRetries | Retries after the first attempt, for 429, 502, 503 and connection errors. Default 3. |
const client = new Launchables({ apiKey: "launchables_...", timeout: 10_000, maxRetries: 5 });
Retries wait 0.5, 1 and 2 seconds, or as long as a Retry-After header asks, up to 60 seconds. Other errors are thrown straight away.
Errors
Every error extends LaunchablesError and carries status, serverMessage, body and type, the server's error type such as "out_of_credit".
| Error | When |
|---|---|
AuthenticationError | 401, or no key given or found |
OutOfCreditError | 402: the organisation has run out of credit (type "out_of_credit"), or the key's workspace has reached its monthly budget ("budget_exceeded") |
PermissionDeniedError | 403: the key's workspace may not use this model ("model_not_allowed") |
RateLimitError | 429, with retryAfter in seconds when the server sends it |
InvalidRequestError | 400, 411, 413, 422 and other 4xx; ValidationError is the check made before sending |
APIError | 5xx |
APIConnectionError | The endpoint could not be reached, including timeouts |
import { OutOfCreditError, RateLimitError, InvalidRequestError, LaunchablesError } from "launchables";
try {
await client.decide(state, questions);
} catch (e) {
if (e instanceof OutOfCreditError) console.log(e.type === "budget_exceeded" ? "workspace budget reached" : "top up credit");
else if (e instanceof RateLimitError) console.log("slow down", e.retryAfter);
else if (e instanceof InvalidRequestError) console.log(e.status, e.serverMessage);
else if (e instanceof LaunchablesError) console.log("failed:", e.message);
else throw e;
}
OutOfCreditError and PermissionDeniedError were added in version 0.1.1, the current release. On 0.1.0, a 402 or 403 is an InvalidRequestError; check status, or update with npm install launchables@latest.
Python
A Python package is coming. Until then, call the API directly; see Code samples.