@labelbox/rl-cli
v0.0.40
Published
`rl` — the rl-gym command-line interface. It mirrors the TypeScript SDK (`@labelbox/rl-sdk`) exactly: where the SDK is `rl.synthesizers.create(...)`, the CLI is `rl synthesizers create …`. Dots become spaces; you get `--help` at every level.
Maintainers
Keywords
Readme
@labelbox/rl-cli
rl — the rl-gym command-line interface. It mirrors the TypeScript SDK
(@labelbox/rl-sdk) exactly: where the SDK is rl.synthesizers.create(...), the
CLI is rl synthesizers create …. Dots become spaces; you get --help at every
level.
rl --help # list nouns (synthesizers, synthesizer-runs)
rl synthesizers --help # list verbs (create, get, list, …)
rl synthesizers create --help # list flagsHow it works (fully live, zero per-operation code)
The CLI ships no baked API reference and has no @labelbox/rl-sdk dependency.
On each run it fetches a manifest from GET /cli/manifest on whatever server
--base-url points at (production by default, or staging, or localhost), validates
it (src/manifest.ts), and builds its entire command tree, --help, request/response
shapes, and docs browse surfaces from it. Dispatch is generic (src/dispatch.ts):
each request is built straight from the manifest operation's HTTP method + path
template + params + body — there is no hand-written command per operation and no
baked client.
The result: adding or changing a backend endpoint needs zero CLI release — the
live CLI reflects it as soon as the backend deploys. The CLI is re-released only when
its own engine code changes. The manifest is revalidated on every run via a
conditional fetch (ETag / If-None-Match), cached per base-url under
~/.cache/rl-gym/, so it can never serve stale data and never needs manual busting.
Docs browse surfaces
Beyond the executable rl <noun> <verb> operations, the manifest carries the docs,
exposed as one consistent positional shape — rl <group> [<id>] (bare lists, an id
shows that one):
rl resources [<id>] # Reference — resource hubs: object shape, operations, recipes
rl recipes [<id>] # How-to — multi-step user-goal guides (--format cli|ts|curl)
rl explain [<concept>] # Explanation — concept pages
rl tutorials [<id>] # Tutorials — getting-started docsInstall / run
Published to public npm as @labelbox/rl-cli — no token, no repo access, no
setup beyond Node itself.
npm uninstall -g @recursion/cli # no-op unless the pre-rename package is installed
npm install -g @labelbox/rl-cli # both own the global `rl` bin — EEXIST otherwise
# or, zero-install:
npx @labelbox/rl-cli --helpThe CLI is standalone, so this pulls in no @labelbox/rl-sdk.
Full setup steps and install-failure triage live in
apps/recursion/web/public/docs/cli-getting-started.md — that page owns them; don't
restate them here.
The CLI is released independently of the SDK (it no longer depends on it): a
packages/cli/** change cuts a CLI release via the Release / CLI GitHub
Action — see yarn dx help release.
From a monorepo checkout, run the bin directly without installing:
yarn workspace @labelbox/rl-cli build
node ./packages/cli/dist/bin.js --helpAuth
Set LABELBOX_API_KEY in the environment, or pass --api-key <key>. Override the
host with --base-url <url> (defaults to the public Recursion API gateway, see
DEFAULT_BASE_URL in src/manifest.ts).
Flags
- Path / query params are individual flags:
--environment-id,--limit, … Required path and query params must be passed as flags. A query param whose type is an array or object (e.g.--models,--enrichment-filters) takes a JSON value (--models '["a","b"]'); its help text is tagged[pass as JSON]. - Request body: scalar top-level fields are individual flags (
--name,--system-prompt, …); pass the full body — including complex fields likecontextInputs/targetFields— with--from-json <file>or--data <json>(mutually exclusive — pass only one). Scalar flags override values from--from-json/--data. A required scalar body field can be supplied by either its flag or the JSON body. - Output: prints the result as JSON by default;
--quietprints only the resulting resource'sid(a blank line for results without one, e.g. list or no-content operations).
rl synthesizers get --synthesizer-job-id sj_01HX...
rl synthesizers create --environment-id env_01HX... --from-json ./body.json
rl synthesizer-runs trigger --problem-version-id pv_01HX... --from-json ./run.jsonThe command surface is the live server
There is nothing to regenerate or commit for the CLI — the command surface is
fetched fresh from the target server's GET /cli/manifest on every run, so a backend
change flows through automatically after deploy with no CLI step. The manifest itself
is assembled by yarn dx manifest:generate (wired into dx codegen) from the
spec-derived reference files and embedded into the backend; to add or change a
command, change the backend @SdkRoute — not this package.
The engine (manifest fetch + cache + validation, generic dispatch, flag mapping,
help formatting, the request-body / returns shape trees, and the docs browse
renderers) is verified by src/*.test.ts, which build the program from a fixture
manifest in-memory and assert the realized flags + --help + browse output — no
committed golden snapshot to maintain.
