API Overview
The Nuabase API has one constructor and two methods: nua.get() produces a single value, and nua.list() produces one value per row of an array.
Nua.direct(config)
Section titled “Nua.direct(config)”Creates a client. The config takes either localAgent or providers, not both:
import { Nua, z } from 'nuabase';import { findLocalAgent } from 'nuabase/local-agent';
// A coding agent CLI on this machineconst nua = Nua.direct({ localAgent: await findLocalAgent() });
// LLM provider APIs, with an optional default modelconst nua = Nua.direct({ providers: { openrouter: { apiKey: process.env.OPENROUTER_API_KEY! } }, model: { alias: 'fast' },});| Option | Description |
|---|---|
localAgent | A LocalAgent from localAgent() or findLocalAgent() in nuabase/local-agent. See Headless Coding Agent API. |
providers | API keys by provider: { groq?, cerebras?, gemini?, openrouter?, deepseek? }, each { apiKey: string }. See LLM Provider APIs. |
model | Default model for a providers client: { alias } or { provider, model }. Defaults to { alias: 'fast' }. A local agent’s default model is set on the agent instead. |
Methods
Section titled “Methods”| Method | Returns | Description |
|---|---|---|
nua.get(prompt) | CastResult<string> | A plain string answer. |
nua.get(prompt, options) | CastResult<z.infer<S>> | A single value matching your schema. |
nua.list(prompt, options) | CastResult<Row[]> | One value per input row, each tagged with its primary key. |
Options
Section titled “Options”| Option | Used by | Description |
|---|---|---|
input | get, list | Context data for get (any JSON-serializable value); an array of objects for list. |
output | get, list | { name, schema }: a name for the generated value and its Zod schema. |
primaryKey | list | Name of a unique ID property on each input object. Each output row carries it. |
model | get, list | Overrides the client’s default model for this call: { alias } or { provider, model }. |
Keep prompt the same across calls and put what varies in input. Providers cache the start of a request, and Nuabase puts the prompt and schema first. See prompt caching.
Results
Section titled “Results”Every call resolves to a CastResult, a union you narrow with result.success:
const result = await nua.get('Extract the address', { input: 'Ship to 123 Main St, Springfield, IL 62701', output: { name: 'address', schema: AddressSchema },});
if (result.success) { result.data; // z.infer<typeof AddressSchema> result.usage; // token counts result.model; // "claude-code:haiku", "openrouter:z-ai/glm-5.3-flash", ... result.latencyMs; // wall-clock time including retries result.meta; // engine, schemaEnforcement, provider or agent, model} else { result.reason; // why it failed, in the agent's or provider's words result.attempts; // attempts made, 0 if none was result.error; // a one-line summary for logs result.latencyMs;}| Field | Present when | Description |
|---|---|---|
data | success: true | The answer as parsed by your schema (or a string), with defaults filled in and transforms applied. |
usage | success: true | promptTokens, completionTokens, totalTokens, plus promptCacheReadTokens and promptCacheWriteTokens when the provider reports them. |
model | success: true | What answered: provider:model or agent:model. |
meta | success: true | engine ('http' or 'local-agent'), schemaEnforcement ('native' or 'in-prompt'), provider or agent, model, and for agents costUsdEstimate. |
reason | success: false | Why the last attempt failed, in the provider’s or agent’s own words where it gave any. When the answer didn’t fit your schema, it starts with Validation failed: and includes the model’s raw response. When no attempt was made, why not. |
attempts | success: false | How many attempts were made: up to 3, or 0 when the call was refused before any. |
error | success: false | A one-line summary for logs: the attempts made and why the last one failed. |
latencyMs | Always | Total time in milliseconds, including retries. |
source | Always | Always 'direct': every call runs in your process. |
See Types for the full type definitions.
Errors
Section titled “Errors”Nuabase separates failures of the LLM call from mistakes in your code.
Returned as success: false. These never throw:
- Network errors, agent timeouts, rate limits, and exhausted quota
- An invalid API key, or an agent that isn’t logged in
- A model that can’t run on the client: an alias with no configured provider, an unconfigured provider, or a provider model on a local agent
- Output your schema still rejects after retries
- For
list(), an input row that isn’t an object, or that lacks theprimaryKeyproperty
A model the client can’t run and an invalid list() row are refused before any attempt, with attempts: 0.
Thrown, before anything is sent:
- An empty or non-string prompt
- A non-array
inputpassed tolist() - An empty
primaryKey - A Zod schema with a type JSON Schema can’t express, such as
z.date()orz.bigint()
localAgent() also throws when the CLI isn’t on PATH, and findLocalAgent() rejects when no agent is installed and logged in.