nuabase 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -31,23 +31,22 @@ const LeadInsights = z.object({
31
31
  });
32
32
  ```
33
33
 
34
- **3. Declare the prompt.** Turn it into a typed function:
34
+ **3. Call the API.** Use `list()` for array operations:
35
35
 
36
36
  ```ts
37
- const classifyLeads = new Nua().createArrayFn({
38
- prompt: 'Classify each lead with industry and company_size bucket.',
39
- output: {
40
- name: 'leadInsights',
41
- schema: LeadInsights,
42
- },
37
+ const nua = Nua.gateway({ apiKey: 'YOUR_API_KEY' });
38
+
39
+ const result = await nua.list('Classify each lead with industry and company_size bucket.', {
40
+ input: leads,
41
+ primaryKey: 'id',
42
+ output: { name: 'leadInsights', schema: LeadInsights },
43
43
  });
44
44
  ```
45
45
 
46
- **4. Invoke.** Call it like any other async function:
46
+ **4. Use the result.** Check for success and access typed data:
47
47
 
48
48
  ```ts
49
- const result = await classifyLeads(leads, 'id');
50
- if (result.isError) throw new Error(result.error);
49
+ if (!result.success) throw new Error(result.error);
51
50
  console.log(result.data[0].leadInsights);
52
51
  // -> { industry: 'Software', company_size: 'Mid-market' }
53
52
  ```
@@ -62,7 +61,7 @@ npm install nuabase zod
62
61
 
63
62
  2. Get your API key from the [Nuabase Console](https://console.nuabase.com/dashboard/api-keys/new).
64
63
 
65
- 3. Set `NUABASE_API_KEY` environment variable, or pass it directly in `new Nua({apiKey: "KEY"})`):
64
+ 3. Set `NUABASE_API_KEY` environment variable, or pass it directly in `Nua.gateway({ apiKey: "KEY" })`:
66
65
 
67
66
  ## Lead Enrichment Example
68
67
 
@@ -70,7 +69,7 @@ npm install nuabase zod
70
69
  import { Nua } from 'nuabase';
71
70
  import { z } from 'zod';
72
71
 
73
- const nua = new Nua({ apiKey: 'API-KEY' });
72
+ const nua = Nua.gateway({ apiKey: 'API-KEY' });
74
73
 
75
74
  const LeadInsights = z.object({
76
75
  company_name: z.string(),
@@ -79,15 +78,6 @@ const LeadInsights = z.object({
79
78
  recommended_follow_up: z.enum(['Call', 'Email', 'Event']),
80
79
  });
81
80
 
82
- const enrichLeads = nua.createArrayFn({
83
- prompt:
84
- 'Summarize each inbound lead by extracting company_name, industry, company_size bucket (SMB, Mid-market, Enterprise), and the recommended_follow_up channel (Call, Email, or Event) based on their notes.',
85
- output: {
86
- name: 'leadInsights',
87
- schema: LeadInsights,
88
- },
89
- });
90
-
91
81
  const rows = [
92
82
  {
93
83
  leadId: 'lead-101',
@@ -107,9 +97,16 @@ const rows = [
107
97
  },
108
98
  ];
109
99
 
110
- const response = await enrichLeads(rows, 'leadId'); // `leadId` is the primary key field
100
+ const response = await nua.list(
101
+ 'Summarize each inbound lead by extracting company_name, industry, company_size bucket (SMB, Mid-market, Enterprise), and the recommended_follow_up channel (Call, Email, or Event) based on their notes.',
102
+ {
103
+ input: rows,
104
+ primaryKey: 'leadId',
105
+ output: { name: 'leadInsights', schema: LeadInsights },
106
+ }
107
+ );
111
108
 
112
- if (response.isError) {
109
+ if (!response.success) {
113
110
  console.error(response.error);
114
111
  return;
115
112
  }
@@ -129,13 +126,12 @@ console.log(response.data);
129
126
  // company_size: 'Mid-market',
130
127
  // recommended_follow_up: 'Call',
131
128
  // },
132
- // sourceRow: { leadId: 'lead-101', name: 'Acme Analytics', notes: '...' },
133
129
  // },
134
130
  // // ...
135
131
  // ];
136
132
  ```
137
133
 
138
- The default invocation waits for completion and returns the full result. Use `.queue(data, primaryKey)` to submit an asynchronous job and receive streaming updates via SSE.
134
+ The default invocation waits for completion and returns the full result. Use `nua.queueList()` to submit an asynchronous job and receive streaming updates via SSE.
139
135
 
140
136
  ## Why Nuabase
141
137
 
@@ -146,61 +142,103 @@ The default invocation waits for completion and returns the full result. Use `.q
146
142
 
147
143
  ## API Response
148
144
 
149
- Every call returns a discriminated union. When `isError` is `true`, you get a flat error object. Otherwise `isSuccess` is `true`, and `data` contains rows merged with your typed output—along with metadata for observability and caching.
145
+ Every call returns a discriminated union. When `success` is `false`, you get an error object. Otherwise `success` is `true`, and `data` contains your typed output along with metadata.
150
146
 
151
147
  **Success**
152
148
 
153
- | Field | Type | Description |
154
- | ------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
155
- | `isSuccess` | `true` | Indicates that the request completed successfully. |
156
- | `data` | `Array<{ [primaryKey]: unknown; [outputName]: z.infer<typeof output>; sourceRow: InputRow }>` | Rows that merged the original primary key with the validated schema output, plus the full `sourceRow` for convenience. |
157
- | `llmRequestId` | `string` | Unique identifier for tracing each Nuabase LLM execution. |
158
- | `usage` | `{ promptTokens: number; completionTokens: number; totalTokens: number }` | Token usage statistics for the LLM request. |
159
- | `cacheHits` | `number` | Count of input rows served from Nuabase response cache. |
160
- | `rowsWithNoResults` | `string[]` | Primary keys that could not be resolved by the model. |
161
- | `isError` | `false \| undefined` | Absent on success; included for type narrowing. |
149
+ | Field | Type | Description |
150
+ | ----------- | --------------------------------------------------------- | ------------------------------------------------------- |
151
+ | `success` | `true` | Indicates that the request completed successfully. |
152
+ | `data` | `T` (for `get`) or `Array<{ [pk]: value; [output]: T }>` (for `list`) | The typed result matching your schema. |
153
+ | `usage` | `{ promptTokens, completionTokens, totalTokens }` | Token usage statistics for the LLM request. |
154
+ | `model` | `string` | The LLM model used for this request. |
155
+ | `latencyMs` | `number` | Request latency in milliseconds. |
156
+ | `source` | `'gateway'` \| `'direct'` | Which backend processed the request. |
157
+ | `meta` | `object` | Additional metadata (varies by source). |
158
+
159
+ **Gateway-specific metadata** (`meta` when `source` is `'gateway'`):
160
+
161
+ | Field | Type | Description |
162
+ | ------------ | --------- | ---------------------------------------------- |
163
+ | `requestId` | `string` | Unique identifier for tracing. |
164
+ | `cached` | `boolean` | Whether the result was served from cache. |
165
+ | `llmUsage` | `object` | Token usage from LLM calls. |
166
+ | `cacheUsage` | `object` | Token usage served from cache. |
162
167
 
163
168
  **Error**
164
169
 
165
- | Field | Type | Description |
166
- | --------- | -------- | -------------------------------------------------------- |
167
- | `isError` | `true` | Indicates the request failed. |
168
- | `error` | `string` | Message describing the error returned by the API or SDK. |
170
+ | Field | Type | Description |
171
+ | ----------- | ----------------------------- | -------------------------------------------------------- |
172
+ | `success` | `false` | Indicates the request failed. |
173
+ | `error` | `string` | Message describing the error. |
174
+ | `source` | `'gateway'` \| `'direct'` | Which backend returned the error. |
175
+ | `latencyMs` | `number` | Time until failure in milliseconds. |
169
176
 
170
177
  ## SDK API
171
178
 
172
- **`new Nua(config?)`**
173
- Creates a client bound to your Nuabase account. Provide:
179
+ ### Constructors
180
+
181
+ **`Nua.gateway(config?)`**
182
+ Creates a client that connects to the Nuabase API gateway. Use this for production deployments with caching, request tracking, and async job support.
174
183
 
175
184
  - `apiKey?: string` – API key for authentication. Defaults to `process.env.NUABASE_API_KEY`.
176
185
  - `baseUrl?: string` – Override the API host. Defaults to `https://api.nuabase.com`.
177
186
 
178
- **`nua.createArrayFn({ prompt, output })`**
179
- Declares a typed array mapping function backed by Nuabase. Parameters:
187
+ **`Nua.direct(config)`**
188
+ Creates a client that calls LLM providers directly (in-process). Use this for serverless, edge functions, or CLI tools where you don't need the gateway infrastructure.
180
189
 
181
- - `prompt: string` – Natural-language instructions sent to the LLM.
182
- - `output: { name: string; schema: ZodSchema }` – Output configuration with a name and Zod schema describing the output shape.
190
+ - `model: string` – The model to use (e.g., `'gpt-4o-mini'`).
191
+ - `providers: { openai?: { apiKey: string }, ... }` – Provider credentials.
183
192
 
184
- Returns a callable function with two modes:
193
+ ### Methods
185
194
 
186
- - `fn(data, primaryKey)` – Default mode. Runs the job and waits until the full enriched result set is ready.
187
- - `fn.queue(data, primaryKey)` – Submits the job asynchronously and returns streaming metadata via SSE.
195
+ **`nua.get(prompt)`**
196
+ Returns a simple string response from the LLM.
188
197
 
189
- Both modes expect:
198
+ ```ts
199
+ const result = await nua.get("Tell me a joke");
200
+ if (result.success) console.log(result.data); // string
201
+ ```
190
202
 
191
- - `data: Array<Record<string, unknown>>` – Rows you want Nuabase to enrich. Each row must include the primary key.
192
- - `primaryKey: string` – Field name that uniquely identifies each row within `data`. The SDK throws if the field is missing on any item.
203
+ **`nua.get(prompt, options)`**
204
+ Returns a typed single value. Parameters:
193
205
 
194
- Both modes resolve to either:
206
+ - `prompt: string` – Natural-language instructions sent to the LLM.
207
+ - `options.input?: unknown` – Optional input data to include in the prompt.
208
+ - `options.output: { name: string; schema: ZodSchema }` – Output name and Zod schema.
195
209
 
196
- - **Success** – `{ isSuccess: true, data, llmRequestId, usage, cacheHits, rowsWithNoResults }`.
197
- - **Error** – `{ isError: true, error }`.
210
+ ```ts
211
+ const result = await nua.get("Extract the address", {
212
+ input: "123 Main St, Springfield, IL 62701",
213
+ output: { name: 'address', schema: AddressSchema },
214
+ });
215
+ if (result.success) console.log(result.data); // typed as z.infer<typeof AddressSchema>
216
+ ```
198
217
 
199
- **`nua.createFn({ prompt, output })`**
200
- Declares a typed single-value function backed by Nuabase. Similar to `createArrayFn` but for processing a single input value instead of an array. Returns a function that accepts a single input value.
218
+ **`nua.list(prompt, options)`**
219
+ Processes an array of items. Parameters:
201
220
 
202
- **`nua.getRequest(llmRequestId)`**
203
- Retrieves request details for a completed LLM execution using its request ID.
221
+ - `prompt: string` – Natural-language instructions for each item.
222
+ - `options.input: Array<Record<string, unknown>>` – Rows to process.
223
+ - `options.primaryKey: string` – Field that uniquely identifies each row.
224
+ - `options.output: { name: string; schema: ZodSchema }` – Output configuration.
225
+
226
+ ```ts
227
+ const result = await nua.list("Classify each lead", {
228
+ input: leads,
229
+ primaryKey: 'id',
230
+ output: { name: 'classification', schema: ClassificationSchema },
231
+ });
232
+ if (result.success) {
233
+ result.data.forEach(row => console.log(row.id, row.classification));
234
+ }
235
+ ```
236
+
237
+ **`nua.queueGet(prompt, options?)`** *(Gateway mode only)*
238
+ Submits an async job for single-value operations. Returns `{ success: true, jobId }`.
239
+
240
+ **`nua.queueList(prompt, options)`** *(Gateway mode only)*
241
+ Submits an async job for array operations. Returns `{ success: true, jobId }`.
204
242
 
205
243
  ## Next Steps
206
244
 
@@ -211,6 +249,10 @@ Retrieves request details for a completed LLM execution using its request ID.
211
249
 
212
250
  Email us at [hello@nuabase.com](mailto:hello@nuabase.com). On X at [@NuabaseHQ](x.com/NuabaseHQ).
213
251
 
252
+ ## Tests
253
+
254
+ See [TESTING.md](TESTING.md)
255
+
214
256
  ## Credits
215
257
 
216
258
  The template for this package comes from https://github.com/rtivital/ts-package-template