@usenaive-sdk/node
v0.14.1
Published
Legacy Naïve SDK (flat resource API). Superseded by @usenaive-sdk/server — install that for the governed-agent-profile surface (provision/tools/revoke). This package remains as a backward-compatible base and re-export target.
Downloads
1,302
Readme
@usenaive-sdk/node (legacy)
Superseded by
@usenaive-sdk/server. New projects should install@usenaive-sdk/server, which re-exports everything here and adds the governed agent profile surface (forUser(id).provision(template),agentProfile.tools(),agentProfile.revoke(),runtime(pool).start()).
This package remains published for backward compatibility and is the base client
that @usenaive-sdk/server builds on. The flat resource API is unchanged:
import { Naive } from "@usenaive-sdk/node";
const naive = new Naive({ apiKey: process.env.NAIVE_SECRET_KEY });
await naive.cards.create({ name: "Ops", spending_limit_cents: 5000 });
await naive.forUser(alice.id).cards.create({ name: "Ops", spending_limit_cents: 5000 });The durable-runtime and brain surface
createClient() is a second root for teams, agents and the company brain. It
extends Naive, so it is additive in the strongest sense: every legacy
method is still on the same object, over the same transport, hitting the same
URL. src/__tests__/legacy-surface.test.ts asserts that call by call.
import { createClient } from "@usenaive-sdk/node";
import type config from "./naive.config.ts"; // type-only: zero runtime coupling
const naive = createClient<typeof config>({ apiKey: process.env.NAIVE_API_KEY! });
// teams — a (team, tenant) PAIR. forTenant VERIFIES; it does not get-or-create.
const support = await naive.teams.support.forTenant("tu_7f3a…");
const runs = await support.runs.list({ status: "running" });
for await (const ev of support.runs.watch(runs.runs[0].id)) console.log(ev.event_type);
// agents are DERIVED from the team, never addressed independently
const tier1 = support.agents.tier1;
// the brain — ONE per company, so a value, not a collection
const capsule = await naive.brain.attach({ goal: "refund policy" });
const outcome = await naive.brain.forget({ scope: "episode", scope_ref: "ep_1" });
if (outcome.decision === "park") await support.approvals.wait(outcome.approvalId);Without a config type, naive.teams.support is a compile error and
naive.team("support") is the always-present twin — a JS consumer, a
dynamically-configured product and every docs snippet must work with no local
config file.
What refuses, and why that is the feature
A method refuses in the client only when the route is not mounted. Those
methods exist, are typed, and throw NotImplementedError naming the exact
METHOD /path that is missing — they never return {} and never send a
request. Eight are in that set: sessions.open(), the three workspace verbs,
agent.limits(), agent.approvals(), brain.partition() and brain.lane().
The registry is MISSING_ROUTES; src/__tests__/wiring.test.ts proves the
refusing set is exactly it, and that every row is absent from the published
OpenAPI spec, so a row cannot outlive its route.
When a route IS mounted the call goes out, even if the server answers
501 not_configured. "There is no route" and "the route refuses" are different
instructions to a developer: only the second carries error.details.missing
naming each absent dependency, and only the second starts working the day that
dependency lands without a release of this package.
Wired today: runs, approvals, memory, the brain's attach · recall ·
remember · propose · promote · forget · reaffirm, and the whole
(team, tenant) surface — plan(), diagnostics(), board, spend.cost(),
submit(), effects, the session reads, and audit at
/v1/policy/decisions. Of those, plan · diagnostics · board.list ·
board.get · spend.cost return real rows today; the rest are mounted and
answer 501.
Deprecations (nothing is removed)
| still works | prefer |
|---|---|
| naive.cards, and the other 34 root getters | client.self.cards — one object, so the 39-vs-35 asymmetry cannot recur |
| naive.forUser(id) | client.forTenant(id) |
| naive.users | client.tenants |
Breaking changes
Unreleased — the voice/call surface is removed
PhoneClient no longer exposes enableVoice(), call(), calls(), or
endCall(), and agentTools() no longer advertises enableVoice, call, calls,
or endCall to agents. The phone primitive description now reads "Phone numbers and
SMS" — the LiveKit telephony chain (routes, service, MCP tools, CLI commands, config)
was deleted from the API, so /v1/phone/:id/voice/enable, /v1/phone/:id/calls, and
/v1/phone/calls/:callId no longer exist.
Number provisioning and SMS are unaffected — provision, list, status, get,
send, messages, read, thread, assign, and release all stay.
This is a source-compatibility break, not a behavioural regression: LiveKit voice was
never configured in production (no LIVEKIT_* / VOICE_ENABLED secret was ever set),
so assertVoiceConfigured() threw on every one of these calls. Callers were getting an
error before and get a compile error now — but keeping them would have downgraded that
to a bare 404, and left agents holding tool definitions they can only fail with.
Release note:
scripts/release-sdk.shbumpsnpm version patch. Removing public methods warrants a minor bump on 0.x (0.12.x → 0.13.0), not a patch — override the version before publishing this change.
Migration
- import { Naive } from "@usenaive-sdk/node";
+ import { Naive } from "@usenaive-sdk/server";Then you gain the agent profile layer:
const agentProfile = await naive.forUser(tenant.id).provision("sdr", { idempotencyKey: `ap:${tenant.id}` });
const tools = await agentProfile.tools();
await agentProfile.revoke();Purpose
Legacy Naïve SDK (flat resource API). Superseded by @usenaive-sdk/server — install that for the governed-agent-profile surface (provision/tools/revoke). This package remains as a backward-compatible base and re-export target.
Consumers
Part of the Naive monorepo. See the root README for how components fit together and which packages depend on this one.
Configuration
Configured via the monorepo's shared env and package.json. See the root README's driver/env selector matrix.
Run standalone
pnpm --filter @usenaive-sdk/node build
pnpm --filter @usenaive-sdk/node typecheckPlace in the topology
One node in the Naive monorepo (open plumbing). The root README has the full architecture diagram.
