@nestcorehq/node 0.15.0 → 0.16.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 +39 -0
- package/dist/index.d.mts +233 -27
- package/dist/index.d.ts +233 -27
- package/dist/index.js +112 -11
- package/dist/index.mjs +111 -11
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -215,6 +215,45 @@ const { data } = await client.db.from('articles').eq('published', true).semantic
|
|
|
215
215
|
|
|
216
216
|
See https://nestcore.io/docs/memory-api, /docs/collections, /docs/threads and /docs/embeddings.
|
|
217
217
|
|
|
218
|
+
#### Your own embeddings, trust and batches
|
|
219
|
+
|
|
220
|
+
Memory and collections also take vectors from your own (e.g. local) embedding model; the server then calls no provider and charges nothing. Search compares only vectors of the same `model` and size.
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
const model = 'nomic-embed-text-v1.5';
|
|
224
|
+
await client.memory.add('Prefers tea', { embedding: vec, model, metadata: { trust: 'user' } });
|
|
225
|
+
await client.memory.search({ queryEmbedding: q, model, trust: ['user', 'tool'] }); // text query optional
|
|
226
|
+
|
|
227
|
+
// Batches: up to 100 adds, 20 searches, 500 ids / 20 subjects per call
|
|
228
|
+
await client.memory.addMany([{ content: 'a', embedding: va, model }, { content: 'b', embedding: vb, model }]);
|
|
229
|
+
const { data: batch } = await client.memory.searchMany([{ queryEmbedding: q1, model }, { query: 'tea' }]);
|
|
230
|
+
await client.memory.forgetMany({ ids: ['…'], subjects: ['owner:…'] });
|
|
231
|
+
|
|
232
|
+
// A collection document from chunks you embedded (ready at once; the first chunks fix the collection's model)
|
|
233
|
+
await client.collections.from('notes').addChunks([{ content: 'Refunds take 5 days', embedding: v }], { model, title: 'FAQ' });
|
|
234
|
+
await client.collections.from('notes').search({ queryEmbedding: q, model, trust: 'user' });
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### AI credits and the OpenAI-compatible API
|
|
238
|
+
|
|
239
|
+
A project's own provider key always wins. Without one, the workspace's prepaid AI credit can pay (bought in Console → Settings → Billing).
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const { data: credits } = await client.ai.credits();
|
|
243
|
+
// { available, active, balanceUsd, monthlyCapUsd, spentThisMonthUsd, ownKeys, creditProviders }
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
unwrap(await client.ai.chat({ messages }));
|
|
247
|
+
} catch (e) {
|
|
248
|
+
if (e instanceof NestCoreError && e.isCreditsExhausted) {
|
|
249
|
+
// e.reason: 'balance' | 'spend_cap'. Don't retry: offer e.buyUrl, or adding your own key.
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Any OpenAI client works against the gateway (anon key as `apikey`, the user's token as the API key)
|
|
254
|
+
new OpenAI({ baseURL: client.ai.openaiBaseUrl, apiKey: accessToken, defaultHeaders: { apikey: anonKey } });
|
|
255
|
+
```
|
|
256
|
+
|
|
218
257
|
## Errors
|
|
219
258
|
|
|
220
259
|
Every call returns `{ data, error }` (never throws) — check `error` before using
|
package/dist/index.d.mts
CHANGED
|
@@ -1402,8 +1402,23 @@ interface AiMemoryMatch extends AiMemory {
|
|
|
1402
1402
|
/** Similarity nudged by importance and recency; results are sorted by it. */
|
|
1403
1403
|
score: number;
|
|
1404
1404
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1405
|
+
/** `metadata.trust` (and the search `trust` filter): a lowercase word such as `user`, `tool` or `web`. */
|
|
1406
|
+
type AiTrust = string | string[];
|
|
1407
|
+
/**
|
|
1408
|
+
* A vector you computed with your own (e.g. local) embedding model. The server
|
|
1409
|
+
* then calls no model provider and charges nothing. Search compares only
|
|
1410
|
+
* vectors of the same `model` and size, so switching models means re-sending.
|
|
1411
|
+
*/
|
|
1412
|
+
interface ClientEmbedding {
|
|
1413
|
+
/** 1–2000 finite numbers, not all zeros. Needs `model`. */
|
|
1414
|
+
embedding?: number[];
|
|
1415
|
+
/** The model that produced the vector (names the vector space), e.g. `nomic-embed-text-v1.5`. */
|
|
1416
|
+
model?: string;
|
|
1417
|
+
/** Checked against the vector length. */
|
|
1418
|
+
dims?: number;
|
|
1419
|
+
}
|
|
1420
|
+
interface MemoryAddOptions extends ClientEmbedding {
|
|
1421
|
+
/** Service key only: `type:id`, e.g. `user:<id>`, `agent:support`. Signed-in users are always `user:<their id>`; device and phone tokens default to `owner:<owner id>`. */
|
|
1407
1422
|
subject?: string;
|
|
1408
1423
|
/** fact (default), preference, episode, summary, or your own word. */
|
|
1409
1424
|
kind?: string;
|
|
@@ -1411,11 +1426,47 @@ interface MemoryAddOptions {
|
|
|
1411
1426
|
importance?: number;
|
|
1412
1427
|
/** ISO date; the memory is deleted after it. */
|
|
1413
1428
|
expiresAt?: string | null;
|
|
1429
|
+
/** `trust` is reserved: a lowercase word (`^[a-z][a-z0-9_-]{0,31}$`). */
|
|
1414
1430
|
metadata?: Record<string, unknown>;
|
|
1415
1431
|
sourceThreadId?: string;
|
|
1416
1432
|
/** Update a near-identical memory (cosine ≥ 0.92) instead of adding one. Default true. */
|
|
1417
1433
|
dedupe?: boolean;
|
|
1418
1434
|
}
|
|
1435
|
+
/** One item of {@link MemoryClient.addMany}. */
|
|
1436
|
+
interface MemoryAddItem extends MemoryAddOptions {
|
|
1437
|
+
content: string;
|
|
1438
|
+
}
|
|
1439
|
+
interface MemorySearchOptions {
|
|
1440
|
+
subject?: string;
|
|
1441
|
+
/** 1–50, default 5. */
|
|
1442
|
+
k?: number;
|
|
1443
|
+
kind?: string;
|
|
1444
|
+
minSimilarity?: number;
|
|
1445
|
+
/** Only memories whose `metadata.trust` is this word (or one of these words). */
|
|
1446
|
+
trust?: AiTrust;
|
|
1447
|
+
/** Your own query vector; `query` text is then optional. Needs `model`. */
|
|
1448
|
+
queryEmbedding?: number[];
|
|
1449
|
+
/** The model of `queryEmbedding`. */
|
|
1450
|
+
model?: string;
|
|
1451
|
+
dims?: number;
|
|
1452
|
+
}
|
|
1453
|
+
/** One query of {@link MemoryClient.searchMany}: `query` text, `queryEmbedding`, or both. */
|
|
1454
|
+
interface MemorySearchItem extends MemorySearchOptions {
|
|
1455
|
+
query?: string;
|
|
1456
|
+
}
|
|
1457
|
+
interface MemorySearchResult {
|
|
1458
|
+
results: AiMemoryMatch[];
|
|
1459
|
+
/** true = the model provider was down and keyword search answered. */
|
|
1460
|
+
degraded: boolean;
|
|
1461
|
+
model: string | null;
|
|
1462
|
+
}
|
|
1463
|
+
interface MemoryUpdatePatch extends ClientEmbedding {
|
|
1464
|
+
content?: string;
|
|
1465
|
+
kind?: string;
|
|
1466
|
+
importance?: number;
|
|
1467
|
+
expiresAt?: string | null;
|
|
1468
|
+
metadata?: Record<string, unknown>;
|
|
1469
|
+
}
|
|
1419
1470
|
/**
|
|
1420
1471
|
* Memory API: facts about a user (or an agent, an org…) with semantic search.
|
|
1421
1472
|
* A signed-in user reads and writes only their own memory; the service key may
|
|
@@ -1424,27 +1475,48 @@ interface MemoryAddOptions {
|
|
|
1424
1475
|
* ```ts
|
|
1425
1476
|
* await client.memory.add('Prefers vegetarian recipes', { kind: 'preference' });
|
|
1426
1477
|
* const { data } = await client.memory.search('what should I cook?');
|
|
1478
|
+
*
|
|
1479
|
+
* // Your own embeddings (no provider call, nothing charged):
|
|
1480
|
+
* await client.memory.add('Prefers tea', { embedding: vec, model: 'nomic-embed-text-v1.5' });
|
|
1481
|
+
* await client.memory.search({ queryEmbedding: q, model: 'nomic-embed-text-v1.5', trust: 'user' });
|
|
1427
1482
|
* ```
|
|
1428
1483
|
*/
|
|
1429
1484
|
declare class MemoryClient {
|
|
1430
1485
|
private client;
|
|
1431
1486
|
constructor(client: HttpClient);
|
|
1432
1487
|
private path;
|
|
1433
|
-
/**
|
|
1488
|
+
/**
|
|
1489
|
+
* Remember something. `deduped: true` means an existing near-identical memory was updated.
|
|
1490
|
+
* Pass `embedding` + `model` to use your own vector.
|
|
1491
|
+
*/
|
|
1434
1492
|
add(content: string, options?: MemoryAddOptions): Promise<ApiResult<{
|
|
1435
1493
|
memory: AiMemory;
|
|
1436
1494
|
deduped: boolean;
|
|
1437
1495
|
}>>;
|
|
1438
|
-
/**
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1496
|
+
/**
|
|
1497
|
+
* Most relevant memories. `degraded: true` = the model provider was down and keyword search answered.
|
|
1498
|
+
* With `queryEmbedding` + `model` the text is optional: `search({ queryEmbedding, model })`
|
|
1499
|
+
* or `search(null, { queryEmbedding, model })`.
|
|
1500
|
+
*/
|
|
1501
|
+
search(query: string | null | undefined, options?: MemorySearchOptions): Promise<ApiResult<MemorySearchResult>>;
|
|
1502
|
+
search(options: MemorySearchItem): Promise<ApiResult<MemorySearchResult>>;
|
|
1503
|
+
/** Up to 100 memories in one call (each counts against the memory quota). An invalid item fails the whole call with `400 "item <i>: …"`. */
|
|
1504
|
+
addMany(items: MemoryAddItem[]): Promise<ApiResult<{
|
|
1505
|
+
results: Array<{
|
|
1506
|
+
memory: AiMemory;
|
|
1507
|
+
deduped: boolean;
|
|
1508
|
+
}>;
|
|
1509
|
+
}>>;
|
|
1510
|
+
/** Up to 20 searches in one call; `results[i]` answers `queries[i]`. */
|
|
1511
|
+
searchMany(queries: MemorySearchItem[]): Promise<ApiResult<{
|
|
1512
|
+
results: MemorySearchResult[];
|
|
1513
|
+
}>>;
|
|
1514
|
+
/** Delete memories by id (up to 500) and/or whole subjects (up to 20; users and agents only their own). */
|
|
1515
|
+
forgetMany(target: {
|
|
1516
|
+
ids?: string[];
|
|
1517
|
+
subjects?: string[];
|
|
1444
1518
|
}): Promise<ApiResult<{
|
|
1445
|
-
|
|
1446
|
-
degraded: boolean;
|
|
1447
|
-
model: string | null;
|
|
1519
|
+
deleted: number;
|
|
1448
1520
|
}>>;
|
|
1449
1521
|
list(options?: {
|
|
1450
1522
|
subject?: string;
|
|
@@ -1456,13 +1528,8 @@ declare class MemoryClient {
|
|
|
1456
1528
|
total: number;
|
|
1457
1529
|
}>>;
|
|
1458
1530
|
get(id: string): Promise<ApiResult<AiMemory>>;
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
kind?: string;
|
|
1462
|
-
importance?: number;
|
|
1463
|
-
expiresAt?: string | null;
|
|
1464
|
-
metadata?: Record<string, unknown>;
|
|
1465
|
-
}): Promise<ApiResult<AiMemory>>;
|
|
1531
|
+
/** `embedding` + `model` only together with new `content`. */
|
|
1532
|
+
update(id: string, patch: MemoryUpdatePatch): Promise<ApiResult<AiMemory>>;
|
|
1466
1533
|
remove(id: string): Promise<ApiResult<{
|
|
1467
1534
|
deleted: boolean;
|
|
1468
1535
|
}>>;
|
|
@@ -1550,6 +1617,38 @@ type DocumentSource = {
|
|
|
1550
1617
|
path: string;
|
|
1551
1618
|
};
|
|
1552
1619
|
};
|
|
1620
|
+
/** A chunk you split and embedded yourself (see {@link CollectionRef.addChunks}). */
|
|
1621
|
+
interface ClientChunk {
|
|
1622
|
+
content: string;
|
|
1623
|
+
embedding: number[];
|
|
1624
|
+
/** Chunk metadata, e.g. `{ trust: 'user' }`. */
|
|
1625
|
+
metadata?: Record<string, unknown>;
|
|
1626
|
+
}
|
|
1627
|
+
interface AddChunksOptions {
|
|
1628
|
+
/** The embedding model of every chunk. The first client chunks fix the collection's model; another model answers 409. */
|
|
1629
|
+
model: string;
|
|
1630
|
+
/** Checked against each vector's length. */
|
|
1631
|
+
dims?: number;
|
|
1632
|
+
title?: string;
|
|
1633
|
+
metadata?: Record<string, unknown>;
|
|
1634
|
+
/** Service key only: the user who owns (and alone can read) this document. */
|
|
1635
|
+
ownerUserId?: string;
|
|
1636
|
+
}
|
|
1637
|
+
interface CollectionSearchOptions {
|
|
1638
|
+
/** 1–50, default 8. */
|
|
1639
|
+
k?: number;
|
|
1640
|
+
/** Vector + keyword (default); `false` = vector only. */
|
|
1641
|
+
hybrid?: boolean;
|
|
1642
|
+
/** Documents whose metadata contains this object. */
|
|
1643
|
+
filter?: Record<string, unknown>;
|
|
1644
|
+
minSimilarity?: number;
|
|
1645
|
+
/** Only chunks (or their document) whose `metadata.trust` is this word (or one of these words). */
|
|
1646
|
+
trust?: AiTrust;
|
|
1647
|
+
/** Your own query vector; `query` text is then optional. Needs `model` (the collection's). */
|
|
1648
|
+
queryEmbedding?: number[];
|
|
1649
|
+
model?: string;
|
|
1650
|
+
dims?: number;
|
|
1651
|
+
}
|
|
1553
1652
|
interface IngestOptions {
|
|
1554
1653
|
title?: string;
|
|
1555
1654
|
metadata?: Record<string, unknown>;
|
|
@@ -1572,17 +1671,30 @@ declare class CollectionRef {
|
|
|
1572
1671
|
* text files are read from storage or a URL.
|
|
1573
1672
|
*/
|
|
1574
1673
|
ingest(source: DocumentSource, options?: IngestOptions): Promise<ApiResult<AiDocument>>;
|
|
1674
|
+
/**
|
|
1675
|
+
* Add a document from chunks you embedded yourself (1–500; the body limit is 2 MB).
|
|
1676
|
+
* It is `ready` at once; the server calls no provider and charges nothing.
|
|
1677
|
+
*
|
|
1678
|
+
* ```ts
|
|
1679
|
+
* await kb.addChunks([{ content: 'Refunds take 5 days', embedding: vec }], { model: 'nomic-embed-text-v1.5', title: 'FAQ' });
|
|
1680
|
+
* ```
|
|
1681
|
+
*/
|
|
1682
|
+
addChunks(chunks: ClientChunk[], options: AddChunksOptions): Promise<ApiResult<AiDocument>>;
|
|
1575
1683
|
/** Poll a document until it is `ready` or `failed`. */
|
|
1576
1684
|
waitFor(documentId: string, { timeoutMs, intervalMs }?: {
|
|
1577
1685
|
timeoutMs?: number;
|
|
1578
1686
|
intervalMs?: number;
|
|
1579
1687
|
}): Promise<ApiResult<AiDocument>>;
|
|
1580
|
-
/**
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1688
|
+
/**
|
|
1689
|
+
* Hybrid search (vector + keyword). `hybrid: false` is vector only; `filter` matches document metadata.
|
|
1690
|
+
* With your own vector: `search({ queryEmbedding, model })` or `search('text', { queryEmbedding, model })`.
|
|
1691
|
+
*/
|
|
1692
|
+
search(query: string | null | undefined, options?: CollectionSearchOptions): Promise<ApiResult<{
|
|
1693
|
+
results: AiSearchResult[];
|
|
1694
|
+
model: string | null;
|
|
1695
|
+
}>>;
|
|
1696
|
+
search(options: CollectionSearchOptions & {
|
|
1697
|
+
query?: string;
|
|
1586
1698
|
}): Promise<ApiResult<{
|
|
1587
1699
|
results: AiSearchResult[];
|
|
1588
1700
|
model: string | null;
|
|
@@ -1736,6 +1848,7 @@ type ThreadRunEvent = {
|
|
|
1736
1848
|
code?: string;
|
|
1737
1849
|
message: string;
|
|
1738
1850
|
status?: number;
|
|
1851
|
+
details?: Record<string, unknown>;
|
|
1739
1852
|
};
|
|
1740
1853
|
interface ThreadRunResult {
|
|
1741
1854
|
messageId: string;
|
|
@@ -1917,6 +2030,7 @@ type AiStreamEvent = {
|
|
|
1917
2030
|
code?: string;
|
|
1918
2031
|
message: string;
|
|
1919
2032
|
status?: number;
|
|
2033
|
+
details?: Record<string, unknown>;
|
|
1920
2034
|
};
|
|
1921
2035
|
interface AiEmbedResult {
|
|
1922
2036
|
model: string;
|
|
@@ -1930,6 +2044,27 @@ interface AiModel {
|
|
|
1930
2044
|
provider: AiProviderId;
|
|
1931
2045
|
kind: 'chat' | 'embed';
|
|
1932
2046
|
default?: boolean;
|
|
2047
|
+
/** `credits`: paid from the workspace's prepaid AI credit (no project key for this provider). */
|
|
2048
|
+
source?: 'credits';
|
|
2049
|
+
}
|
|
2050
|
+
/**
|
|
2051
|
+
* Whether this project's AI calls can be paid from its workspace's prepaid
|
|
2052
|
+
* credit (when the project has no key of its own for a provider). A project's
|
|
2053
|
+
* own key always wins.
|
|
2054
|
+
*/
|
|
2055
|
+
interface AiCredits {
|
|
2056
|
+
/** There is credit to spend now. */
|
|
2057
|
+
available: boolean;
|
|
2058
|
+
/** The workspace has bought credit at some point. */
|
|
2059
|
+
active: boolean;
|
|
2060
|
+
balanceUsd: number;
|
|
2061
|
+
/** null = no monthly cap. */
|
|
2062
|
+
monthlyCapUsd: number | null;
|
|
2063
|
+
spentThisMonthUsd: number;
|
|
2064
|
+
/** Providers the project has its own key for. */
|
|
2065
|
+
ownKeys: AiProviderId[];
|
|
2066
|
+
/** Providers the credit can pay for. */
|
|
2067
|
+
creditProviders: AiProviderId[];
|
|
1933
2068
|
}
|
|
1934
2069
|
/**
|
|
1935
2070
|
* AI Gateway: chat and embeddings through the project's own provider keys.
|
|
@@ -1948,6 +2083,16 @@ declare class AiClient {
|
|
|
1948
2083
|
readonly threads: ThreadsClient;
|
|
1949
2084
|
constructor(client: HttpClient);
|
|
1950
2085
|
private path;
|
|
2086
|
+
/**
|
|
2087
|
+
* Base URL of the OpenAI-compatible API (`chat/completions` with `stream`,
|
|
2088
|
+
* `embeddings`, `models`) for any OpenAI client. Send the project key as the
|
|
2089
|
+
* `apikey` header and the user's (or device's) access token as the API key:
|
|
2090
|
+
*
|
|
2091
|
+
* ```ts
|
|
2092
|
+
* new OpenAI({ baseURL: client.ai.openaiBaseUrl, apiKey: accessToken, defaultHeaders: { apikey: anonKey } });
|
|
2093
|
+
* ```
|
|
2094
|
+
*/
|
|
2095
|
+
get openaiBaseUrl(): string;
|
|
1951
2096
|
private body;
|
|
1952
2097
|
chat(options: AiChatOptions): Promise<ApiResult<AiChatResult>>;
|
|
1953
2098
|
/**
|
|
@@ -1963,7 +2108,13 @@ declare class AiClient {
|
|
|
1963
2108
|
model?: string;
|
|
1964
2109
|
provider?: AiProviderId;
|
|
1965
2110
|
}): Promise<ApiResult<AiEmbedResult>>;
|
|
1966
|
-
/**
|
|
2111
|
+
/**
|
|
2112
|
+
* The workspace's prepaid AI credit as this project sees it. When a call is
|
|
2113
|
+
* paid from credit and none is left, it fails with 402 `CREDITS_EXHAUSTED`
|
|
2114
|
+
* (see `NestCoreError.isCreditsExhausted`, `reason` and `buyUrl`).
|
|
2115
|
+
*/
|
|
2116
|
+
credits(): Promise<ApiResult<AiCredits>>;
|
|
2117
|
+
/** Models the project can call with its saved provider keys (and, `source: 'credits'`, those its workspace's credit pays for). */
|
|
1967
2118
|
models(): Promise<ApiResult<AiModel[]>>;
|
|
1968
2119
|
/** Service key: per-call traces (model, tokens, latency, cost, status), newest first. */
|
|
1969
2120
|
traces(options?: {
|
|
@@ -2228,10 +2379,30 @@ declare function sanitizePath(path: string): string;
|
|
|
2228
2379
|
declare class NestCoreError extends Error {
|
|
2229
2380
|
readonly code?: string;
|
|
2230
2381
|
readonly status?: number;
|
|
2382
|
+
/** The API's error body, e.g. QUOTA_EXCEEDED's `quota`/`plan`/`limit`/`upgradeUrl`. */
|
|
2383
|
+
readonly details?: Record<string, unknown>;
|
|
2231
2384
|
constructor(message: string, opts?: {
|
|
2232
2385
|
code?: string;
|
|
2233
2386
|
status?: number;
|
|
2387
|
+
details?: Record<string, unknown>;
|
|
2234
2388
|
});
|
|
2389
|
+
/** 423: the project is paused (plan limit or owner) or compromised (kill switch). */
|
|
2390
|
+
get isProjectPaused(): boolean;
|
|
2391
|
+
/** 402 QUOTA_EXCEEDED: where to send the user to upgrade, when the API gave one. */
|
|
2392
|
+
get upgradeUrl(): string | undefined;
|
|
2393
|
+
/**
|
|
2394
|
+
* 402: an AI call paid from the workspace's prepaid credit found none left
|
|
2395
|
+
* (`reason` `balance`) or hit the monthly cap (`spend_cap`). Don't retry:
|
|
2396
|
+
* offer `buyUrl`, or adding the project's own provider key.
|
|
2397
|
+
*/
|
|
2398
|
+
get isCreditsExhausted(): boolean;
|
|
2399
|
+
/**
|
|
2400
|
+
* Why the call was refused, when the API said: `balance` | `spend_cap` for
|
|
2401
|
+
* CREDITS_EXHAUSTED, the quota reason (e.g. `ai_collections`) for QUOTA_EXCEEDED.
|
|
2402
|
+
*/
|
|
2403
|
+
get reason(): string | undefined;
|
|
2404
|
+
/** 402 CREDITS_EXHAUSTED: where to buy more AI credit. */
|
|
2405
|
+
get buyUrl(): string | undefined;
|
|
2235
2406
|
}
|
|
2236
2407
|
/** @deprecated Renamed to {@link NestCoreError}; kept so existing `instanceof` checks keep working. */
|
|
2237
2408
|
declare const OrbitNestError: typeof NestCoreError;
|
|
@@ -2266,6 +2437,41 @@ declare const AuthLimitCodes: {
|
|
|
2266
2437
|
/** Too many wrong passwords: the email is locked for the lockout duration. */
|
|
2267
2438
|
readonly ACCOUNT_LOCKED: "ACCOUNT_LOCKED";
|
|
2268
2439
|
};
|
|
2440
|
+
/**
|
|
2441
|
+
* `error.code` values about the project itself (any endpoint can answer them).
|
|
2442
|
+
* Project kinds: an App project is a backend for an app; an Agent project is
|
|
2443
|
+
* the private backend of one PC running NestCore Agent.
|
|
2444
|
+
*/
|
|
2445
|
+
declare const ProjectErrorCodes: {
|
|
2446
|
+
/**
|
|
2447
|
+
* 402: a plan limit was reached. `details` has quota, plan, limit, usage and, for projects, kind/reason/upgradeUrl
|
|
2448
|
+
* (`reason: 'ai_collections'` = the plan's collections per project).
|
|
2449
|
+
*/
|
|
2450
|
+
readonly QUOTA_EXCEEDED: "QUOTA_EXCEEDED";
|
|
2451
|
+
/**
|
|
2452
|
+
* 402: an AI call paid from prepaid credit found none left. `details`: reason (`balance` | `spend_cap`),
|
|
2453
|
+
* balanceUsd, monthlyCapUsd, spentThisMonthUsd, buyUrl. See {@link CreditsExhaustedDetails}.
|
|
2454
|
+
*/
|
|
2455
|
+
readonly CREDITS_EXHAUSTED: "CREDITS_EXHAUSTED";
|
|
2456
|
+
/** 423: the project is paused (downgrade or owner) or compromised (kill switch). Nothing was deleted. */
|
|
2457
|
+
readonly PROJECT_PAUSED: "PROJECT_PAUSED";
|
|
2458
|
+
/** 403: not allowed on an Agent project (only the agent schema, agent-* buckets and the agent functions). */
|
|
2459
|
+
readonly AGENT_PROJECT_RESTRICTED: "AGENT_PROJECT_RESTRICTED";
|
|
2460
|
+
/** 409: agent-only operation (agent template, agent functions) on an App project. */
|
|
2461
|
+
readonly NOT_AN_AGENT_PROJECT: "NOT_AN_AGENT_PROJECT";
|
|
2462
|
+
};
|
|
2463
|
+
/** `balance`: no credit left; `spend_cap`: the workspace's monthly AI credit cap is reached. */
|
|
2464
|
+
type CreditsExhaustedReason = 'balance' | 'spend_cap';
|
|
2465
|
+
/** The body of a 402 `CREDITS_EXHAUSTED` (in `error.details` / `NestCoreError.details`). */
|
|
2466
|
+
interface CreditsExhaustedDetails {
|
|
2467
|
+
code: 'CREDITS_EXHAUSTED';
|
|
2468
|
+
reason: CreditsExhaustedReason;
|
|
2469
|
+
message: string;
|
|
2470
|
+
balanceUsd: number;
|
|
2471
|
+
monthlyCapUsd: number | null;
|
|
2472
|
+
spentThisMonthUsd: number;
|
|
2473
|
+
buyUrl: string;
|
|
2474
|
+
}
|
|
2269
2475
|
|
|
2270
2476
|
/** @deprecated Renamed to {@link NestCoreClient}. */
|
|
2271
2477
|
type OrbitNestClient = NestCoreClient;
|
|
@@ -2344,4 +2550,4 @@ declare function createClient(config: NestCoreConfig & {
|
|
|
2344
2550
|
realtimeOptions?: RealtimeOptions;
|
|
2345
2551
|
}): NestCoreClient;
|
|
2346
2552
|
|
|
2347
|
-
export { type AdminAuthUser, type AdminCreateUserAttributes, type AdminUpdateUserAttributes, type AdminUserList, type AiChatOptions, type AiChatResult, type AiCitation, AiClient, type AiCollection, type AiContentPart, type AiDocument, type AiEmbedResult, type AiMemory, type AiMemoryMatch, type AiMessage, type AiModel, type AiProviderId, type AiSearchResult, type AiStreamEvent, type AiThread, type AiThreadMessage, type AiThreadPart, type AiTool, type AiToolCall, type AiTrace, AnalyticsClient, type AnalyticsEvent, type AnalyticsOptions, type ApiError, type ApiResponse, type ApiResult, AuthAdminClient, AuthClient, AuthLimitCodes, type AuthSession, type AuthStats, type AuthUser, type BackgroundJob, type BackgroundJobRun, type BroadcastPayload, CollectionRef, CollectionsClient, type CreateJobOptions, DatabaseClient, type DocumentSource, EnvironmentClient, type EnvironmentVariable, type FilterValue, type FunctionInvokeOptions, type FunctionResponse, FunctionsClient, type GenerateTypesOptions, HttpClient, type ImageTransformOptions, type IngestOptions, type IngestionResult, JobsClient, type LogEntry, type LogQueryOptions, LoggingClient, type MemoryAddOptions, MemoryClient, type MfaChallenge, type MfaFactor, MigrationError, MigrationExecutor, type MigrationFile, type MigrationRecord, MigrationRegistry, MigrationRunner, type MigrationRunnerDeps, MigrationScanner, type MigrationSqlClient, type MigrationStatus, type MigrationStatusEntry, type NestCoreClient, type NestCoreConfig, NestCoreError, type OrbitNestClient, type OrbitNestConfig, OrbitNestError, type PaginationOptions, type PasskeyAuthenticateVerifyOptions, type PasskeyAuthenticationOptions, type PasskeyDevice, type PasskeyRegisterVerifyOptions, type PasskeyRegistrationOptions, type PasskeySignUpOptions, type PasskeySignUpVerifyOptions, type PasswordRecoveryOptions, type PasswordResetOptions, type PgChangesFilter, type PgChangesPayload, type PgEvent, type PresenceJoinCallback, type PresenceLeaveCallback, PresenceManager, type PresenceState, type PresenceSyncCallback, type QueryResult, REGISTRY_TABLE, RealtimeChannel, RealtimeClient, type RealtimeOptions, type RealtimeStatus, type RequestOptions, type RlsPolicy, type RunResult, type SignInCredentials, type SignUpCredentials, StorageBucket, StorageClient, type StorageFile, type StorageListItem, type TableMetadata, ThreadRef, type ThreadRunEvent, type ThreadRunOptions, type ThreadRunResult, ThreadsClient, type UpdateJobOptions, type UpdateUserOptions, type UploadOptions, createClient, createMigrationRunner, generateTypes, isMfaChallenge, sanitizePath, unwrap, validatePath, validateRequired };
|
|
2553
|
+
export { type AddChunksOptions, type AdminAuthUser, type AdminCreateUserAttributes, type AdminUpdateUserAttributes, type AdminUserList, type AiChatOptions, type AiChatResult, type AiCitation, AiClient, type AiCollection, type AiContentPart, type AiCredits, type AiDocument, type AiEmbedResult, type AiMemory, type AiMemoryMatch, type AiMessage, type AiModel, type AiProviderId, type AiSearchResult, type AiStreamEvent, type AiThread, type AiThreadMessage, type AiThreadPart, type AiTool, type AiToolCall, type AiTrace, type AiTrust, AnalyticsClient, type AnalyticsEvent, type AnalyticsOptions, type ApiError, type ApiResponse, type ApiResult, AuthAdminClient, AuthClient, AuthLimitCodes, type AuthSession, type AuthStats, type AuthUser, type BackgroundJob, type BackgroundJobRun, type BroadcastPayload, type ClientChunk, type ClientEmbedding, CollectionRef, type CollectionSearchOptions, CollectionsClient, type CreateJobOptions, type CreditsExhaustedDetails, type CreditsExhaustedReason, DatabaseClient, type DocumentSource, EnvironmentClient, type EnvironmentVariable, type FilterValue, type FunctionInvokeOptions, type FunctionResponse, FunctionsClient, type GenerateTypesOptions, HttpClient, type ImageTransformOptions, type IngestOptions, type IngestionResult, JobsClient, type LogEntry, type LogQueryOptions, LoggingClient, type MemoryAddItem, type MemoryAddOptions, MemoryClient, type MemorySearchItem, type MemorySearchOptions, type MemorySearchResult, type MemoryUpdatePatch, type MfaChallenge, type MfaFactor, MigrationError, MigrationExecutor, type MigrationFile, type MigrationRecord, MigrationRegistry, MigrationRunner, type MigrationRunnerDeps, MigrationScanner, type MigrationSqlClient, type MigrationStatus, type MigrationStatusEntry, type NestCoreClient, type NestCoreConfig, NestCoreError, type OrbitNestClient, type OrbitNestConfig, OrbitNestError, type PaginationOptions, type PasskeyAuthenticateVerifyOptions, type PasskeyAuthenticationOptions, type PasskeyDevice, type PasskeyRegisterVerifyOptions, type PasskeyRegistrationOptions, type PasskeySignUpOptions, type PasskeySignUpVerifyOptions, type PasswordRecoveryOptions, type PasswordResetOptions, type PgChangesFilter, type PgChangesPayload, type PgEvent, type PresenceJoinCallback, type PresenceLeaveCallback, PresenceManager, type PresenceState, type PresenceSyncCallback, ProjectErrorCodes, type QueryResult, REGISTRY_TABLE, RealtimeChannel, RealtimeClient, type RealtimeOptions, type RealtimeStatus, type RequestOptions, type RlsPolicy, type RunResult, type SignInCredentials, type SignUpCredentials, StorageBucket, StorageClient, type StorageFile, type StorageListItem, type TableMetadata, ThreadRef, type ThreadRunEvent, type ThreadRunOptions, type ThreadRunResult, ThreadsClient, type UpdateJobOptions, type UpdateUserOptions, type UploadOptions, createClient, createMigrationRunner, generateTypes, isMfaChallenge, sanitizePath, unwrap, validatePath, validateRequired };
|
package/dist/index.d.ts
CHANGED
|
@@ -1402,8 +1402,23 @@ interface AiMemoryMatch extends AiMemory {
|
|
|
1402
1402
|
/** Similarity nudged by importance and recency; results are sorted by it. */
|
|
1403
1403
|
score: number;
|
|
1404
1404
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1405
|
+
/** `metadata.trust` (and the search `trust` filter): a lowercase word such as `user`, `tool` or `web`. */
|
|
1406
|
+
type AiTrust = string | string[];
|
|
1407
|
+
/**
|
|
1408
|
+
* A vector you computed with your own (e.g. local) embedding model. The server
|
|
1409
|
+
* then calls no model provider and charges nothing. Search compares only
|
|
1410
|
+
* vectors of the same `model` and size, so switching models means re-sending.
|
|
1411
|
+
*/
|
|
1412
|
+
interface ClientEmbedding {
|
|
1413
|
+
/** 1–2000 finite numbers, not all zeros. Needs `model`. */
|
|
1414
|
+
embedding?: number[];
|
|
1415
|
+
/** The model that produced the vector (names the vector space), e.g. `nomic-embed-text-v1.5`. */
|
|
1416
|
+
model?: string;
|
|
1417
|
+
/** Checked against the vector length. */
|
|
1418
|
+
dims?: number;
|
|
1419
|
+
}
|
|
1420
|
+
interface MemoryAddOptions extends ClientEmbedding {
|
|
1421
|
+
/** Service key only: `type:id`, e.g. `user:<id>`, `agent:support`. Signed-in users are always `user:<their id>`; device and phone tokens default to `owner:<owner id>`. */
|
|
1407
1422
|
subject?: string;
|
|
1408
1423
|
/** fact (default), preference, episode, summary, or your own word. */
|
|
1409
1424
|
kind?: string;
|
|
@@ -1411,11 +1426,47 @@ interface MemoryAddOptions {
|
|
|
1411
1426
|
importance?: number;
|
|
1412
1427
|
/** ISO date; the memory is deleted after it. */
|
|
1413
1428
|
expiresAt?: string | null;
|
|
1429
|
+
/** `trust` is reserved: a lowercase word (`^[a-z][a-z0-9_-]{0,31}$`). */
|
|
1414
1430
|
metadata?: Record<string, unknown>;
|
|
1415
1431
|
sourceThreadId?: string;
|
|
1416
1432
|
/** Update a near-identical memory (cosine ≥ 0.92) instead of adding one. Default true. */
|
|
1417
1433
|
dedupe?: boolean;
|
|
1418
1434
|
}
|
|
1435
|
+
/** One item of {@link MemoryClient.addMany}. */
|
|
1436
|
+
interface MemoryAddItem extends MemoryAddOptions {
|
|
1437
|
+
content: string;
|
|
1438
|
+
}
|
|
1439
|
+
interface MemorySearchOptions {
|
|
1440
|
+
subject?: string;
|
|
1441
|
+
/** 1–50, default 5. */
|
|
1442
|
+
k?: number;
|
|
1443
|
+
kind?: string;
|
|
1444
|
+
minSimilarity?: number;
|
|
1445
|
+
/** Only memories whose `metadata.trust` is this word (or one of these words). */
|
|
1446
|
+
trust?: AiTrust;
|
|
1447
|
+
/** Your own query vector; `query` text is then optional. Needs `model`. */
|
|
1448
|
+
queryEmbedding?: number[];
|
|
1449
|
+
/** The model of `queryEmbedding`. */
|
|
1450
|
+
model?: string;
|
|
1451
|
+
dims?: number;
|
|
1452
|
+
}
|
|
1453
|
+
/** One query of {@link MemoryClient.searchMany}: `query` text, `queryEmbedding`, or both. */
|
|
1454
|
+
interface MemorySearchItem extends MemorySearchOptions {
|
|
1455
|
+
query?: string;
|
|
1456
|
+
}
|
|
1457
|
+
interface MemorySearchResult {
|
|
1458
|
+
results: AiMemoryMatch[];
|
|
1459
|
+
/** true = the model provider was down and keyword search answered. */
|
|
1460
|
+
degraded: boolean;
|
|
1461
|
+
model: string | null;
|
|
1462
|
+
}
|
|
1463
|
+
interface MemoryUpdatePatch extends ClientEmbedding {
|
|
1464
|
+
content?: string;
|
|
1465
|
+
kind?: string;
|
|
1466
|
+
importance?: number;
|
|
1467
|
+
expiresAt?: string | null;
|
|
1468
|
+
metadata?: Record<string, unknown>;
|
|
1469
|
+
}
|
|
1419
1470
|
/**
|
|
1420
1471
|
* Memory API: facts about a user (or an agent, an org…) with semantic search.
|
|
1421
1472
|
* A signed-in user reads and writes only their own memory; the service key may
|
|
@@ -1424,27 +1475,48 @@ interface MemoryAddOptions {
|
|
|
1424
1475
|
* ```ts
|
|
1425
1476
|
* await client.memory.add('Prefers vegetarian recipes', { kind: 'preference' });
|
|
1426
1477
|
* const { data } = await client.memory.search('what should I cook?');
|
|
1478
|
+
*
|
|
1479
|
+
* // Your own embeddings (no provider call, nothing charged):
|
|
1480
|
+
* await client.memory.add('Prefers tea', { embedding: vec, model: 'nomic-embed-text-v1.5' });
|
|
1481
|
+
* await client.memory.search({ queryEmbedding: q, model: 'nomic-embed-text-v1.5', trust: 'user' });
|
|
1427
1482
|
* ```
|
|
1428
1483
|
*/
|
|
1429
1484
|
declare class MemoryClient {
|
|
1430
1485
|
private client;
|
|
1431
1486
|
constructor(client: HttpClient);
|
|
1432
1487
|
private path;
|
|
1433
|
-
/**
|
|
1488
|
+
/**
|
|
1489
|
+
* Remember something. `deduped: true` means an existing near-identical memory was updated.
|
|
1490
|
+
* Pass `embedding` + `model` to use your own vector.
|
|
1491
|
+
*/
|
|
1434
1492
|
add(content: string, options?: MemoryAddOptions): Promise<ApiResult<{
|
|
1435
1493
|
memory: AiMemory;
|
|
1436
1494
|
deduped: boolean;
|
|
1437
1495
|
}>>;
|
|
1438
|
-
/**
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1496
|
+
/**
|
|
1497
|
+
* Most relevant memories. `degraded: true` = the model provider was down and keyword search answered.
|
|
1498
|
+
* With `queryEmbedding` + `model` the text is optional: `search({ queryEmbedding, model })`
|
|
1499
|
+
* or `search(null, { queryEmbedding, model })`.
|
|
1500
|
+
*/
|
|
1501
|
+
search(query: string | null | undefined, options?: MemorySearchOptions): Promise<ApiResult<MemorySearchResult>>;
|
|
1502
|
+
search(options: MemorySearchItem): Promise<ApiResult<MemorySearchResult>>;
|
|
1503
|
+
/** Up to 100 memories in one call (each counts against the memory quota). An invalid item fails the whole call with `400 "item <i>: …"`. */
|
|
1504
|
+
addMany(items: MemoryAddItem[]): Promise<ApiResult<{
|
|
1505
|
+
results: Array<{
|
|
1506
|
+
memory: AiMemory;
|
|
1507
|
+
deduped: boolean;
|
|
1508
|
+
}>;
|
|
1509
|
+
}>>;
|
|
1510
|
+
/** Up to 20 searches in one call; `results[i]` answers `queries[i]`. */
|
|
1511
|
+
searchMany(queries: MemorySearchItem[]): Promise<ApiResult<{
|
|
1512
|
+
results: MemorySearchResult[];
|
|
1513
|
+
}>>;
|
|
1514
|
+
/** Delete memories by id (up to 500) and/or whole subjects (up to 20; users and agents only their own). */
|
|
1515
|
+
forgetMany(target: {
|
|
1516
|
+
ids?: string[];
|
|
1517
|
+
subjects?: string[];
|
|
1444
1518
|
}): Promise<ApiResult<{
|
|
1445
|
-
|
|
1446
|
-
degraded: boolean;
|
|
1447
|
-
model: string | null;
|
|
1519
|
+
deleted: number;
|
|
1448
1520
|
}>>;
|
|
1449
1521
|
list(options?: {
|
|
1450
1522
|
subject?: string;
|
|
@@ -1456,13 +1528,8 @@ declare class MemoryClient {
|
|
|
1456
1528
|
total: number;
|
|
1457
1529
|
}>>;
|
|
1458
1530
|
get(id: string): Promise<ApiResult<AiMemory>>;
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
kind?: string;
|
|
1462
|
-
importance?: number;
|
|
1463
|
-
expiresAt?: string | null;
|
|
1464
|
-
metadata?: Record<string, unknown>;
|
|
1465
|
-
}): Promise<ApiResult<AiMemory>>;
|
|
1531
|
+
/** `embedding` + `model` only together with new `content`. */
|
|
1532
|
+
update(id: string, patch: MemoryUpdatePatch): Promise<ApiResult<AiMemory>>;
|
|
1466
1533
|
remove(id: string): Promise<ApiResult<{
|
|
1467
1534
|
deleted: boolean;
|
|
1468
1535
|
}>>;
|
|
@@ -1550,6 +1617,38 @@ type DocumentSource = {
|
|
|
1550
1617
|
path: string;
|
|
1551
1618
|
};
|
|
1552
1619
|
};
|
|
1620
|
+
/** A chunk you split and embedded yourself (see {@link CollectionRef.addChunks}). */
|
|
1621
|
+
interface ClientChunk {
|
|
1622
|
+
content: string;
|
|
1623
|
+
embedding: number[];
|
|
1624
|
+
/** Chunk metadata, e.g. `{ trust: 'user' }`. */
|
|
1625
|
+
metadata?: Record<string, unknown>;
|
|
1626
|
+
}
|
|
1627
|
+
interface AddChunksOptions {
|
|
1628
|
+
/** The embedding model of every chunk. The first client chunks fix the collection's model; another model answers 409. */
|
|
1629
|
+
model: string;
|
|
1630
|
+
/** Checked against each vector's length. */
|
|
1631
|
+
dims?: number;
|
|
1632
|
+
title?: string;
|
|
1633
|
+
metadata?: Record<string, unknown>;
|
|
1634
|
+
/** Service key only: the user who owns (and alone can read) this document. */
|
|
1635
|
+
ownerUserId?: string;
|
|
1636
|
+
}
|
|
1637
|
+
interface CollectionSearchOptions {
|
|
1638
|
+
/** 1–50, default 8. */
|
|
1639
|
+
k?: number;
|
|
1640
|
+
/** Vector + keyword (default); `false` = vector only. */
|
|
1641
|
+
hybrid?: boolean;
|
|
1642
|
+
/** Documents whose metadata contains this object. */
|
|
1643
|
+
filter?: Record<string, unknown>;
|
|
1644
|
+
minSimilarity?: number;
|
|
1645
|
+
/** Only chunks (or their document) whose `metadata.trust` is this word (or one of these words). */
|
|
1646
|
+
trust?: AiTrust;
|
|
1647
|
+
/** Your own query vector; `query` text is then optional. Needs `model` (the collection's). */
|
|
1648
|
+
queryEmbedding?: number[];
|
|
1649
|
+
model?: string;
|
|
1650
|
+
dims?: number;
|
|
1651
|
+
}
|
|
1553
1652
|
interface IngestOptions {
|
|
1554
1653
|
title?: string;
|
|
1555
1654
|
metadata?: Record<string, unknown>;
|
|
@@ -1572,17 +1671,30 @@ declare class CollectionRef {
|
|
|
1572
1671
|
* text files are read from storage or a URL.
|
|
1573
1672
|
*/
|
|
1574
1673
|
ingest(source: DocumentSource, options?: IngestOptions): Promise<ApiResult<AiDocument>>;
|
|
1674
|
+
/**
|
|
1675
|
+
* Add a document from chunks you embedded yourself (1–500; the body limit is 2 MB).
|
|
1676
|
+
* It is `ready` at once; the server calls no provider and charges nothing.
|
|
1677
|
+
*
|
|
1678
|
+
* ```ts
|
|
1679
|
+
* await kb.addChunks([{ content: 'Refunds take 5 days', embedding: vec }], { model: 'nomic-embed-text-v1.5', title: 'FAQ' });
|
|
1680
|
+
* ```
|
|
1681
|
+
*/
|
|
1682
|
+
addChunks(chunks: ClientChunk[], options: AddChunksOptions): Promise<ApiResult<AiDocument>>;
|
|
1575
1683
|
/** Poll a document until it is `ready` or `failed`. */
|
|
1576
1684
|
waitFor(documentId: string, { timeoutMs, intervalMs }?: {
|
|
1577
1685
|
timeoutMs?: number;
|
|
1578
1686
|
intervalMs?: number;
|
|
1579
1687
|
}): Promise<ApiResult<AiDocument>>;
|
|
1580
|
-
/**
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1688
|
+
/**
|
|
1689
|
+
* Hybrid search (vector + keyword). `hybrid: false` is vector only; `filter` matches document metadata.
|
|
1690
|
+
* With your own vector: `search({ queryEmbedding, model })` or `search('text', { queryEmbedding, model })`.
|
|
1691
|
+
*/
|
|
1692
|
+
search(query: string | null | undefined, options?: CollectionSearchOptions): Promise<ApiResult<{
|
|
1693
|
+
results: AiSearchResult[];
|
|
1694
|
+
model: string | null;
|
|
1695
|
+
}>>;
|
|
1696
|
+
search(options: CollectionSearchOptions & {
|
|
1697
|
+
query?: string;
|
|
1586
1698
|
}): Promise<ApiResult<{
|
|
1587
1699
|
results: AiSearchResult[];
|
|
1588
1700
|
model: string | null;
|
|
@@ -1736,6 +1848,7 @@ type ThreadRunEvent = {
|
|
|
1736
1848
|
code?: string;
|
|
1737
1849
|
message: string;
|
|
1738
1850
|
status?: number;
|
|
1851
|
+
details?: Record<string, unknown>;
|
|
1739
1852
|
};
|
|
1740
1853
|
interface ThreadRunResult {
|
|
1741
1854
|
messageId: string;
|
|
@@ -1917,6 +2030,7 @@ type AiStreamEvent = {
|
|
|
1917
2030
|
code?: string;
|
|
1918
2031
|
message: string;
|
|
1919
2032
|
status?: number;
|
|
2033
|
+
details?: Record<string, unknown>;
|
|
1920
2034
|
};
|
|
1921
2035
|
interface AiEmbedResult {
|
|
1922
2036
|
model: string;
|
|
@@ -1930,6 +2044,27 @@ interface AiModel {
|
|
|
1930
2044
|
provider: AiProviderId;
|
|
1931
2045
|
kind: 'chat' | 'embed';
|
|
1932
2046
|
default?: boolean;
|
|
2047
|
+
/** `credits`: paid from the workspace's prepaid AI credit (no project key for this provider). */
|
|
2048
|
+
source?: 'credits';
|
|
2049
|
+
}
|
|
2050
|
+
/**
|
|
2051
|
+
* Whether this project's AI calls can be paid from its workspace's prepaid
|
|
2052
|
+
* credit (when the project has no key of its own for a provider). A project's
|
|
2053
|
+
* own key always wins.
|
|
2054
|
+
*/
|
|
2055
|
+
interface AiCredits {
|
|
2056
|
+
/** There is credit to spend now. */
|
|
2057
|
+
available: boolean;
|
|
2058
|
+
/** The workspace has bought credit at some point. */
|
|
2059
|
+
active: boolean;
|
|
2060
|
+
balanceUsd: number;
|
|
2061
|
+
/** null = no monthly cap. */
|
|
2062
|
+
monthlyCapUsd: number | null;
|
|
2063
|
+
spentThisMonthUsd: number;
|
|
2064
|
+
/** Providers the project has its own key for. */
|
|
2065
|
+
ownKeys: AiProviderId[];
|
|
2066
|
+
/** Providers the credit can pay for. */
|
|
2067
|
+
creditProviders: AiProviderId[];
|
|
1933
2068
|
}
|
|
1934
2069
|
/**
|
|
1935
2070
|
* AI Gateway: chat and embeddings through the project's own provider keys.
|
|
@@ -1948,6 +2083,16 @@ declare class AiClient {
|
|
|
1948
2083
|
readonly threads: ThreadsClient;
|
|
1949
2084
|
constructor(client: HttpClient);
|
|
1950
2085
|
private path;
|
|
2086
|
+
/**
|
|
2087
|
+
* Base URL of the OpenAI-compatible API (`chat/completions` with `stream`,
|
|
2088
|
+
* `embeddings`, `models`) for any OpenAI client. Send the project key as the
|
|
2089
|
+
* `apikey` header and the user's (or device's) access token as the API key:
|
|
2090
|
+
*
|
|
2091
|
+
* ```ts
|
|
2092
|
+
* new OpenAI({ baseURL: client.ai.openaiBaseUrl, apiKey: accessToken, defaultHeaders: { apikey: anonKey } });
|
|
2093
|
+
* ```
|
|
2094
|
+
*/
|
|
2095
|
+
get openaiBaseUrl(): string;
|
|
1951
2096
|
private body;
|
|
1952
2097
|
chat(options: AiChatOptions): Promise<ApiResult<AiChatResult>>;
|
|
1953
2098
|
/**
|
|
@@ -1963,7 +2108,13 @@ declare class AiClient {
|
|
|
1963
2108
|
model?: string;
|
|
1964
2109
|
provider?: AiProviderId;
|
|
1965
2110
|
}): Promise<ApiResult<AiEmbedResult>>;
|
|
1966
|
-
/**
|
|
2111
|
+
/**
|
|
2112
|
+
* The workspace's prepaid AI credit as this project sees it. When a call is
|
|
2113
|
+
* paid from credit and none is left, it fails with 402 `CREDITS_EXHAUSTED`
|
|
2114
|
+
* (see `NestCoreError.isCreditsExhausted`, `reason` and `buyUrl`).
|
|
2115
|
+
*/
|
|
2116
|
+
credits(): Promise<ApiResult<AiCredits>>;
|
|
2117
|
+
/** Models the project can call with its saved provider keys (and, `source: 'credits'`, those its workspace's credit pays for). */
|
|
1967
2118
|
models(): Promise<ApiResult<AiModel[]>>;
|
|
1968
2119
|
/** Service key: per-call traces (model, tokens, latency, cost, status), newest first. */
|
|
1969
2120
|
traces(options?: {
|
|
@@ -2228,10 +2379,30 @@ declare function sanitizePath(path: string): string;
|
|
|
2228
2379
|
declare class NestCoreError extends Error {
|
|
2229
2380
|
readonly code?: string;
|
|
2230
2381
|
readonly status?: number;
|
|
2382
|
+
/** The API's error body, e.g. QUOTA_EXCEEDED's `quota`/`plan`/`limit`/`upgradeUrl`. */
|
|
2383
|
+
readonly details?: Record<string, unknown>;
|
|
2231
2384
|
constructor(message: string, opts?: {
|
|
2232
2385
|
code?: string;
|
|
2233
2386
|
status?: number;
|
|
2387
|
+
details?: Record<string, unknown>;
|
|
2234
2388
|
});
|
|
2389
|
+
/** 423: the project is paused (plan limit or owner) or compromised (kill switch). */
|
|
2390
|
+
get isProjectPaused(): boolean;
|
|
2391
|
+
/** 402 QUOTA_EXCEEDED: where to send the user to upgrade, when the API gave one. */
|
|
2392
|
+
get upgradeUrl(): string | undefined;
|
|
2393
|
+
/**
|
|
2394
|
+
* 402: an AI call paid from the workspace's prepaid credit found none left
|
|
2395
|
+
* (`reason` `balance`) or hit the monthly cap (`spend_cap`). Don't retry:
|
|
2396
|
+
* offer `buyUrl`, or adding the project's own provider key.
|
|
2397
|
+
*/
|
|
2398
|
+
get isCreditsExhausted(): boolean;
|
|
2399
|
+
/**
|
|
2400
|
+
* Why the call was refused, when the API said: `balance` | `spend_cap` for
|
|
2401
|
+
* CREDITS_EXHAUSTED, the quota reason (e.g. `ai_collections`) for QUOTA_EXCEEDED.
|
|
2402
|
+
*/
|
|
2403
|
+
get reason(): string | undefined;
|
|
2404
|
+
/** 402 CREDITS_EXHAUSTED: where to buy more AI credit. */
|
|
2405
|
+
get buyUrl(): string | undefined;
|
|
2235
2406
|
}
|
|
2236
2407
|
/** @deprecated Renamed to {@link NestCoreError}; kept so existing `instanceof` checks keep working. */
|
|
2237
2408
|
declare const OrbitNestError: typeof NestCoreError;
|
|
@@ -2266,6 +2437,41 @@ declare const AuthLimitCodes: {
|
|
|
2266
2437
|
/** Too many wrong passwords: the email is locked for the lockout duration. */
|
|
2267
2438
|
readonly ACCOUNT_LOCKED: "ACCOUNT_LOCKED";
|
|
2268
2439
|
};
|
|
2440
|
+
/**
|
|
2441
|
+
* `error.code` values about the project itself (any endpoint can answer them).
|
|
2442
|
+
* Project kinds: an App project is a backend for an app; an Agent project is
|
|
2443
|
+
* the private backend of one PC running NestCore Agent.
|
|
2444
|
+
*/
|
|
2445
|
+
declare const ProjectErrorCodes: {
|
|
2446
|
+
/**
|
|
2447
|
+
* 402: a plan limit was reached. `details` has quota, plan, limit, usage and, for projects, kind/reason/upgradeUrl
|
|
2448
|
+
* (`reason: 'ai_collections'` = the plan's collections per project).
|
|
2449
|
+
*/
|
|
2450
|
+
readonly QUOTA_EXCEEDED: "QUOTA_EXCEEDED";
|
|
2451
|
+
/**
|
|
2452
|
+
* 402: an AI call paid from prepaid credit found none left. `details`: reason (`balance` | `spend_cap`),
|
|
2453
|
+
* balanceUsd, monthlyCapUsd, spentThisMonthUsd, buyUrl. See {@link CreditsExhaustedDetails}.
|
|
2454
|
+
*/
|
|
2455
|
+
readonly CREDITS_EXHAUSTED: "CREDITS_EXHAUSTED";
|
|
2456
|
+
/** 423: the project is paused (downgrade or owner) or compromised (kill switch). Nothing was deleted. */
|
|
2457
|
+
readonly PROJECT_PAUSED: "PROJECT_PAUSED";
|
|
2458
|
+
/** 403: not allowed on an Agent project (only the agent schema, agent-* buckets and the agent functions). */
|
|
2459
|
+
readonly AGENT_PROJECT_RESTRICTED: "AGENT_PROJECT_RESTRICTED";
|
|
2460
|
+
/** 409: agent-only operation (agent template, agent functions) on an App project. */
|
|
2461
|
+
readonly NOT_AN_AGENT_PROJECT: "NOT_AN_AGENT_PROJECT";
|
|
2462
|
+
};
|
|
2463
|
+
/** `balance`: no credit left; `spend_cap`: the workspace's monthly AI credit cap is reached. */
|
|
2464
|
+
type CreditsExhaustedReason = 'balance' | 'spend_cap';
|
|
2465
|
+
/** The body of a 402 `CREDITS_EXHAUSTED` (in `error.details` / `NestCoreError.details`). */
|
|
2466
|
+
interface CreditsExhaustedDetails {
|
|
2467
|
+
code: 'CREDITS_EXHAUSTED';
|
|
2468
|
+
reason: CreditsExhaustedReason;
|
|
2469
|
+
message: string;
|
|
2470
|
+
balanceUsd: number;
|
|
2471
|
+
monthlyCapUsd: number | null;
|
|
2472
|
+
spentThisMonthUsd: number;
|
|
2473
|
+
buyUrl: string;
|
|
2474
|
+
}
|
|
2269
2475
|
|
|
2270
2476
|
/** @deprecated Renamed to {@link NestCoreClient}. */
|
|
2271
2477
|
type OrbitNestClient = NestCoreClient;
|
|
@@ -2344,4 +2550,4 @@ declare function createClient(config: NestCoreConfig & {
|
|
|
2344
2550
|
realtimeOptions?: RealtimeOptions;
|
|
2345
2551
|
}): NestCoreClient;
|
|
2346
2552
|
|
|
2347
|
-
export { type AdminAuthUser, type AdminCreateUserAttributes, type AdminUpdateUserAttributes, type AdminUserList, type AiChatOptions, type AiChatResult, type AiCitation, AiClient, type AiCollection, type AiContentPart, type AiDocument, type AiEmbedResult, type AiMemory, type AiMemoryMatch, type AiMessage, type AiModel, type AiProviderId, type AiSearchResult, type AiStreamEvent, type AiThread, type AiThreadMessage, type AiThreadPart, type AiTool, type AiToolCall, type AiTrace, AnalyticsClient, type AnalyticsEvent, type AnalyticsOptions, type ApiError, type ApiResponse, type ApiResult, AuthAdminClient, AuthClient, AuthLimitCodes, type AuthSession, type AuthStats, type AuthUser, type BackgroundJob, type BackgroundJobRun, type BroadcastPayload, CollectionRef, CollectionsClient, type CreateJobOptions, DatabaseClient, type DocumentSource, EnvironmentClient, type EnvironmentVariable, type FilterValue, type FunctionInvokeOptions, type FunctionResponse, FunctionsClient, type GenerateTypesOptions, HttpClient, type ImageTransformOptions, type IngestOptions, type IngestionResult, JobsClient, type LogEntry, type LogQueryOptions, LoggingClient, type MemoryAddOptions, MemoryClient, type MfaChallenge, type MfaFactor, MigrationError, MigrationExecutor, type MigrationFile, type MigrationRecord, MigrationRegistry, MigrationRunner, type MigrationRunnerDeps, MigrationScanner, type MigrationSqlClient, type MigrationStatus, type MigrationStatusEntry, type NestCoreClient, type NestCoreConfig, NestCoreError, type OrbitNestClient, type OrbitNestConfig, OrbitNestError, type PaginationOptions, type PasskeyAuthenticateVerifyOptions, type PasskeyAuthenticationOptions, type PasskeyDevice, type PasskeyRegisterVerifyOptions, type PasskeyRegistrationOptions, type PasskeySignUpOptions, type PasskeySignUpVerifyOptions, type PasswordRecoveryOptions, type PasswordResetOptions, type PgChangesFilter, type PgChangesPayload, type PgEvent, type PresenceJoinCallback, type PresenceLeaveCallback, PresenceManager, type PresenceState, type PresenceSyncCallback, type QueryResult, REGISTRY_TABLE, RealtimeChannel, RealtimeClient, type RealtimeOptions, type RealtimeStatus, type RequestOptions, type RlsPolicy, type RunResult, type SignInCredentials, type SignUpCredentials, StorageBucket, StorageClient, type StorageFile, type StorageListItem, type TableMetadata, ThreadRef, type ThreadRunEvent, type ThreadRunOptions, type ThreadRunResult, ThreadsClient, type UpdateJobOptions, type UpdateUserOptions, type UploadOptions, createClient, createMigrationRunner, generateTypes, isMfaChallenge, sanitizePath, unwrap, validatePath, validateRequired };
|
|
2553
|
+
export { type AddChunksOptions, type AdminAuthUser, type AdminCreateUserAttributes, type AdminUpdateUserAttributes, type AdminUserList, type AiChatOptions, type AiChatResult, type AiCitation, AiClient, type AiCollection, type AiContentPart, type AiCredits, type AiDocument, type AiEmbedResult, type AiMemory, type AiMemoryMatch, type AiMessage, type AiModel, type AiProviderId, type AiSearchResult, type AiStreamEvent, type AiThread, type AiThreadMessage, type AiThreadPart, type AiTool, type AiToolCall, type AiTrace, type AiTrust, AnalyticsClient, type AnalyticsEvent, type AnalyticsOptions, type ApiError, type ApiResponse, type ApiResult, AuthAdminClient, AuthClient, AuthLimitCodes, type AuthSession, type AuthStats, type AuthUser, type BackgroundJob, type BackgroundJobRun, type BroadcastPayload, type ClientChunk, type ClientEmbedding, CollectionRef, type CollectionSearchOptions, CollectionsClient, type CreateJobOptions, type CreditsExhaustedDetails, type CreditsExhaustedReason, DatabaseClient, type DocumentSource, EnvironmentClient, type EnvironmentVariable, type FilterValue, type FunctionInvokeOptions, type FunctionResponse, FunctionsClient, type GenerateTypesOptions, HttpClient, type ImageTransformOptions, type IngestOptions, type IngestionResult, JobsClient, type LogEntry, type LogQueryOptions, LoggingClient, type MemoryAddItem, type MemoryAddOptions, MemoryClient, type MemorySearchItem, type MemorySearchOptions, type MemorySearchResult, type MemoryUpdatePatch, type MfaChallenge, type MfaFactor, MigrationError, MigrationExecutor, type MigrationFile, type MigrationRecord, MigrationRegistry, MigrationRunner, type MigrationRunnerDeps, MigrationScanner, type MigrationSqlClient, type MigrationStatus, type MigrationStatusEntry, type NestCoreClient, type NestCoreConfig, NestCoreError, type OrbitNestClient, type OrbitNestConfig, OrbitNestError, type PaginationOptions, type PasskeyAuthenticateVerifyOptions, type PasskeyAuthenticationOptions, type PasskeyDevice, type PasskeyRegisterVerifyOptions, type PasskeyRegistrationOptions, type PasskeySignUpOptions, type PasskeySignUpVerifyOptions, type PasswordRecoveryOptions, type PasswordResetOptions, type PgChangesFilter, type PgChangesPayload, type PgEvent, type PresenceJoinCallback, type PresenceLeaveCallback, PresenceManager, type PresenceState, type PresenceSyncCallback, ProjectErrorCodes, type QueryResult, REGISTRY_TABLE, RealtimeChannel, RealtimeClient, type RealtimeOptions, type RealtimeStatus, type RequestOptions, type RlsPolicy, type RunResult, type SignInCredentials, type SignUpCredentials, StorageBucket, StorageClient, type StorageFile, type StorageListItem, type TableMetadata, ThreadRef, type ThreadRunEvent, type ThreadRunOptions, type ThreadRunResult, ThreadsClient, type UpdateJobOptions, type UpdateUserOptions, type UploadOptions, createClient, createMigrationRunner, generateTypes, isMfaChallenge, sanitizePath, unwrap, validatePath, validateRequired };
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,7 @@ __export(index_exports, {
|
|
|
42
42
|
NestCoreError: () => NestCoreError,
|
|
43
43
|
OrbitNestError: () => OrbitNestError,
|
|
44
44
|
PresenceManager: () => PresenceManager,
|
|
45
|
+
ProjectErrorCodes: () => ProjectErrorCodes,
|
|
45
46
|
REGISTRY_TABLE: () => REGISTRY_TABLE,
|
|
46
47
|
RealtimeChannel: () => RealtimeChannel,
|
|
47
48
|
RealtimeClient: () => RealtimeClient,
|
|
@@ -2296,13 +2297,27 @@ var MemoryClient = class {
|
|
|
2296
2297
|
path(p = "") {
|
|
2297
2298
|
return `/api/project/${this.client.getProjectSlug()}/ai/v1/memory${p}`;
|
|
2298
2299
|
}
|
|
2299
|
-
/**
|
|
2300
|
+
/**
|
|
2301
|
+
* Remember something. `deduped: true` means an existing near-identical memory was updated.
|
|
2302
|
+
* Pass `embedding` + `model` to use your own vector.
|
|
2303
|
+
*/
|
|
2300
2304
|
add(content, options = {}) {
|
|
2301
2305
|
return this.client.request(this.path(), { method: "POST", body: { content, ...options } });
|
|
2302
2306
|
}
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2307
|
+
search(queryOrOptions, options = {}) {
|
|
2308
|
+
return this.client.request(this.path("/search"), { method: "POST", body: searchBody(queryOrOptions, options) });
|
|
2309
|
+
}
|
|
2310
|
+
/** Up to 100 memories in one call (each counts against the memory quota). An invalid item fails the whole call with `400 "item <i>: …"`. */
|
|
2311
|
+
addMany(items) {
|
|
2312
|
+
return this.client.request(this.path("/batch/add"), { method: "POST", body: { items } });
|
|
2313
|
+
}
|
|
2314
|
+
/** Up to 20 searches in one call; `results[i]` answers `queries[i]`. */
|
|
2315
|
+
searchMany(queries) {
|
|
2316
|
+
return this.client.request(this.path("/batch/search"), { method: "POST", body: { queries } });
|
|
2317
|
+
}
|
|
2318
|
+
/** Delete memories by id (up to 500) and/or whole subjects (up to 20; users and agents only their own). */
|
|
2319
|
+
forgetMany(target) {
|
|
2320
|
+
return this.client.request(this.path("/batch/forget"), { method: "POST", body: target });
|
|
2306
2321
|
}
|
|
2307
2322
|
list(options = {}) {
|
|
2308
2323
|
return this.client.request(this.path(query(options)));
|
|
@@ -2310,6 +2325,7 @@ var MemoryClient = class {
|
|
|
2310
2325
|
get(id) {
|
|
2311
2326
|
return this.client.request(this.path(`/${encodeURIComponent(id)}`));
|
|
2312
2327
|
}
|
|
2328
|
+
/** `embedding` + `model` only together with new `content`. */
|
|
2313
2329
|
update(id, patch) {
|
|
2314
2330
|
return this.client.request(this.path(`/${encodeURIComponent(id)}`), { method: "PATCH", body: patch });
|
|
2315
2331
|
}
|
|
@@ -2347,6 +2363,17 @@ var CollectionRef = class {
|
|
|
2347
2363
|
if (res.error || !wait) return res;
|
|
2348
2364
|
return this.waitFor(res.data.id, typeof wait === "object" ? wait : {});
|
|
2349
2365
|
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Add a document from chunks you embedded yourself (1–500; the body limit is 2 MB).
|
|
2368
|
+
* It is `ready` at once; the server calls no provider and charges nothing.
|
|
2369
|
+
*
|
|
2370
|
+
* ```ts
|
|
2371
|
+
* await kb.addChunks([{ content: 'Refunds take 5 days', embedding: vec }], { model: 'nomic-embed-text-v1.5', title: 'FAQ' });
|
|
2372
|
+
* ```
|
|
2373
|
+
*/
|
|
2374
|
+
addChunks(chunks, options) {
|
|
2375
|
+
return this.client.request(this.path("/documents"), { method: "POST", body: { chunks, ...options } });
|
|
2376
|
+
}
|
|
2350
2377
|
/** Poll a document until it is `ready` or `failed`. */
|
|
2351
2378
|
async waitFor(documentId, { timeoutMs = 12e4, intervalMs = 1e3 } = {}) {
|
|
2352
2379
|
const until = Date.now() + timeoutMs;
|
|
@@ -2357,9 +2384,8 @@ var CollectionRef = class {
|
|
|
2357
2384
|
await new Promise((r) => setTimeout(r, intervalMs));
|
|
2358
2385
|
}
|
|
2359
2386
|
}
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
return this.client.request(this.path("/search"), { method: "POST", body: { query: query2, ...options } });
|
|
2387
|
+
search(queryOrOptions, options = {}) {
|
|
2388
|
+
return this.client.request(this.path("/search"), { method: "POST", body: searchBody(queryOrOptions, options) });
|
|
2363
2389
|
}
|
|
2364
2390
|
listDocuments(options = {}) {
|
|
2365
2391
|
return this.client.request(this.path(`/documents${query(options)}`));
|
|
@@ -2449,7 +2475,7 @@ var ThreadRef = class {
|
|
|
2449
2475
|
}
|
|
2450
2476
|
if (!res.ok || !res.body) {
|
|
2451
2477
|
const data = await res.json().catch(() => null);
|
|
2452
|
-
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status };
|
|
2478
|
+
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status, ...data && typeof data === "object" ? { details: data } : {} };
|
|
2453
2479
|
return;
|
|
2454
2480
|
}
|
|
2455
2481
|
try {
|
|
@@ -2486,6 +2512,10 @@ var ThreadsClient = class {
|
|
|
2486
2512
|
return this.from(id).delete();
|
|
2487
2513
|
}
|
|
2488
2514
|
};
|
|
2515
|
+
function searchBody(queryOrOptions, options) {
|
|
2516
|
+
if (queryOrOptions !== null && typeof queryOrOptions === "object") return { ...queryOrOptions };
|
|
2517
|
+
return typeof queryOrOptions === "string" ? { query: queryOrOptions, ...options } : { ...options };
|
|
2518
|
+
}
|
|
2489
2519
|
function query(o) {
|
|
2490
2520
|
const q = Object.entries(o).filter(([, v]) => v !== void 0 && v !== null).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
|
|
2491
2521
|
return q.length ? `?${q.join("&")}` : "";
|
|
@@ -2500,6 +2530,18 @@ var AiClient = class {
|
|
|
2500
2530
|
path(p) {
|
|
2501
2531
|
return `/api/project/${this.client.getProjectSlug()}/ai/v1/${p}`;
|
|
2502
2532
|
}
|
|
2533
|
+
/**
|
|
2534
|
+
* Base URL of the OpenAI-compatible API (`chat/completions` with `stream`,
|
|
2535
|
+
* `embeddings`, `models`) for any OpenAI client. Send the project key as the
|
|
2536
|
+
* `apikey` header and the user's (or device's) access token as the API key:
|
|
2537
|
+
*
|
|
2538
|
+
* ```ts
|
|
2539
|
+
* new OpenAI({ baseURL: client.ai.openaiBaseUrl, apiKey: accessToken, defaultHeaders: { apikey: anonKey } });
|
|
2540
|
+
* ```
|
|
2541
|
+
*/
|
|
2542
|
+
get openaiBaseUrl() {
|
|
2543
|
+
return `${this.client.getBaseUrl()}/api/project/${this.client.getProjectSlug()}/ai/openai/v1`;
|
|
2544
|
+
}
|
|
2503
2545
|
body(o, stream) {
|
|
2504
2546
|
return {
|
|
2505
2547
|
model: o.model,
|
|
@@ -2541,7 +2583,7 @@ var AiClient = class {
|
|
|
2541
2583
|
}
|
|
2542
2584
|
if (!res.ok || !res.body) {
|
|
2543
2585
|
const data = await res.json().catch(() => null);
|
|
2544
|
-
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status };
|
|
2586
|
+
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status, ...data && typeof data === "object" ? { details: data } : {} };
|
|
2545
2587
|
return;
|
|
2546
2588
|
}
|
|
2547
2589
|
try {
|
|
@@ -2554,7 +2596,15 @@ var AiClient = class {
|
|
|
2554
2596
|
async embed(input, options = {}) {
|
|
2555
2597
|
return this.client.request(this.path("embeddings"), { method: "POST", body: { input, ...options } });
|
|
2556
2598
|
}
|
|
2557
|
-
/**
|
|
2599
|
+
/**
|
|
2600
|
+
* The workspace's prepaid AI credit as this project sees it. When a call is
|
|
2601
|
+
* paid from credit and none is left, it fails with 402 `CREDITS_EXHAUSTED`
|
|
2602
|
+
* (see `NestCoreError.isCreditsExhausted`, `reason` and `buyUrl`).
|
|
2603
|
+
*/
|
|
2604
|
+
async credits() {
|
|
2605
|
+
return this.client.request(this.path("credits"));
|
|
2606
|
+
}
|
|
2607
|
+
/** Models the project can call with its saved provider keys (and, `source: 'credits'`, those its workspace's credit pays for). */
|
|
2558
2608
|
async models() {
|
|
2559
2609
|
return this.client.request(this.path("models"));
|
|
2560
2610
|
}
|
|
@@ -3064,6 +3114,37 @@ var NestCoreError = class extends Error {
|
|
|
3064
3114
|
this.name = "NestCoreError";
|
|
3065
3115
|
this.code = opts.code;
|
|
3066
3116
|
this.status = opts.status;
|
|
3117
|
+
this.details = opts.details;
|
|
3118
|
+
}
|
|
3119
|
+
/** 423: the project is paused (plan limit or owner) or compromised (kill switch). */
|
|
3120
|
+
get isProjectPaused() {
|
|
3121
|
+
return this.code === ProjectErrorCodes.PROJECT_PAUSED;
|
|
3122
|
+
}
|
|
3123
|
+
/** 402 QUOTA_EXCEEDED: where to send the user to upgrade, when the API gave one. */
|
|
3124
|
+
get upgradeUrl() {
|
|
3125
|
+
const u = this.details?.upgradeUrl;
|
|
3126
|
+
return typeof u === "string" ? u : void 0;
|
|
3127
|
+
}
|
|
3128
|
+
/**
|
|
3129
|
+
* 402: an AI call paid from the workspace's prepaid credit found none left
|
|
3130
|
+
* (`reason` `balance`) or hit the monthly cap (`spend_cap`). Don't retry:
|
|
3131
|
+
* offer `buyUrl`, or adding the project's own provider key.
|
|
3132
|
+
*/
|
|
3133
|
+
get isCreditsExhausted() {
|
|
3134
|
+
return this.code === ProjectErrorCodes.CREDITS_EXHAUSTED;
|
|
3135
|
+
}
|
|
3136
|
+
/**
|
|
3137
|
+
* Why the call was refused, when the API said: `balance` | `spend_cap` for
|
|
3138
|
+
* CREDITS_EXHAUSTED, the quota reason (e.g. `ai_collections`) for QUOTA_EXCEEDED.
|
|
3139
|
+
*/
|
|
3140
|
+
get reason() {
|
|
3141
|
+
const r = this.details?.reason;
|
|
3142
|
+
return typeof r === "string" ? r : void 0;
|
|
3143
|
+
}
|
|
3144
|
+
/** 402 CREDITS_EXHAUSTED: where to buy more AI credit. */
|
|
3145
|
+
get buyUrl() {
|
|
3146
|
+
const u = this.details?.buyUrl;
|
|
3147
|
+
return typeof u === "string" ? u : void 0;
|
|
3067
3148
|
}
|
|
3068
3149
|
};
|
|
3069
3150
|
var OrbitNestError = NestCoreError;
|
|
@@ -3071,7 +3152,8 @@ function unwrap(result) {
|
|
|
3071
3152
|
if (result.error) {
|
|
3072
3153
|
throw new NestCoreError(result.error.message, {
|
|
3073
3154
|
code: result.error.code,
|
|
3074
|
-
status: result.error.status
|
|
3155
|
+
status: result.error.status,
|
|
3156
|
+
details: result.error.details
|
|
3075
3157
|
});
|
|
3076
3158
|
}
|
|
3077
3159
|
return result.data;
|
|
@@ -3084,6 +3166,24 @@ var AuthLimitCodes = {
|
|
|
3084
3166
|
/** Too many wrong passwords: the email is locked for the lockout duration. */
|
|
3085
3167
|
ACCOUNT_LOCKED: "ACCOUNT_LOCKED"
|
|
3086
3168
|
};
|
|
3169
|
+
var ProjectErrorCodes = {
|
|
3170
|
+
/**
|
|
3171
|
+
* 402: a plan limit was reached. `details` has quota, plan, limit, usage and, for projects, kind/reason/upgradeUrl
|
|
3172
|
+
* (`reason: 'ai_collections'` = the plan's collections per project).
|
|
3173
|
+
*/
|
|
3174
|
+
QUOTA_EXCEEDED: "QUOTA_EXCEEDED",
|
|
3175
|
+
/**
|
|
3176
|
+
* 402: an AI call paid from prepaid credit found none left. `details`: reason (`balance` | `spend_cap`),
|
|
3177
|
+
* balanceUsd, monthlyCapUsd, spentThisMonthUsd, buyUrl. See {@link CreditsExhaustedDetails}.
|
|
3178
|
+
*/
|
|
3179
|
+
CREDITS_EXHAUSTED: "CREDITS_EXHAUSTED",
|
|
3180
|
+
/** 423: the project is paused (downgrade or owner) or compromised (kill switch). Nothing was deleted. */
|
|
3181
|
+
PROJECT_PAUSED: "PROJECT_PAUSED",
|
|
3182
|
+
/** 403: not allowed on an Agent project (only the agent schema, agent-* buckets and the agent functions). */
|
|
3183
|
+
AGENT_PROJECT_RESTRICTED: "AGENT_PROJECT_RESTRICTED",
|
|
3184
|
+
/** 409: agent-only operation (agent template, agent functions) on an App project. */
|
|
3185
|
+
NOT_AN_AGENT_PROJECT: "NOT_AN_AGENT_PROJECT"
|
|
3186
|
+
};
|
|
3087
3187
|
|
|
3088
3188
|
// src/index.ts
|
|
3089
3189
|
var DEFAULT_BASE_URL = "https://api.nestcore.io";
|
|
@@ -3180,6 +3280,7 @@ function createClient(config) {
|
|
|
3180
3280
|
NestCoreError,
|
|
3181
3281
|
OrbitNestError,
|
|
3182
3282
|
PresenceManager,
|
|
3283
|
+
ProjectErrorCodes,
|
|
3183
3284
|
REGISTRY_TABLE,
|
|
3184
3285
|
RealtimeChannel,
|
|
3185
3286
|
RealtimeClient,
|
package/dist/index.mjs
CHANGED
|
@@ -2234,13 +2234,27 @@ var MemoryClient = class {
|
|
|
2234
2234
|
path(p = "") {
|
|
2235
2235
|
return `/api/project/${this.client.getProjectSlug()}/ai/v1/memory${p}`;
|
|
2236
2236
|
}
|
|
2237
|
-
/**
|
|
2237
|
+
/**
|
|
2238
|
+
* Remember something. `deduped: true` means an existing near-identical memory was updated.
|
|
2239
|
+
* Pass `embedding` + `model` to use your own vector.
|
|
2240
|
+
*/
|
|
2238
2241
|
add(content, options = {}) {
|
|
2239
2242
|
return this.client.request(this.path(), { method: "POST", body: { content, ...options } });
|
|
2240
2243
|
}
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
+
search(queryOrOptions, options = {}) {
|
|
2245
|
+
return this.client.request(this.path("/search"), { method: "POST", body: searchBody(queryOrOptions, options) });
|
|
2246
|
+
}
|
|
2247
|
+
/** Up to 100 memories in one call (each counts against the memory quota). An invalid item fails the whole call with `400 "item <i>: …"`. */
|
|
2248
|
+
addMany(items) {
|
|
2249
|
+
return this.client.request(this.path("/batch/add"), { method: "POST", body: { items } });
|
|
2250
|
+
}
|
|
2251
|
+
/** Up to 20 searches in one call; `results[i]` answers `queries[i]`. */
|
|
2252
|
+
searchMany(queries) {
|
|
2253
|
+
return this.client.request(this.path("/batch/search"), { method: "POST", body: { queries } });
|
|
2254
|
+
}
|
|
2255
|
+
/** Delete memories by id (up to 500) and/or whole subjects (up to 20; users and agents only their own). */
|
|
2256
|
+
forgetMany(target) {
|
|
2257
|
+
return this.client.request(this.path("/batch/forget"), { method: "POST", body: target });
|
|
2244
2258
|
}
|
|
2245
2259
|
list(options = {}) {
|
|
2246
2260
|
return this.client.request(this.path(query(options)));
|
|
@@ -2248,6 +2262,7 @@ var MemoryClient = class {
|
|
|
2248
2262
|
get(id) {
|
|
2249
2263
|
return this.client.request(this.path(`/${encodeURIComponent(id)}`));
|
|
2250
2264
|
}
|
|
2265
|
+
/** `embedding` + `model` only together with new `content`. */
|
|
2251
2266
|
update(id, patch) {
|
|
2252
2267
|
return this.client.request(this.path(`/${encodeURIComponent(id)}`), { method: "PATCH", body: patch });
|
|
2253
2268
|
}
|
|
@@ -2285,6 +2300,17 @@ var CollectionRef = class {
|
|
|
2285
2300
|
if (res.error || !wait) return res;
|
|
2286
2301
|
return this.waitFor(res.data.id, typeof wait === "object" ? wait : {});
|
|
2287
2302
|
}
|
|
2303
|
+
/**
|
|
2304
|
+
* Add a document from chunks you embedded yourself (1–500; the body limit is 2 MB).
|
|
2305
|
+
* It is `ready` at once; the server calls no provider and charges nothing.
|
|
2306
|
+
*
|
|
2307
|
+
* ```ts
|
|
2308
|
+
* await kb.addChunks([{ content: 'Refunds take 5 days', embedding: vec }], { model: 'nomic-embed-text-v1.5', title: 'FAQ' });
|
|
2309
|
+
* ```
|
|
2310
|
+
*/
|
|
2311
|
+
addChunks(chunks, options) {
|
|
2312
|
+
return this.client.request(this.path("/documents"), { method: "POST", body: { chunks, ...options } });
|
|
2313
|
+
}
|
|
2288
2314
|
/** Poll a document until it is `ready` or `failed`. */
|
|
2289
2315
|
async waitFor(documentId, { timeoutMs = 12e4, intervalMs = 1e3 } = {}) {
|
|
2290
2316
|
const until = Date.now() + timeoutMs;
|
|
@@ -2295,9 +2321,8 @@ var CollectionRef = class {
|
|
|
2295
2321
|
await new Promise((r) => setTimeout(r, intervalMs));
|
|
2296
2322
|
}
|
|
2297
2323
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
return this.client.request(this.path("/search"), { method: "POST", body: { query: query2, ...options } });
|
|
2324
|
+
search(queryOrOptions, options = {}) {
|
|
2325
|
+
return this.client.request(this.path("/search"), { method: "POST", body: searchBody(queryOrOptions, options) });
|
|
2301
2326
|
}
|
|
2302
2327
|
listDocuments(options = {}) {
|
|
2303
2328
|
return this.client.request(this.path(`/documents${query(options)}`));
|
|
@@ -2387,7 +2412,7 @@ var ThreadRef = class {
|
|
|
2387
2412
|
}
|
|
2388
2413
|
if (!res.ok || !res.body) {
|
|
2389
2414
|
const data = await res.json().catch(() => null);
|
|
2390
|
-
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status };
|
|
2415
|
+
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status, ...data && typeof data === "object" ? { details: data } : {} };
|
|
2391
2416
|
return;
|
|
2392
2417
|
}
|
|
2393
2418
|
try {
|
|
@@ -2424,6 +2449,10 @@ var ThreadsClient = class {
|
|
|
2424
2449
|
return this.from(id).delete();
|
|
2425
2450
|
}
|
|
2426
2451
|
};
|
|
2452
|
+
function searchBody(queryOrOptions, options) {
|
|
2453
|
+
if (queryOrOptions !== null && typeof queryOrOptions === "object") return { ...queryOrOptions };
|
|
2454
|
+
return typeof queryOrOptions === "string" ? { query: queryOrOptions, ...options } : { ...options };
|
|
2455
|
+
}
|
|
2427
2456
|
function query(o) {
|
|
2428
2457
|
const q = Object.entries(o).filter(([, v]) => v !== void 0 && v !== null).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
|
|
2429
2458
|
return q.length ? `?${q.join("&")}` : "";
|
|
@@ -2438,6 +2467,18 @@ var AiClient = class {
|
|
|
2438
2467
|
path(p) {
|
|
2439
2468
|
return `/api/project/${this.client.getProjectSlug()}/ai/v1/${p}`;
|
|
2440
2469
|
}
|
|
2470
|
+
/**
|
|
2471
|
+
* Base URL of the OpenAI-compatible API (`chat/completions` with `stream`,
|
|
2472
|
+
* `embeddings`, `models`) for any OpenAI client. Send the project key as the
|
|
2473
|
+
* `apikey` header and the user's (or device's) access token as the API key:
|
|
2474
|
+
*
|
|
2475
|
+
* ```ts
|
|
2476
|
+
* new OpenAI({ baseURL: client.ai.openaiBaseUrl, apiKey: accessToken, defaultHeaders: { apikey: anonKey } });
|
|
2477
|
+
* ```
|
|
2478
|
+
*/
|
|
2479
|
+
get openaiBaseUrl() {
|
|
2480
|
+
return `${this.client.getBaseUrl()}/api/project/${this.client.getProjectSlug()}/ai/openai/v1`;
|
|
2481
|
+
}
|
|
2441
2482
|
body(o, stream) {
|
|
2442
2483
|
return {
|
|
2443
2484
|
model: o.model,
|
|
@@ -2479,7 +2520,7 @@ var AiClient = class {
|
|
|
2479
2520
|
}
|
|
2480
2521
|
if (!res.ok || !res.body) {
|
|
2481
2522
|
const data = await res.json().catch(() => null);
|
|
2482
|
-
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status };
|
|
2523
|
+
yield { type: "error", code: data?.code, message: errorMessage(data, res.status), status: res.status, ...data && typeof data === "object" ? { details: data } : {} };
|
|
2483
2524
|
return;
|
|
2484
2525
|
}
|
|
2485
2526
|
try {
|
|
@@ -2492,7 +2533,15 @@ var AiClient = class {
|
|
|
2492
2533
|
async embed(input, options = {}) {
|
|
2493
2534
|
return this.client.request(this.path("embeddings"), { method: "POST", body: { input, ...options } });
|
|
2494
2535
|
}
|
|
2495
|
-
/**
|
|
2536
|
+
/**
|
|
2537
|
+
* The workspace's prepaid AI credit as this project sees it. When a call is
|
|
2538
|
+
* paid from credit and none is left, it fails with 402 `CREDITS_EXHAUSTED`
|
|
2539
|
+
* (see `NestCoreError.isCreditsExhausted`, `reason` and `buyUrl`).
|
|
2540
|
+
*/
|
|
2541
|
+
async credits() {
|
|
2542
|
+
return this.client.request(this.path("credits"));
|
|
2543
|
+
}
|
|
2544
|
+
/** Models the project can call with its saved provider keys (and, `source: 'credits'`, those its workspace's credit pays for). */
|
|
2496
2545
|
async models() {
|
|
2497
2546
|
return this.client.request(this.path("models"));
|
|
2498
2547
|
}
|
|
@@ -3002,6 +3051,37 @@ var NestCoreError = class extends Error {
|
|
|
3002
3051
|
this.name = "NestCoreError";
|
|
3003
3052
|
this.code = opts.code;
|
|
3004
3053
|
this.status = opts.status;
|
|
3054
|
+
this.details = opts.details;
|
|
3055
|
+
}
|
|
3056
|
+
/** 423: the project is paused (plan limit or owner) or compromised (kill switch). */
|
|
3057
|
+
get isProjectPaused() {
|
|
3058
|
+
return this.code === ProjectErrorCodes.PROJECT_PAUSED;
|
|
3059
|
+
}
|
|
3060
|
+
/** 402 QUOTA_EXCEEDED: where to send the user to upgrade, when the API gave one. */
|
|
3061
|
+
get upgradeUrl() {
|
|
3062
|
+
const u = this.details?.upgradeUrl;
|
|
3063
|
+
return typeof u === "string" ? u : void 0;
|
|
3064
|
+
}
|
|
3065
|
+
/**
|
|
3066
|
+
* 402: an AI call paid from the workspace's prepaid credit found none left
|
|
3067
|
+
* (`reason` `balance`) or hit the monthly cap (`spend_cap`). Don't retry:
|
|
3068
|
+
* offer `buyUrl`, or adding the project's own provider key.
|
|
3069
|
+
*/
|
|
3070
|
+
get isCreditsExhausted() {
|
|
3071
|
+
return this.code === ProjectErrorCodes.CREDITS_EXHAUSTED;
|
|
3072
|
+
}
|
|
3073
|
+
/**
|
|
3074
|
+
* Why the call was refused, when the API said: `balance` | `spend_cap` for
|
|
3075
|
+
* CREDITS_EXHAUSTED, the quota reason (e.g. `ai_collections`) for QUOTA_EXCEEDED.
|
|
3076
|
+
*/
|
|
3077
|
+
get reason() {
|
|
3078
|
+
const r = this.details?.reason;
|
|
3079
|
+
return typeof r === "string" ? r : void 0;
|
|
3080
|
+
}
|
|
3081
|
+
/** 402 CREDITS_EXHAUSTED: where to buy more AI credit. */
|
|
3082
|
+
get buyUrl() {
|
|
3083
|
+
const u = this.details?.buyUrl;
|
|
3084
|
+
return typeof u === "string" ? u : void 0;
|
|
3005
3085
|
}
|
|
3006
3086
|
};
|
|
3007
3087
|
var OrbitNestError = NestCoreError;
|
|
@@ -3009,7 +3089,8 @@ function unwrap(result) {
|
|
|
3009
3089
|
if (result.error) {
|
|
3010
3090
|
throw new NestCoreError(result.error.message, {
|
|
3011
3091
|
code: result.error.code,
|
|
3012
|
-
status: result.error.status
|
|
3092
|
+
status: result.error.status,
|
|
3093
|
+
details: result.error.details
|
|
3013
3094
|
});
|
|
3014
3095
|
}
|
|
3015
3096
|
return result.data;
|
|
@@ -3022,6 +3103,24 @@ var AuthLimitCodes = {
|
|
|
3022
3103
|
/** Too many wrong passwords: the email is locked for the lockout duration. */
|
|
3023
3104
|
ACCOUNT_LOCKED: "ACCOUNT_LOCKED"
|
|
3024
3105
|
};
|
|
3106
|
+
var ProjectErrorCodes = {
|
|
3107
|
+
/**
|
|
3108
|
+
* 402: a plan limit was reached. `details` has quota, plan, limit, usage and, for projects, kind/reason/upgradeUrl
|
|
3109
|
+
* (`reason: 'ai_collections'` = the plan's collections per project).
|
|
3110
|
+
*/
|
|
3111
|
+
QUOTA_EXCEEDED: "QUOTA_EXCEEDED",
|
|
3112
|
+
/**
|
|
3113
|
+
* 402: an AI call paid from prepaid credit found none left. `details`: reason (`balance` | `spend_cap`),
|
|
3114
|
+
* balanceUsd, monthlyCapUsd, spentThisMonthUsd, buyUrl. See {@link CreditsExhaustedDetails}.
|
|
3115
|
+
*/
|
|
3116
|
+
CREDITS_EXHAUSTED: "CREDITS_EXHAUSTED",
|
|
3117
|
+
/** 423: the project is paused (downgrade or owner) or compromised (kill switch). Nothing was deleted. */
|
|
3118
|
+
PROJECT_PAUSED: "PROJECT_PAUSED",
|
|
3119
|
+
/** 403: not allowed on an Agent project (only the agent schema, agent-* buckets and the agent functions). */
|
|
3120
|
+
AGENT_PROJECT_RESTRICTED: "AGENT_PROJECT_RESTRICTED",
|
|
3121
|
+
/** 409: agent-only operation (agent template, agent functions) on an App project. */
|
|
3122
|
+
NOT_AN_AGENT_PROJECT: "NOT_AN_AGENT_PROJECT"
|
|
3123
|
+
};
|
|
3025
3124
|
|
|
3026
3125
|
// src/index.ts
|
|
3027
3126
|
var DEFAULT_BASE_URL = "https://api.nestcore.io";
|
|
@@ -3117,6 +3216,7 @@ export {
|
|
|
3117
3216
|
NestCoreError,
|
|
3118
3217
|
OrbitNestError,
|
|
3119
3218
|
PresenceManager,
|
|
3219
|
+
ProjectErrorCodes,
|
|
3120
3220
|
REGISTRY_TABLE,
|
|
3121
3221
|
RealtimeChannel,
|
|
3122
3222
|
RealtimeClient,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestcorehq/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "NestCore Node.js SDK for database operations, edge functions, and authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
24
24
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
25
25
|
"lint": "eslint src",
|
|
26
|
-
"typecheck": "tsc --noEmit"
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"test": "node test/aliases.test.mjs && node test/client.test.mjs && node test/migrations.test.mjs && node test/query-builder.test.mjs && node test/typegen.test.mjs"
|
|
27
28
|
},
|
|
28
29
|
"keywords": [
|
|
29
30
|
"nestcore",
|