Skip to content

TypeScript SDK

Terminal window
npm install @pensievelab/sdk
import Pensieve from "@pensievelab/sdk";
const pensieve = new Pensieve(); // reads PENSIEVE_API_KEY
const decision = await pensieve.models.decide("grade-audit", { input: trial, key: trial.task });

It has no dependencies, and runs on Node 18 and later, in browsers and on edge runtimes. Types for every request and answer are generated from the OpenAPI spec.

new Pensieve({
apiKey: "pk_test_yourname", // or PENSIEVE_API_KEY
baseURL: "https://api.pensievelabs.co", // or PENSIEVE_BASE_URL
timeout: 60_000, // milliseconds per try
maxRetries: 2,
fetch: customFetch, // any fetch-compatible function
defaultHeaders: {},
webhookSecret: "whsec_...", // or PENSIEVE_WEBHOOK_SECRET
onError: (error) => {}, // errors from capture's background work
});

Any call takes these options as its last argument: { idempotencyKey, timeout, maxRetries, signal, headers }.

Path ids come first, then an object of fields named as in the API.

Resource Methods
models list, retrieve, update, decide
models.routing update
models.versions list, retrieve, weights
batches create, retrieve, createAndWait
calls list, retrieve
outcomes send, sendMany
corrections send
captures create
tests retrieve
tests.cases list, add
experiments list, start, retrieve, stop
experiments.runs list
methods list, create, retrieve, update, remove
releases list, shadow, retrieve, signoff, split, promote, stop, rollback
review list, retrieve, answer
tasks create
frontier list
sources list, connect, retrieve, update, remove
keys list, create, revoke
members list, invite, update, remove
usage retrieve
webhooks list, create, remove, unwrap, sign
events list
workspace retrieve

Plus pensieve.capture(model, fn, options) and pensieve.flush(): see Record the calls you make today.

Await a list for one page, or loop over it for every item across pages:

const page = await pensieve.calls.list({ model: "grade-audit", limit: 50 });
page.data; // this page
if (page.hasNextPage()) {
const next = await page.getNextPage();
}
for await (const call of pensieve.calls.list({ model: "grade-audit" })) {
// every call, fetched a page at a time
}
const { data, response, requestId } = await pensieve.models.retrieve("grade-audit").withResponse();

Every error is a class you can catch. API errors carry status, type, param and requestId:

import { ConflictError } from "@pensievelab/sdk";
try {
await pensieve.releases.promote(release.id, { expect: "v7" });
} catch (error) {
if (error instanceof ConflictError) console.log(error.param, error.message);
else throw error;
}

BadRequestError 400, AuthenticationError 401, PermissionDeniedError 403, NotFoundError 404, ConflictError 409, RateLimitError 429, NotAvailableError 501, InternalServerError 5xx, and APIConnectionError, APITimeoutError and APIUserAbortError when no answer came back. See Errors and retries.

const event = await pensieve.webhooks.unwrap(rawBody, request.headers); // checks the signature and age

See Webhooks and events.