@labelbox/recursion-sdk
v0.0.275
Published
The Recursion TypeScript SDK, **generated from the backend OpenAPI spec** with [`@hey-api/openapi-ts`](https://heyapi.dev). Almost the entire package is generated — the only hand-written code is the path reader (`src/nesting.ts`) and a thin auth construct
Maintainers
Keywords
Readme
@labelbox/recursion-sdk
The Recursion TypeScript SDK, generated from the backend OpenAPI spec with
@hey-api/openapi-ts. Almost the entire package is
generated — the only hand-written code is the path reader (src/nesting.ts) and
a thin auth constructor (src/index.ts).
import { createRecursionClient } from '@labelbox/recursion-sdk';
const rl = createRecursionClient({ apiKey: process.env.LABELBOX_API_KEY });
const job = await rl.synthesizers.create({
environmentId: 'env_…',
body: { name: 'Variant generator', systemPrompt: '…' },
});Install
Published to public npm as @labelbox/recursion-sdk — no registry configuration,
repository access, or install-time credential is needed:
npm install @labelbox/recursion-sdkFull setup steps:
apps/horizon/docs/public/docs/ts-sdk-getting-started.md. The SDK releases independently
of the CLI: a packages/sdk-ts/** change (e.g. a committed openapi.json update)
cuts an SDK release via the Release / SDK GitHub Action — see yarn commands release.
Surface
Calls use flat params — path/query values and the request body are all top-level
keys of a single options argument; the request body sits under body.
Instance-based: rl.<namespace>.<method>(...).
The body param would otherwise be named after its DTO (e.g.
createSynthesizerJobBodyDto) — yarn generate sdk renames it to body via a
deterministic post-pass (normalizeGeneratedClient in
tools/dx/src/commands/sdk.ts), since hey-api offers no lever for this. The same
guarded pass narrows hey-api's generic whole-slot map type to body after proving
that the generated SDK emits no header, path, or query slot mappings.
Opt-in, declared at the source. An operation is in the SDK iff its backend
handler carries @SdkRoute(...segments) (apps/horizon/api/src/common/sdk-route.decorator.ts),
which emits an x-sdk-path OpenAPI extension. @SdkRoute('synthesizers', 'create')
→ rl.synthesizers.create(...). There is no heuristic and no per-operation
code here — src/nesting.ts just reads the declared paths and asserts (at
codegen time) that every path is unique and a valid identifier. Endpoints without
@SdkRoute are not generated (that is also how you exclude one).
Scope grows by annotating more handlers — e.g. the synthesizer tag is exposed
as rl.synthesizers (jobs) and rl.synthesizerRuns (runs).
Regenerating
# Regenerate the client + the SDK reference docs from the committed spec snapshot.
yarn generate sdk
# Also re-dump the spec snapshot (packages/sdk-ts/openapi.json) from the backend first.
yarn generate sdk --refresh-specsrc/generated/** and src/reference/*.generated.ts are git-ignored. Regenerate
them from the committed openapi.json with yarn generate prerequisites. Cold installs
also generate them through root postinstall → yarn build libs; warm-cache builds and
checks that consume them explicitly own generation in their task or workflow. The shared
setup-node-yarn action only installs dependencies. Never hand-edit generated output;
only openapi.json is committed.
Generation choices (and why)
bundle: true— the fetch runtime is vendored intosrc/generatedso the SDK is self-contained and version-locked to the generator (the standalone@hey-api/client-fetchpackage drifts independently).@hey-api/client-fetchis therefore a devDependency, used only at generation time.output.importFileExtension: '.js'— makes generated relative imports compatible with the repo'smoduleResolution: NodeNext.- No
exactOptionalPropertyTypes: true(tsconfig) — the vendored fetch runtime does not satisfy this flag, so this package leaves it off (defaulting to false) while every other package in the repo opts in explicitly. It is the one strictness relaxation this generated-heavy package makes; hand-written code stays clean. src/generatedexcluded from Biome — generated output is not linted; its determinism is what the freshness check relies on.
Docs
The generated SDK reference shown in the in-app API docs is derived from the
same spec by yarn generate sdk into this package's ./reference export
(SDK_REFERENCE, with its ./schema shape), keyed by operationId so each
operation's doc page renders its TS SDK / CLI / cURL examples.
