wontopos 2.2.39 → 2.2.41
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 +9 -9
- package/dist/cjs/wontopos.d.cts +360 -189
- package/dist/cjs/wontopos.js +612 -267
- package/dist/wontopos.d.ts +360 -189
- package/dist/wontopos.js +612 -267
- package/package.json +1 -1
package/dist/cjs/wontopos.d.cts
CHANGED
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
* so with no `userId` anywhere the zero-setup path just works.
|
|
16
16
|
*
|
|
17
17
|
* The API key picks *which memory* (your account); `model` picks *which engine*
|
|
18
|
-
* reads it.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
18
|
+
* reads it. `listModels()` reports each model's `memory` as `"shared"` or
|
|
19
|
+
* `"isolated"`, and an isolated one starts empty. Every model on the shared pool
|
|
20
|
+
* lists, fetches and deletes the same memories, but a search may not find memories
|
|
21
|
+
* stored through a different model; store and search with the same one. Set a
|
|
22
|
+
* default in the constructor, or override a single call with
|
|
22
23
|
* `mem.withModel("tablet-1").recall(...)`.
|
|
23
24
|
*
|
|
24
25
|
* Recall quality does not depend on which language a memory was written in: a
|
|
@@ -26,10 +27,11 @@
|
|
|
26
27
|
* and searching call no LLM.
|
|
27
28
|
*
|
|
28
29
|
* Reliability: every call retries transient failures with exponential backoff +
|
|
29
|
-
* jitter, honoring `Retry-After` — 429
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* jitter, honoring `Retry-After` up to 30s — 429 and a 409 that says another write
|
|
31
|
+
* to the store was in flight, always; 408/502/503/504 and connection errors only when
|
|
32
|
+
* a retry can never double-process a write (idempotent calls, or a failure at connect
|
|
33
|
+
* time). Tune with `maxRetries` (0 disables) and `timeoutMs`, or per call site via
|
|
34
|
+
* the `withTimeout()` / `withRetries()` clones.
|
|
33
35
|
*
|
|
34
36
|
* Debugging: set `WONTOPOS_LOG=debug` to log method/path/status/timing/retries
|
|
35
37
|
* to stderr — never memory content, request bodies, or the API key.
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
* runtime's (never disabled by this SDK; Node 18+ floors TLS at 1.2). Prefer
|
|
41
43
|
* `Client.fromEnv()` over keys in source code.
|
|
42
44
|
*/
|
|
43
|
-
/** Test hook
|
|
45
|
+
/** @deprecated Test hook. The warn-once set is process-global by design. */
|
|
44
46
|
export declare function _resetStoreIdWarnings(): void;
|
|
45
47
|
export declare const SEARCH_LIMIT_MIN = 5;
|
|
46
48
|
export declare const SEARCH_LIMIT_MAX = 20;
|
|
@@ -53,16 +55,36 @@ export interface RateLimit {
|
|
|
53
55
|
remaining: number | null;
|
|
54
56
|
reset: number | null;
|
|
55
57
|
}
|
|
58
|
+
/** What a `WosError` carries beyond its status, message and request id. */
|
|
59
|
+
export interface WosErrorInit {
|
|
60
|
+
/** `error.type` from the service's answer. */
|
|
61
|
+
type?: string;
|
|
62
|
+
/** The rest of the service's error object. */
|
|
63
|
+
details?: Record<string, unknown>;
|
|
64
|
+
/** `Retry-After`, in seconds (read by `RateLimitError`). */
|
|
65
|
+
retryAfter?: number;
|
|
66
|
+
/** The underlying error, kept as the standard `cause`. */
|
|
67
|
+
cause?: unknown;
|
|
68
|
+
}
|
|
56
69
|
export declare class WosError extends Error {
|
|
57
70
|
readonly status: number;
|
|
58
71
|
/** The server's id for the request when it sent one — include it when contacting support. */
|
|
59
72
|
readonly requestId?: string;
|
|
60
|
-
|
|
73
|
+
/** `error.type` from the service's answer (e.g. `"conflict_error"`), when it sent one.
|
|
74
|
+
* Control characters are removed and it is capped, like the message. */
|
|
75
|
+
readonly type?: string;
|
|
76
|
+
/** Every other field of the service's error object — all but `message`, `type` and
|
|
77
|
+
* `request_id` — when there is any. Control characters are removed from its keys
|
|
78
|
+
* and strings, each string is capped, and when its JSON is over 8192 characters the
|
|
79
|
+
* biggest fields are left out. A 501 carries `model` and `endpoint` here. */
|
|
80
|
+
readonly details?: Record<string, unknown>;
|
|
81
|
+
constructor(status: number, message: string, requestId?: string, init?: WosErrorInit);
|
|
61
82
|
}
|
|
62
83
|
/** The request never got a response (DNS/TLS/timeout/connection). `status` is 0. */
|
|
63
84
|
export declare class APIConnectionError extends WosError {
|
|
64
85
|
}
|
|
65
|
-
/** 400 — the request was malformed (bad arguments).
|
|
86
|
+
/** 400 — the request was malformed (bad arguments). 413 (body too large) and 422
|
|
87
|
+
* (an idempotency key reused with a different body) arrive as this class too. */
|
|
66
88
|
export declare class BadRequestError extends WosError {
|
|
67
89
|
}
|
|
68
90
|
/** 401 — the API key is missing, wrong, or revoked. */
|
|
@@ -74,14 +96,23 @@ export declare class PaymentRequiredError extends WosError {
|
|
|
74
96
|
/** 403 — the key/model isn't allowed to do this. */
|
|
75
97
|
export declare class PermissionDeniedError extends WosError {
|
|
76
98
|
}
|
|
77
|
-
/** 404 — the store or resource doesn't exist
|
|
99
|
+
/** 404 — the store or resource doesn't exist. */
|
|
78
100
|
export declare class NotFoundError extends WosError {
|
|
79
101
|
}
|
|
80
|
-
/** 409
|
|
102
|
+
/** 409: another write to this store was in flight (retried automatically; nothing was
|
|
103
|
+
* stored), or the store id collides with an existing one (not retried). */
|
|
81
104
|
export declare class ConflictError extends WosError {
|
|
105
|
+
/** The existing store id this one collides with. Set only on a collision, which
|
|
106
|
+
* retrying cannot fix. */
|
|
107
|
+
readonly conflictsWith?: string;
|
|
108
|
+
constructor(status: number, message: string, requestId?: string, init?: WosErrorInit);
|
|
82
109
|
}
|
|
83
|
-
/** 429 — too many requests. Back off and retry (the client already retries these
|
|
110
|
+
/** 429 — too many requests. Back off and retry (the client already retries these,
|
|
111
|
+
* unless `Retry-After` asks for more than 30 seconds). */
|
|
84
112
|
export declare class RateLimitError extends WosError {
|
|
113
|
+
/** Seconds the service asked to wait (`Retry-After`), when it said. */
|
|
114
|
+
readonly retryAfter?: number;
|
|
115
|
+
constructor(status: number, message: string, requestId?: string, init?: WosErrorInit);
|
|
85
116
|
}
|
|
86
117
|
/**
|
|
87
118
|
* 5xx — the service failed.
|
|
@@ -89,11 +120,9 @@ export declare class RateLimitError extends WosError {
|
|
|
89
120
|
* `502` / `503` / `504` are transient: the client already retries them for calls
|
|
90
121
|
* where a retry cannot double-process a write, and retrying yourself is reasonable.
|
|
91
122
|
*
|
|
92
|
-
* `501` is NOT transient. It means the
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* drop the call. Treating the whole 5xx range as retryable sends a caller into a
|
|
96
|
-
* loop that cannot end.
|
|
123
|
+
* `501` is NOT transient. It means the model you selected does not implement that
|
|
124
|
+
* endpoint at all (`details` carries `model` and `endpoint`). Retrying can never
|
|
125
|
+
* succeed — pick a model that supports it (`listModels`) or drop the call.
|
|
97
126
|
*/
|
|
98
127
|
export declare class ServerError extends WosError {
|
|
99
128
|
}
|
|
@@ -139,8 +168,7 @@ export interface StoreResult {
|
|
|
139
168
|
* A genuinely new fact that only varies a detail of one already stored ("no meetings
|
|
140
169
|
* before 10am" next to "no meetings on Fridays") can land here too, so a duplicate is
|
|
141
170
|
* not always a harmless no-op: read this id, and either store one sentence that states
|
|
142
|
-
* both or `update()` the existing memory with the combined statement.
|
|
143
|
-
* dropped write gave the caller nothing to act on.
|
|
171
|
+
* both or `update()` the existing memory with the combined statement.
|
|
144
172
|
*/
|
|
145
173
|
duplicate_of?: string;
|
|
146
174
|
/** Present when the store was a duplicate and something (e.g. a speaker tag) was dropped. */
|
|
@@ -159,6 +187,9 @@ export interface StatusResult {
|
|
|
159
187
|
/**
|
|
160
188
|
* An image attached to a memory, passed to `add`/`store` via `opts.image`.
|
|
161
189
|
*
|
|
190
|
+
* Both edges must be 700px or more; a smaller image is refused (400). A request
|
|
191
|
+
* body is capped at 10MB.
|
|
192
|
+
*
|
|
162
193
|
* What the service keeps is NOT your original. An image whose long edge is over
|
|
163
194
|
* 1568px is downscaled to 1568 before anything else happens, and that smaller
|
|
164
195
|
* picture is what gets stored, and handed back by `getImage`. Nothing on our side
|
|
@@ -173,18 +204,23 @@ export interface StatusResult {
|
|
|
173
204
|
* already fits within 1568px, and a re-encode that would make the file BIGGER is
|
|
174
205
|
* thrown away and your bytes kept as they were.
|
|
175
206
|
*
|
|
176
|
-
* Keep your own copy if you need the full-resolution file.
|
|
177
|
-
* yourself, or put its URL in `reference` — we store that string and never open it.
|
|
207
|
+
* Keep your own copy if you need the full-resolution file.
|
|
178
208
|
*
|
|
179
209
|
* You are billed for the picture we keep, so downscaling never costs you more.
|
|
180
210
|
*/
|
|
181
211
|
export interface ImageInput {
|
|
182
212
|
/** base64 of the image. A `data:image/...;base64,` prefix is accepted and stripped. */
|
|
183
213
|
data: string;
|
|
184
|
-
/**
|
|
214
|
+
/**
|
|
215
|
+
* Where YOUR copy of the image lives. Stored as-is; the service never fetches it.
|
|
216
|
+
*
|
|
217
|
+
* When you send one, the service keeps no image bytes: `getImage` answers 404 for
|
|
218
|
+
* this memory, and you fetch the picture from your own reference.
|
|
219
|
+
*/
|
|
185
220
|
reference?: string;
|
|
186
221
|
/**
|
|
187
|
-
* When the image was TAKEN
|
|
222
|
+
* When the image was TAKEN, if you know it — usually from EXIF. RFC3339 or a plain
|
|
223
|
+
* date (`YYYY-MM-DD`); anything else is refused (400) naming the field.
|
|
188
224
|
*
|
|
189
225
|
* Worth passing: an image knows a moment that its caption does not. This fills
|
|
190
226
|
* `metadata.event_date` when that is empty, so "the day we moved" sorts by when it
|
|
@@ -211,12 +247,8 @@ export interface ImageDeleteResult {
|
|
|
211
247
|
status?: string;
|
|
212
248
|
memory_id?: string;
|
|
213
249
|
/**
|
|
214
|
-
* Whether the MEMORY survives losing its image.
|
|
215
|
-
*
|
|
216
|
-
* A captioned image keeps its text and only loses the image. An image stored with no
|
|
217
|
-
* caption IS the memory, so deleting the image deletes the memory — and the service
|
|
218
|
-
* says so here rather than silently taking more than you asked for. Call with
|
|
219
|
-
* `preview: true` first if that distinction matters to you.
|
|
250
|
+
* Whether the MEMORY survives losing its image. `false` means the delete removed
|
|
251
|
+
* the whole memory; call with `preview: true` first to find out before it happens.
|
|
220
252
|
*/
|
|
221
253
|
memory_kept?: boolean;
|
|
222
254
|
/** Plain-language note about the above, when there is something to say. */
|
|
@@ -242,7 +274,7 @@ export interface RevisionsResult {
|
|
|
242
274
|
revised?: number;
|
|
243
275
|
/** Memories nothing has touched since they were written. Always `total - revised`. */
|
|
244
276
|
unrevised?: number;
|
|
245
|
-
/**
|
|
277
|
+
/** The memories you stored. */
|
|
246
278
|
total?: number;
|
|
247
279
|
/** What `revised` counts, spelled out by the service. */
|
|
248
280
|
counts?: string;
|
|
@@ -291,8 +323,8 @@ export interface LineageResult {
|
|
|
291
323
|
export interface SpeakerPage {
|
|
292
324
|
speaker?: string;
|
|
293
325
|
memories: Memory[];
|
|
294
|
-
/** How many underlying records a delete would actually remove, beyond what was returned. */
|
|
295
326
|
chunks?: number;
|
|
327
|
+
/** The count to show before anyone confirms a delete of this speaker's memories. */
|
|
296
328
|
points_to_delete?: number;
|
|
297
329
|
returned?: number;
|
|
298
330
|
has_more?: boolean;
|
|
@@ -307,20 +339,17 @@ export interface UpdateResult {
|
|
|
307
339
|
status?: string;
|
|
308
340
|
[key: string]: unknown;
|
|
309
341
|
}
|
|
310
|
-
/** `searchFull` → everything one search answered with
|
|
311
|
-
*
|
|
312
|
-
* `
|
|
313
|
-
* almost every call. Two options make it the wrong one: `max_images` asks for
|
|
314
|
-
* photos, which arrive in their own field, and `verify` is reported on by
|
|
315
|
-
* `verify_used`. Merging away both means paying for a
|
|
316
|
-
* search you shaped and never seeing what came of it. */
|
|
342
|
+
/** `searchFull` → everything one search answered with. `search` returns every memory
|
|
343
|
+
* as one array; this keeps the fields apart and adds `verify_used`, the report on
|
|
344
|
+
* the `verify` option. */
|
|
317
345
|
export interface SearchResult {
|
|
318
346
|
/** What others said, and general memories. */
|
|
319
347
|
memories: Memory[];
|
|
320
348
|
/** The assistant's own words (speaker "me"); `[]` on a model that does not keep
|
|
321
349
|
* them apart. */
|
|
322
350
|
self_memories: Memory[];
|
|
323
|
-
/** Image memories
|
|
351
|
+
/** Image memories the answer carried (one by default on an image-capable model,
|
|
352
|
+
* up to `max_images`); `[]` when there were none. */
|
|
324
353
|
images: Memory[];
|
|
325
354
|
/** Re-ask passes actually performed. Present only when `verify` was sent; lower
|
|
326
355
|
* than you asked for means the store had nothing further to add. */
|
|
@@ -398,7 +427,9 @@ export interface StatsResult {
|
|
|
398
427
|
export interface MemoryPage {
|
|
399
428
|
memories: Memory[];
|
|
400
429
|
count: number;
|
|
401
|
-
/** Pass back as `cursor` for the next page; `null`
|
|
430
|
+
/** Pass back as `cursor` for the next page; `null` means there is none. It can be
|
|
431
|
+
* non-null on the last page, and the next call then returns an empty page. Pass
|
|
432
|
+
* back only a cursor the service returned. */
|
|
402
433
|
next_cursor: string | null;
|
|
403
434
|
[key: string]: unknown;
|
|
404
435
|
}
|
|
@@ -409,12 +440,33 @@ export interface SelfSearchResult {
|
|
|
409
440
|
/** The assistant's own words (stored with speaker "me"); `[]` on non-self models. */
|
|
410
441
|
self_memories: Memory[];
|
|
411
442
|
}
|
|
443
|
+
/** What a model can do, as `listModels()` reports it. A model without a feature
|
|
444
|
+
* refuses the call that needs it (usually 403) or answers without that part. */
|
|
445
|
+
export interface ModelCapabilities {
|
|
446
|
+
/** Image memories: `opts.image` on `add`, `max_images`, `getImage`, `listImages`. */
|
|
447
|
+
images?: boolean;
|
|
448
|
+
/** `engram()`; `listEngrams()` names the ones this model runs. */
|
|
449
|
+
engrams?: boolean;
|
|
450
|
+
/** Delivery forms (`form` / `tz`) on search, recall and engram. */
|
|
451
|
+
forms?: boolean;
|
|
452
|
+
/** Re-ask passes (`verify`) on search. */
|
|
453
|
+
re_ask?: boolean;
|
|
454
|
+
/** The assistant's own words apart, in `self_memories`. */
|
|
455
|
+
self_memories?: boolean;
|
|
456
|
+
/** Speaker names, as the service reports them. */
|
|
457
|
+
speaker_names?: boolean;
|
|
458
|
+
[key: string]: boolean | undefined;
|
|
459
|
+
}
|
|
412
460
|
export interface ModelInfo {
|
|
413
461
|
id: string;
|
|
414
462
|
name: string;
|
|
415
463
|
available: boolean;
|
|
416
|
-
/** "shared" —
|
|
464
|
+
/** "shared" — lists, fetches and deletes the common memory pool, though a search
|
|
465
|
+
* may not find memories stored through a different model; "isolated" — its own
|
|
466
|
+
* dedicated store. */
|
|
417
467
|
memory: "shared" | "isolated";
|
|
468
|
+
/** What this model can do. Check it before relying on a feature. */
|
|
469
|
+
capabilities?: ModelCapabilities;
|
|
418
470
|
}
|
|
419
471
|
/** One entry of the engram / delivery-form catalogue (`listEngrams`). */
|
|
420
472
|
export interface EngramInfo {
|
|
@@ -434,18 +486,21 @@ export interface EngramCatalog {
|
|
|
434
486
|
}
|
|
435
487
|
/** `createStore` / `deleteStore` → `{ user_id, status }`. */
|
|
436
488
|
export interface StoreOpResult {
|
|
437
|
-
/** The store id
|
|
438
|
-
* Ids are normalized (see the `note`), so compare this against your input. */
|
|
489
|
+
/** The store id. `createStore` answers with the id as you sent it. */
|
|
439
490
|
user_id?: string;
|
|
491
|
+
/** The normalized form the store is filed under, when it differs from `user_id`. */
|
|
492
|
+
canonical_id?: string;
|
|
440
493
|
status?: string;
|
|
441
|
-
/** Present when the API
|
|
442
|
-
* end users can land in one store if their ids differ only by punctuation. */
|
|
494
|
+
/** Present when the API filed your id under a normalized form, explaining how. */
|
|
443
495
|
note?: string;
|
|
444
496
|
[key: string]: unknown;
|
|
445
497
|
}
|
|
446
498
|
export interface StoreInfo {
|
|
499
|
+
/** The id the store was created with — pass it back as `userId`. */
|
|
447
500
|
user_id: string;
|
|
448
501
|
created_at: string;
|
|
502
|
+
/** The normalized form the store is filed under, when it differs from `user_id`. */
|
|
503
|
+
canonical_id?: string;
|
|
449
504
|
[key: string]: unknown;
|
|
450
505
|
}
|
|
451
506
|
/** `addSpeaker` / `removeSpeaker` → `{ user_id, speaker, status }`. */
|
|
@@ -477,21 +532,29 @@ export interface SpeakersList {
|
|
|
477
532
|
* Retrieval behaves the same in every language, so these behave
|
|
478
533
|
* identically in every language. Unlisted keys are dropped by the API rather than
|
|
479
534
|
* rejected, so a typo silently widens the search — spell them exactly.
|
|
535
|
+
*
|
|
536
|
+
* Filters apply to `memories`. The assistant's own words (`self_memories`) are not
|
|
537
|
+
* filtered, and `search` merges them into its answer, so read `searchFull` when a
|
|
538
|
+
* filtered answer must hold only what matched.
|
|
539
|
+
*
|
|
540
|
+
* Every date takes RFC3339 or a plain date (`YYYY-MM-DD`). A plain end date
|
|
541
|
+
* (`time_to`, `event_to`) covers that whole day in UTC. A value that is not a date
|
|
542
|
+
* is refused (400) naming the field.
|
|
480
543
|
*/
|
|
481
544
|
export interface SearchFilters {
|
|
482
545
|
/** Only these categories (the `category` you see on `listMemories` results). */
|
|
483
546
|
categories?: string[];
|
|
484
|
-
/**
|
|
547
|
+
/** When the memory was stored. */
|
|
485
548
|
time_from?: string;
|
|
486
549
|
time_to?: string;
|
|
487
550
|
/** WHEN THE CONTENT HAPPENED (`metadata.event_date`), not when it was written —
|
|
488
|
-
* this is the one you usually want.
|
|
551
|
+
* this is the one you usually want. */
|
|
489
552
|
event_from?: string;
|
|
490
553
|
event_to?: string;
|
|
491
554
|
/** Drop matches the engine scored below this importance (0–1). */
|
|
492
555
|
min_importance?: number;
|
|
493
556
|
}
|
|
494
|
-
/** Test hook
|
|
557
|
+
/** @deprecated Test hook. The warn-once set is process-global by design. */
|
|
495
558
|
export declare function _resetFilterWarnings(): void;
|
|
496
559
|
/** Known `search` options. An unknown key is refused before anything is sent — the
|
|
497
560
|
* service drops keys it does not recognise and answers normally, so a misspelling
|
|
@@ -520,26 +583,29 @@ export interface SearchOptions {
|
|
|
520
583
|
* that need several distinct memories from far apart in the history; it does little
|
|
521
584
|
* on a single-fact lookup.
|
|
522
585
|
*
|
|
523
|
-
* Requires a
|
|
524
|
-
*
|
|
586
|
+
* Requires a model that lists `re_ask` in its `listModels()` capabilities; any
|
|
587
|
+
* other refuses the call (403) rather than charging for passes that never happened.
|
|
525
588
|
*/
|
|
526
589
|
verify?: number;
|
|
527
590
|
/**
|
|
528
591
|
* How many image memories the answer may carry, 0–5. Omit it and the service uses
|
|
529
|
-
* 1; `0` asks for none.
|
|
530
|
-
*
|
|
531
|
-
* Out of range is refused, not clamped — silently cutting 5 to 1 would leave you
|
|
532
|
-
* believing you got five.
|
|
592
|
+
* 1; `0` asks for none. Out of range is refused before the request, not clamped —
|
|
593
|
+
* silently cutting 6 to 5 would leave you believing you got six.
|
|
533
594
|
*
|
|
534
|
-
* Requires
|
|
535
|
-
* than answering with no images.
|
|
595
|
+
* Requires a model that lists `images` in its capabilities, and is refused (403)
|
|
596
|
+
* on one without it rather than answering with no images.
|
|
536
597
|
*/
|
|
537
598
|
max_images?: number;
|
|
599
|
+
/** Delivery form, "memoir" or "archive": how each memory's time is rendered. Needs a
|
|
600
|
+
* model that lists `forms` in its capabilities. The service refuses an unknown
|
|
601
|
+
* form (400). */
|
|
602
|
+
form?: string;
|
|
603
|
+
/** Your UTC offset in hours, for rendering times in `form`. */
|
|
604
|
+
tz?: number;
|
|
538
605
|
/**
|
|
539
606
|
* Fields the service accepts that this version does not know about, merged into the
|
|
540
|
-
* request as written. Every other key is refused, so a typo cannot reach the wire
|
|
541
|
-
*
|
|
542
|
-
* a caller billed for one pass believing they had bought three.
|
|
607
|
+
* request as written. Every other key is refused, so a typo cannot reach the wire.
|
|
608
|
+
* The store, the query and the count always win over a copy in here.
|
|
543
609
|
*/
|
|
544
610
|
extra?: Record<string, unknown>;
|
|
545
611
|
}
|
|
@@ -547,69 +613,128 @@ export interface SearchOptions {
|
|
|
547
613
|
* Per-call options for a write.
|
|
548
614
|
*
|
|
549
615
|
* `idempotencyKey` makes repeating THIS EXACT write safe: the API replays the first
|
|
550
|
-
* response instead of storing again, for 10 minutes, and answers 422 if the
|
|
551
|
-
* arrives with a different body. Use it when a retry is your own (a job that
|
|
552
|
-
* was re-run, a queue that redelivers). The SDK retries a write on
|
|
553
|
-
*
|
|
554
|
-
* was stored. It never retries a write
|
|
555
|
-
*
|
|
556
|
-
* know whether it
|
|
616
|
+
* response instead of storing again, for up to 10 minutes, and answers 422 if the
|
|
617
|
+
* same key arrives with a different body. Use it when a retry is your own (a job that
|
|
618
|
+
* died and was re-run, a queue that redelivers). The SDK retries a write on 429, and
|
|
619
|
+
* on a 409 that says another write to the store was in flight: the service answers
|
|
620
|
+
* both before it processes anything, so nothing was stored. It never retries a write
|
|
621
|
+
* on 408 / 502 / 503 / 504 or a dropped body, where the write may already have been
|
|
622
|
+
* applied — without a key the client cannot know whether it was.
|
|
623
|
+
*
|
|
624
|
+
* The key covers a retry sent after the first attempt finished. A retry that overlaps
|
|
625
|
+
* a first attempt still running can run twice, so wait for the first to fail before
|
|
626
|
+
* re-sending.
|
|
557
627
|
*
|
|
558
628
|
* The key must be UNIQUE PER LOGICAL WRITE — derive it from the thing being stored
|
|
559
629
|
* (`` `import:${row.id}` ``), never a constant, or the second write replays the first
|
|
560
630
|
* and is silently lost. Format: 1-128 chars of `[A-Za-z0-9._:-]`, checked locally.
|
|
561
631
|
*
|
|
562
|
-
* The window is
|
|
563
|
-
*
|
|
632
|
+
* The window is best-effort and can be shorter than 10 minutes; it is not a durable
|
|
633
|
+
* de-duplication record.
|
|
564
634
|
*/
|
|
565
635
|
export interface WriteOptions {
|
|
566
636
|
idempotencyKey?: string;
|
|
567
637
|
/**
|
|
568
|
-
* An image to store alongside the text
|
|
638
|
+
* An image to store alongside the text. Needs a model that lists `images` in its
|
|
639
|
+
* `listModels()` capabilities; any other refuses the write rather than store the
|
|
640
|
+
* caption and quietly drop the image.
|
|
569
641
|
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
* write rather than store the caption and quietly drop the image.
|
|
642
|
+
* A caption is required: the service refuses empty `content` (400) even with an
|
|
643
|
+
* image attached.
|
|
573
644
|
*/
|
|
574
645
|
image?: ImageInput;
|
|
575
646
|
}
|
|
647
|
+
/** The part of an `AbortSignal` the client uses, for a runtime that declares none. */
|
|
648
|
+
export interface AbortSignalShape {
|
|
649
|
+
readonly aborted: boolean;
|
|
650
|
+
addEventListener(type: "abort", listener: () => void): void;
|
|
651
|
+
removeEventListener(type: "abort", listener: () => void): void;
|
|
652
|
+
}
|
|
653
|
+
/** The runtime's own `AbortSignal` type when it declares one (the DOM lib,
|
|
654
|
+
* `@types/node`), otherwise {@link AbortSignalShape}. `AbortController#signal` fits. */
|
|
655
|
+
export type AbortSignalLike = typeof globalThis extends {
|
|
656
|
+
AbortSignal: {
|
|
657
|
+
prototype: infer S;
|
|
658
|
+
};
|
|
659
|
+
} ? S : AbortSignalShape;
|
|
660
|
+
/** The `init` the client passes to `fetch`. */
|
|
661
|
+
export interface FetchInitLike {
|
|
662
|
+
method: string;
|
|
663
|
+
headers: Record<string, string>;
|
|
664
|
+
body?: string;
|
|
665
|
+
signal: AbortSignalLike;
|
|
666
|
+
redirect: "manual";
|
|
667
|
+
}
|
|
668
|
+
/** The part of a `fetch` response the client reads. */
|
|
669
|
+
export interface FetchResponseLike {
|
|
670
|
+
readonly status: number;
|
|
671
|
+
readonly ok: boolean;
|
|
672
|
+
readonly type?: string;
|
|
673
|
+
readonly url?: string;
|
|
674
|
+
readonly redirected?: boolean;
|
|
675
|
+
readonly headers: {
|
|
676
|
+
get(name: string): string | null;
|
|
677
|
+
};
|
|
678
|
+
readonly body?: {
|
|
679
|
+
getReader(): {
|
|
680
|
+
read(): Promise<{
|
|
681
|
+
done: boolean;
|
|
682
|
+
value?: Uint8Array;
|
|
683
|
+
}>;
|
|
684
|
+
cancel(reason?: unknown): Promise<void>;
|
|
685
|
+
};
|
|
686
|
+
cancel(reason?: unknown): Promise<void>;
|
|
687
|
+
} | null;
|
|
688
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
689
|
+
}
|
|
690
|
+
/** The runtime's own `fetch` type when it declares one (the DOM lib, `@types/node`),
|
|
691
|
+
* otherwise a structural signature, so these types need neither. */
|
|
692
|
+
export type FetchLike = typeof globalThis extends {
|
|
693
|
+
fetch: infer F;
|
|
694
|
+
} ? F : (url: string, init: FetchInitLike) => Promise<FetchResponseLike>;
|
|
576
695
|
export interface ClientOptions {
|
|
577
696
|
apiKey: string;
|
|
578
|
-
/** API base URL (defaults to the hosted service)
|
|
697
|
+
/** API base URL (defaults to the hosted service): an http or https URL or, where
|
|
698
|
+
* the runtime has a page, a URL relative to it. Whitespace at either end is
|
|
699
|
+
* trimmed; whitespace, a control character or a backslash left in it after that is
|
|
700
|
+
* refused.
|
|
701
|
+
* A relative URL where the runtime has no page (server-side rendering) fails the
|
|
702
|
+
* first call that uses it, or goes to `fetch` as given when you pass one. */
|
|
579
703
|
baseUrl?: string;
|
|
580
|
-
/** Per-request timeout in ms, applied to each retry attempt (default 30000).
|
|
704
|
+
/** Per-request timeout in ms, applied to each retry attempt (default 30000). A
|
|
705
|
+
* value that is not a positive number means the default; values above 2147483647
|
|
706
|
+
* are clamped to it. */
|
|
581
707
|
timeoutMs?: number;
|
|
582
708
|
/** Default model for every call (sent as `X-WOS-Model`). See `listModels()`. */
|
|
583
709
|
model?: string;
|
|
584
|
-
/** Default store for every call. Override per call by passing `userId`.
|
|
585
|
-
* to the account's built-in `default` store
|
|
710
|
+
/** Default store for every call. Override per call by passing `userId`. Leave it
|
|
711
|
+
* out to use the account's built-in `default` store; passing it as `undefined` is
|
|
712
|
+
* refused, because that is usually a lookup that found nothing. */
|
|
586
713
|
userId?: string;
|
|
587
|
-
/** How many times to retry transient failures before throwing — 429
|
|
588
|
-
* 408/502/503/504 and connection
|
|
589
|
-
* double-process a write. 0 disables retries
|
|
714
|
+
/** How many times to retry transient failures before throwing — 429 and a 409
|
|
715
|
+
* that says another write was in flight, always; 408/502/503/504 and connection
|
|
716
|
+
* errors only when a retry can never double-process a write. 0 disables retries
|
|
717
|
+
* (default 2). */
|
|
590
718
|
maxRetries?: number;
|
|
591
|
-
/** Alias of `maxRetries`.
|
|
592
|
-
* SDKs are published in lockstep as "the same surface" — so code ported between
|
|
593
|
-
* them silently lost its retry setting instead of failing loudly (an unknown
|
|
594
|
-
* key on an options object is not an error in TS at runtime). Both names work;
|
|
595
|
-
* `maxRetries` wins if somehow both are given. */
|
|
719
|
+
/** Alias of `maxRetries`. `maxRetries` wins when both are given. */
|
|
596
720
|
retries?: number;
|
|
597
721
|
/** A total budget for one call, in ms, across every attempt.
|
|
598
722
|
*
|
|
599
723
|
* `timeoutMs` bounds ONE attempt. At the defaults — 30s, two retries — a single
|
|
600
724
|
* call can hold a connection for 30s + backoff + 30s + backoff + 30s, over a
|
|
601
|
-
* minute
|
|
602
|
-
*
|
|
725
|
+
* minute. Unset means no overall budget. A retry whose wait does not fit in what
|
|
726
|
+
* is left is not made: the call fails with the error of the last response. A
|
|
727
|
+
* value that is not a positive number means no budget; values above 2147483647
|
|
728
|
+
* are clamped to it. */
|
|
603
729
|
deadlineMs?: number;
|
|
604
730
|
/** The caller's `AbortSignal` — cancel work already in flight.
|
|
605
731
|
*
|
|
606
732
|
* The SDK aborts on its own timeout; this is the seam for the caller's reason.
|
|
607
|
-
* When someone closes the chat window, the recall that window asked for
|
|
608
|
-
*
|
|
609
|
-
* running to completion and billing for an answer nobody will read.
|
|
733
|
+
* When someone closes the chat window, the recall that window asked for ends, and
|
|
734
|
+
* so does a backoff sleep waiting to retry it.
|
|
610
735
|
*
|
|
611
736
|
* Per call, clone: `mem.withSignal(ctrl.signal).recall(...)`. */
|
|
612
|
-
signal?:
|
|
737
|
+
signal?: AbortSignalLike;
|
|
613
738
|
/** The `fetch` used for every request (default: the global `fetch`).
|
|
614
739
|
*
|
|
615
740
|
* This is the seam for anything the runtime cannot express through options.
|
|
@@ -626,8 +751,12 @@ export interface ClientOptions {
|
|
|
626
751
|
*
|
|
627
752
|
* It is also how you add instrumentation or drive the client in a test without
|
|
628
753
|
* a network. Retries, timeouts, redirect refusal and the size cap all still
|
|
629
|
-
* apply — this replaces the transport, not the client's rules.
|
|
630
|
-
|
|
754
|
+
* apply — this replaces the transport, not the client's rules. Pass
|
|
755
|
+
* `init.redirect` through unchanged: a fetch that follows a redirect sends the
|
|
756
|
+
* key to wherever it points, and an answer it reports as redirected
|
|
757
|
+
* (`res.redirected`) is refused. A fetch that sends the request to another URL
|
|
758
|
+
* on purpose, such as a proxy that rewrites it, is fine. */
|
|
759
|
+
fetch?: FetchLike;
|
|
631
760
|
}
|
|
632
761
|
/** Wontopos memory client. Store and recall memories, isolated per `userId`. */
|
|
633
762
|
export declare class Client {
|
|
@@ -642,6 +771,13 @@ export declare class Client {
|
|
|
642
771
|
/** Transport. Held as a field (not read off `globalThis` per call) so a caller
|
|
643
772
|
* who passes one gets it for every request, including from cloned clients. */
|
|
644
773
|
private readonly fetchImpl;
|
|
774
|
+
/** Whether `baseUrl` carries userinfo, which network errors must not show. */
|
|
775
|
+
private readonly userinfo;
|
|
776
|
+
/** Whether `baseUrl` did not resolve to a URL at construction: a relative one where
|
|
777
|
+
* the runtime had no page. */
|
|
778
|
+
private readonly pageRelative;
|
|
779
|
+
/** Whether the caller supplied `fetch`. */
|
|
780
|
+
private readonly customFetch;
|
|
645
781
|
/** The store every call uses unless one passes `userId`. */
|
|
646
782
|
private readonly defaultUser;
|
|
647
783
|
private _rateLimit;
|
|
@@ -653,7 +789,7 @@ export declare class Client {
|
|
|
653
789
|
/** A client whose key comes from `WONTOPOS_API_KEY` (or `WOS_API_KEY`) — keeps
|
|
654
790
|
* keys out of source code. Node/Bun/Deno-with-env only. */
|
|
655
791
|
static fromEnv(opts?: Omit<ClientOptions, "apiKey">): Client;
|
|
656
|
-
/** Never expose the key: `JSON.stringify(client)` gets the redacted view. */
|
|
792
|
+
/** Never expose the key or a URL password: `JSON.stringify(client)` gets the redacted view. */
|
|
657
793
|
toJSON(): Record<string, string>;
|
|
658
794
|
/** Resolve a call's store: the explicit userId, else the client default. */
|
|
659
795
|
private uid;
|
|
@@ -673,7 +809,7 @@ export declare class Client {
|
|
|
673
809
|
* const r = await mem.withSignal(ctrl.signal).recall(q, user);
|
|
674
810
|
*
|
|
675
811
|
* Aborting ends the request in flight AND any backoff sleep waiting to retry it. */
|
|
676
|
-
withSignal(signal:
|
|
812
|
+
withSignal(signal: AbortSignalLike): Client;
|
|
677
813
|
/** A client with a total budget per call, across every retry (everything else
|
|
678
814
|
* kept). `mem.withDeadline(5_000).search(q)` inside a handler that has five
|
|
679
815
|
* seconds. */
|
|
@@ -683,19 +819,23 @@ export declare class Client {
|
|
|
683
819
|
withTimeout(timeoutMs: number): Client;
|
|
684
820
|
/** A client with a different retry budget (everything else kept). 0 disables retries. */
|
|
685
821
|
withRetries(maxRetries: number): Client;
|
|
686
|
-
/** Store one memory. `metadata` optional —
|
|
687
|
-
*
|
|
688
|
-
*
|
|
689
|
-
*
|
|
822
|
+
/** Store one memory. `metadata` optional — the service keeps only these keys and
|
|
823
|
+
* drops any other (this client warns once per unknown key):
|
|
824
|
+
* - `event_date`: when the content actually happened, RFC3339 or a plain date
|
|
825
|
+
* (`YYYY-MM-DD`, read as UTC midnight); anything else is refused (400) naming the field.
|
|
826
|
+
* - `speaker`: "me" = the assistant's own words, or a person's name (up to 50 per store).
|
|
827
|
+
* - `category`, `conversation_id`.
|
|
690
828
|
*
|
|
691
829
|
* `opts.idempotencyKey`: see {@link WriteOptions} — pass one to make YOUR retry
|
|
692
830
|
* of this exact write safe to repeat. */
|
|
693
831
|
add(content: string, userId?: string, metadata?: Record<string, unknown>, opts?: WriteOptions): Promise<StoreResult>;
|
|
694
|
-
/** Alias of `add` — store one memory.
|
|
832
|
+
/** Alias of `add` — store one memory. */
|
|
695
833
|
store(content: string, userId?: string, metadata?: Record<string, unknown>, opts?: WriteOptions): Promise<StoreResult>;
|
|
696
834
|
/** Store a conversation turn (user + assistant). Payload first, userId last — same shape as add/search. */
|
|
697
835
|
addTurn(userMsg: string, assistantMsg: string, userId?: string, opts?: WriteOptions): Promise<StatusResult>;
|
|
698
836
|
/** Bulk-ingest a large blob of text in one call. For backfilling.
|
|
837
|
+
* `timestamp` must be RFC3339 (`2026-05-02T09:00:00Z`): a plain date or any other
|
|
838
|
+
* string is ignored, and the memory is filed at upload time.
|
|
699
839
|
* The call most worth an `opts.idempotencyKey`: a backfill that dies halfway and is
|
|
700
840
|
* re-run would otherwise ingest the whole blob a second time. */
|
|
701
841
|
addBulk(content: string, userId?: string, category?: string, timestamp?: string, opts?: WriteOptions): Promise<StatusResult>;
|
|
@@ -704,22 +844,25 @@ export declare class Client {
|
|
|
704
844
|
/** Search a store's memories. Returns them most relevant first.
|
|
705
845
|
*
|
|
706
846
|
* `limit` is 5-20, and out of range is refused rather than clamped: asking for 50
|
|
707
|
-
* and silently receiving 20 reads as "that is all there is". The default is 10
|
|
708
|
-
* a call that passes no count is unaffected. Before 2.2.35 the count was sent on
|
|
709
|
-
* unchecked.
|
|
847
|
+
* and silently receiving 20 reads as "that is all there is". The default is 10.
|
|
710
848
|
*
|
|
711
|
-
* `limit` bounds `memories`, not the returned array.
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
* on the array you get back, not on `limit`. `
|
|
716
|
-
* apart.
|
|
849
|
+
* `limit` bounds `memories`, not the returned array. The assistant's own words (on
|
|
850
|
+
* a model that lists `self_memories` in its capabilities) and image memories (one
|
|
851
|
+
* unless `max_images` says otherwise, on a model that lists `images`) come back in
|
|
852
|
+
* it as well, so it can hold more than `limit`. They are billed either way. Size a
|
|
853
|
+
* prompt window on the array you get back, not on `limit`. `searchFull()` hands the
|
|
854
|
+
* fields back apart.
|
|
855
|
+
*
|
|
856
|
+
* `filters` apply to `memories` only; the assistant's own words merged in here are
|
|
857
|
+
* not filtered. */
|
|
717
858
|
search(query: string, userId?: string, limit?: number, opts?: SearchOptions): Promise<Memory[]>;
|
|
718
|
-
/** Search
|
|
719
|
-
* `{ memories, self_memories }` — `memories` is what others said and general
|
|
859
|
+
/** Search, with the assistant's own words kept apart: both fields from ONE call.
|
|
860
|
+
* Returns `{ memories, self_memories }` — `memories` is what others said and general
|
|
720
861
|
* memories, `self_memories` is the assistant's OWN words (stored with speaker
|
|
721
862
|
* "me"), kept apart so whoever reads them never confuses who said what. On a model
|
|
722
|
-
* that does not
|
|
863
|
+
* that does not list `self_memories` in its capabilities, `self_memories` is `[]`.
|
|
864
|
+
* Image memories are not included; `search` and `searchFull` carry them. `filters`
|
|
865
|
+
* apply to `memories` only. `userId` may be omitted. */
|
|
723
866
|
searchSelf(query: string, userId?: string, limit?: number, opts?: SearchOptions): Promise<SelfSearchResult>;
|
|
724
867
|
/**
|
|
725
868
|
* Search, and keep every field the answer came with.
|
|
@@ -729,16 +872,18 @@ export declare class Client {
|
|
|
729
872
|
*
|
|
730
873
|
* const r = await mem.searchFull("the day we moved", "alice", 10,
|
|
731
874
|
* { max_images: 3, verify: 2 });
|
|
732
|
-
* r.images.length; // the photos,
|
|
875
|
+
* r.images.length; // the photos, apart from the text memories
|
|
733
876
|
* r.verify_used; // how many re-ask passes actually ran (you are billed per pass)
|
|
734
877
|
*
|
|
735
|
-
*
|
|
736
|
-
* rather than accepted and
|
|
878
|
+
* Each option needs a model that lists it in its `listModels()` capabilities
|
|
879
|
+
* (`images`, `re_ask`) and is refused (403) on any other rather than accepted and
|
|
880
|
+
* ignored. `filters` apply to `memories`; `self_memories` are not filtered.
|
|
737
881
|
*/
|
|
738
882
|
searchFull(query: string, userId?: string, limit?: number, opts?: SearchOptions): Promise<SearchResult>;
|
|
739
883
|
/** One-call LLM context: short-term turns + long-term matches + surrounding context.
|
|
740
|
-
* `form` ("memoir"/"archive",
|
|
741
|
-
* that form; `tz` is your UTC-offset hours
|
|
884
|
+
* `form` ("memoir"/"archive", on a model that lists `forms` in its capabilities)
|
|
885
|
+
* renders each long-term memory's time in that form; `tz` is your UTC-offset hours
|
|
886
|
+
* for that rendering. */
|
|
742
887
|
recall(query: string, userId?: string, opts?: {
|
|
743
888
|
form?: string;
|
|
744
889
|
tz?: number;
|
|
@@ -746,19 +891,19 @@ export declare class Client {
|
|
|
746
891
|
* Long-term memories to recall, 5–20. Default 10. Out of range is refused, not
|
|
747
892
|
* clamped — asking for 20 and silently getting 10 reads as "that is all there is".
|
|
748
893
|
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
* did not ask for.
|
|
894
|
+
* A model that does not take a recall count refuses the call (403) rather than
|
|
895
|
+
* answering with a number you did not ask for.
|
|
752
896
|
*/
|
|
753
897
|
limit?: number;
|
|
754
898
|
/** How much surrounding context is attached around the best match, 0–20. Default 10;
|
|
755
|
-
* 0 attaches none.
|
|
899
|
+
* 0 attaches none. Refused (403) by the same models as `limit`. */
|
|
756
900
|
context_limit?: number;
|
|
757
901
|
}): Promise<RecallResult>;
|
|
758
902
|
/** Run a built-in engram ("deep_recall" | "timeline" | "gather" | "equilibrium" |
|
|
759
903
|
* "tone_stabilizer"; the service is the authority — an unknown name comes back with
|
|
760
904
|
* the list it accepts). Returns the merged result.
|
|
761
|
-
* `form`/`tz` render memory times (memoir/archive) on
|
|
905
|
+
* `form`/`tz` render memory times (memoir/archive) on a model that lists `forms` in
|
|
906
|
+
* its capabilities, same as search/recall. */
|
|
762
907
|
engram(name: string, query: string, userId?: string, opts?: {
|
|
763
908
|
form?: string;
|
|
764
909
|
tz?: number;
|
|
@@ -783,13 +928,17 @@ export declare class Client {
|
|
|
783
928
|
usage(days?: number): Promise<UsageResult>;
|
|
784
929
|
/** Fetch ONE memory by id — the text you stored, and its metadata.
|
|
785
930
|
* The id is what `add`/`store` or `listMemories` returned. Same visibility as
|
|
786
|
-
* `listMemories`: an id from another store, an
|
|
787
|
-
* invalidated memory rejects with `NotFoundError`. Pass `undefined` as
|
|
788
|
-
* the default store — it is positional here
|
|
931
|
+
* `listMemories`: an id from another store, an id `listMemories` does not return,
|
|
932
|
+
* or an invalidated memory rejects with `NotFoundError`. Pass `undefined` as
|
|
933
|
+
* `userId` for the default store — it is positional here. */
|
|
789
934
|
get(userId: string | undefined, memoryId: string): Promise<Memory>;
|
|
790
935
|
/** List a store's stored memories — the text you stored, plus its metadata.
|
|
791
936
|
* Paginated: pass the returned `next_cursor` back as `cursor` for the next
|
|
792
|
-
* page
|
|
937
|
+
* page, and only a cursor the service returned. A `null` cursor means there is no
|
|
938
|
+
* next page; a non-null one can still be followed by an empty page. Use it to
|
|
939
|
+
* browse or export a store.
|
|
940
|
+
*
|
|
941
|
+
* `limit` is 1-500 (default 100); anything else is refused before the request.
|
|
793
942
|
*
|
|
794
943
|
* let cursor: string | null = null;
|
|
795
944
|
* const all: Memory[] = [];
|
|
@@ -804,7 +953,11 @@ export declare class Client {
|
|
|
804
953
|
cursor?: string;
|
|
805
954
|
}): Promise<MemoryPage>;
|
|
806
955
|
/** Async-iterate every stored memory in a store, paging under the hood — no cursor
|
|
807
|
-
* bookkeeping. The text you stored and its metadata only.
|
|
956
|
+
* bookkeeping. The text you stored and its metadata only. `pageSize` is 1-500.
|
|
957
|
+
*
|
|
958
|
+
* A walk that cannot reach the end of the store (the service hands back a cursor it
|
|
959
|
+
* already gave after a non-empty page, or the page ceiling is reached) throws rather
|
|
960
|
+
* than end with part of the store.
|
|
808
961
|
*
|
|
809
962
|
* for await (const m of mem.iterMemories()) console.log(m.id, m.content);
|
|
810
963
|
*/
|
|
@@ -814,7 +967,7 @@ export declare class Client {
|
|
|
814
967
|
/** Collect ALL of a store's memories into an array (the text you stored, and its metadata). */
|
|
815
968
|
exportMemories(userId?: string): Promise<Memory[]>;
|
|
816
969
|
/** Collect ALL of a store's image memories into an array — the image-side pair of
|
|
817
|
-
* `exportMemories`. */
|
|
970
|
+
* `exportMemories`. `pageSize` is 5-20. */
|
|
818
971
|
exportImages(userId?: string, opts?: {
|
|
819
972
|
pageSize?: number;
|
|
820
973
|
}): Promise<Memory[]>;
|
|
@@ -830,9 +983,9 @@ export declare class Client {
|
|
|
830
983
|
*
|
|
831
984
|
* The type is sniffed from the bytes themselves rather than from whatever the file
|
|
832
985
|
* was called, so name the file from `contentType` rather than from what you sent.
|
|
833
|
-
*
|
|
834
|
-
*
|
|
835
|
-
*
|
|
986
|
+
* Rejects with `NotFoundError` when this memory has no image, or when the service
|
|
987
|
+
* keeps no image bytes for it — which is always the case for an image stored with
|
|
988
|
+
* `reference`: fetch that one from your own reference. It says "no" instead of
|
|
836
989
|
* handing back something empty, so "a memory with no image" never looks the same as
|
|
837
990
|
* "an image we lost".
|
|
838
991
|
*
|
|
@@ -844,10 +997,9 @@ export declare class Client {
|
|
|
844
997
|
/**
|
|
845
998
|
* Remove the PHOTO from a memory, keeping its text.
|
|
846
999
|
*
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
* nothing.
|
|
1000
|
+
* `preview: true` reports what would happen, including `memory_kept`, and changes
|
|
1001
|
+
* nothing. Retried like `deleteStore`; without `preview`, a 404 after an ambiguous
|
|
1002
|
+
* failure carries the same note.
|
|
851
1003
|
*
|
|
852
1004
|
* const p = await mem.forgetImage(undefined, id, { preview: true });
|
|
853
1005
|
* if (p.memory_kept === false) { /* this would delete the whole memory *\/ }
|
|
@@ -863,13 +1015,16 @@ export declare class Client {
|
|
|
863
1015
|
* `next_before` and `next_skip_ids` back as `before` / `skipIds`. The pair exists
|
|
864
1016
|
* because several images can share a timestamp, and a timestamp alone would either
|
|
865
1017
|
* repeat them or skip them.
|
|
1018
|
+
*
|
|
1019
|
+
* `limit` is 5-20; anything else is refused before the request.
|
|
866
1020
|
*/
|
|
867
1021
|
listImages(userId?: string, opts?: {
|
|
868
1022
|
limit?: number;
|
|
869
1023
|
before?: string;
|
|
870
1024
|
skipIds?: string[];
|
|
871
1025
|
}): Promise<ImagePage>;
|
|
872
|
-
/** Async-iterate every image memory, paging under the hood.
|
|
1026
|
+
/** Async-iterate every image memory, paging under the hood. `pageSize` is 5-20.
|
|
1027
|
+
* Like `iterMemories`, a walk that cannot reach the end throws. */
|
|
873
1028
|
iterImages(userId?: string, opts?: {
|
|
874
1029
|
pageSize?: number;
|
|
875
1030
|
}): AsyncGenerator<Memory>;
|
|
@@ -882,9 +1037,8 @@ export declare class Client {
|
|
|
882
1037
|
* rewritten. Free, and it never reaches the retrieval path.
|
|
883
1038
|
*
|
|
884
1039
|
* Counts memories a transform touched (supersede, update, retract, image removed).
|
|
885
|
-
* Deletions are NOT counted: a deleted memory leaves nothing to count.
|
|
886
|
-
* the
|
|
887
|
-
* so they do not belong in a ratio that answers "how much of MY memory changed".
|
|
1040
|
+
* Deletions are NOT counted: a deleted memory leaves nothing to count. `total`
|
|
1041
|
+
* counts the memories you stored.
|
|
888
1042
|
*
|
|
889
1043
|
* By default this returns COUNTS ONLY, and the answer is the same size for a store
|
|
890
1044
|
* of a hundred memories and a store of a hundred million. That is deliberate: a model
|
|
@@ -910,10 +1064,8 @@ export declare class Client {
|
|
|
910
1064
|
* Pages are ordered by when each memory was STORED, not by when it was edited.
|
|
911
1065
|
* The response says so in `ordered_by`.
|
|
912
1066
|
*
|
|
913
|
-
* Served from `/api/v1/won
|
|
914
|
-
*
|
|
915
|
-
* the address says so. The old path still answers, for clients published before
|
|
916
|
-
* 2026-08-18, and both share one rate-limit budget.
|
|
1067
|
+
* Served from `/api/v1/won/revisions`: `/api/v1/won/*` holds the calls a model makes
|
|
1068
|
+
* ABOUT its memory rather than calls an application makes WITH it.
|
|
917
1069
|
*/
|
|
918
1070
|
revisions(userId?: string, opts?: {
|
|
919
1071
|
/**
|
|
@@ -921,7 +1073,8 @@ export declare class Client {
|
|
|
921
1073
|
* number. One side per call — there is no way to ask for both lists at once.
|
|
922
1074
|
*/
|
|
923
1075
|
include?: "revised" | "unrevised";
|
|
924
|
-
/** Memories per page
|
|
1076
|
+
/** Memories per page, 5-20; 20 is the default. Anything else is refused before
|
|
1077
|
+
* the request. */
|
|
925
1078
|
limit?: number;
|
|
926
1079
|
/** Cursor: `next_before` from the previous page. */
|
|
927
1080
|
before?: string;
|
|
@@ -941,11 +1094,10 @@ export declare class Client {
|
|
|
941
1094
|
*
|
|
942
1095
|
* `speaker` is the tag written at store time (`metadata.speaker`) — `"me"` for the
|
|
943
1096
|
* assistant's own words, otherwise a person's name. Same cursor paging as
|
|
944
|
-
* `listImages
|
|
1097
|
+
* `listImages`; `limit` is 5-20.
|
|
945
1098
|
*
|
|
946
|
-
* `
|
|
947
|
-
*
|
|
948
|
-
* about to confirm one.
|
|
1099
|
+
* `points_to_delete` is the count to show before anyone confirms a delete of this
|
|
1100
|
+
* speaker's memories.
|
|
949
1101
|
*/
|
|
950
1102
|
bySpeaker(speaker: string, userId?: string, opts?: {
|
|
951
1103
|
limit?: number;
|
|
@@ -963,9 +1115,9 @@ export declare class Client {
|
|
|
963
1115
|
*
|
|
964
1116
|
* Ask rather than hard-code: a name copied from the docs freezes a caller to the
|
|
965
1117
|
* catalogue as it was that day, and anything added later stays invisible. The
|
|
966
|
-
* service is the authority. What
|
|
967
|
-
*
|
|
968
|
-
*
|
|
1118
|
+
* service is the authority. What comes back depends on the model (`forms` is empty
|
|
1119
|
+
* on one that does not list `forms` in its capabilities), so pass `withModel()` if
|
|
1120
|
+
* you want another model's catalogue.
|
|
969
1121
|
*
|
|
970
1122
|
* const { engrams, forms } = await mem.listEngrams();
|
|
971
1123
|
*/
|
|
@@ -975,9 +1127,13 @@ export declare class Client {
|
|
|
975
1127
|
* return 404. Idempotent. Every account starts with a `default` store.
|
|
976
1128
|
* Returns `{ user_id, status }` (`status` is `"created"` or `"exists"`). */
|
|
977
1129
|
createStore(userId?: string): Promise<StoreOpResult>;
|
|
978
|
-
/** List your stores: `[{ user_id, created_at }, ...]` (`default`
|
|
1130
|
+
/** List your stores: `[{ user_id, created_at, canonical_id? }, ...]` (`default`
|
|
1131
|
+
* first). Each `user_id` is the id the store was created with. */
|
|
979
1132
|
listStores(): Promise<StoreInfo[]>;
|
|
980
|
-
/** Delete a store and ALL its memories. Returns `{ user_id, status }`.
|
|
1133
|
+
/** Delete a store and ALL its memories. Returns `{ user_id, status }`.
|
|
1134
|
+
* A delete retried after an ambiguous failure (408/502/503/504 or a dropped
|
|
1135
|
+
* connection) that then answers 404 rejects with a `NotFoundError` saying an
|
|
1136
|
+
* earlier attempt may already have deleted it. */
|
|
981
1137
|
deleteStore(userId: string): Promise<StoreOpResult>;
|
|
982
1138
|
/** Register a person for this store. Speakers are explicit: register once, then
|
|
983
1139
|
* store with `{ speaker }`. `"me"` (the assistant itself) never needs
|
|
@@ -985,67 +1141,82 @@ export declare class Client {
|
|
|
985
1141
|
addSpeaker(speaker: string, userId?: string): Promise<SpeakerOpResult>;
|
|
986
1142
|
/** The store's registered people, each with its memory count. */
|
|
987
1143
|
listSpeakers(userId?: string): Promise<SpeakersList>;
|
|
988
|
-
/** Unregister a person. Their memories stay; the name tag goes.
|
|
1144
|
+
/** Unregister a person. Their memories stay; the name tag goes. Retried like
|
|
1145
|
+
* `deleteStore`, with the same note on a 404 after an ambiguous failure. */
|
|
989
1146
|
removeSpeaker(speaker: string, userId?: string): Promise<SpeakerOpResult>;
|
|
990
1147
|
/** Delete a single memory by id. Pass `undefined` as `userId` for the default
|
|
991
|
-
* store — it is positional here
|
|
1148
|
+
* store — it is positional here. */
|
|
992
1149
|
delete(userId: string | undefined, memoryId: string): Promise<StatusResult>;
|
|
993
1150
|
/** Delete ALL memories for a store (GDPR erase). `userId` is required on purpose -
|
|
994
1151
|
* this is destructive, so it never falls back to the default store. */
|
|
995
1152
|
deleteAll(userId: string): Promise<StatusResult>;
|
|
996
1153
|
private post;
|
|
997
|
-
/**
|
|
998
|
-
*
|
|
999
|
-
|
|
1000
|
-
* Only `/memory/image` does this, and it is why this cannot go through `request()`:
|
|
1001
|
-
* that path reads the body as text and insists the result parses to a JSON object.
|
|
1002
|
-
* Feeding it a JPEG would throw "invalid JSON in response" — a confusing error for a
|
|
1003
|
-
* call that actually succeeded.
|
|
1004
|
-
*
|
|
1005
|
-
* Errors still arrive as JSON, so those are handed back to the normal machinery: on
|
|
1006
|
-
* a non-2xx we re-read the body as text and reuse `errorFor`, which keeps 404
|
|
1007
|
-
* (`NotFoundError`) and 401 behaving the same as everywhere else.
|
|
1008
|
-
*/
|
|
1154
|
+
/** A DELETE that removes something: a 404 after an ambiguous failure says an earlier
|
|
1155
|
+
* attempt may already have removed it. */
|
|
1156
|
+
private remove;
|
|
1009
1157
|
/** Where this call's budget runs out, or `undefined` when it has none. Computed
|
|
1010
1158
|
* once per call, not per attempt — a budget recomputed each attempt is not a
|
|
1011
1159
|
* budget. */
|
|
1012
1160
|
private deadlineAt;
|
|
1013
1161
|
/** The abort wiring for ONE attempt: this SDK's per-attempt timeout, the caller's
|
|
1014
1162
|
* signal, and whatever is left of the overall deadline — whichever fires first.
|
|
1015
|
-
*
|
|
1016
|
-
*
|
|
1017
|
-
* in one of two request paths is exactly how `getImage` ended up with no retry loop
|
|
1018
|
-
* while the module doc promised every call had one. */
|
|
1163
|
+
* With no time left it throws `answer` (the refusal that led here), or the
|
|
1164
|
+
* deadline error when there is none. */
|
|
1019
1165
|
private beginAttempt;
|
|
1020
1166
|
/** What to say when an attempt was cut short. The three reasons need different
|
|
1021
1167
|
* words: a timeout may have landed server-side, a cancellation certainly did not
|
|
1022
1168
|
* matter to the caller, and an exhausted budget is the caller's own setting. */
|
|
1023
1169
|
private abortMessage;
|
|
1024
|
-
/**
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1170
|
+
/** Whether a wait of `ms` still leaves time before the deadline. */
|
|
1171
|
+
private fits;
|
|
1172
|
+
/** Sleep between attempts, waking the moment the caller aborts. */
|
|
1173
|
+
private pause;
|
|
1174
|
+
/** The error for a request that got no answer. The message names the cause code
|
|
1175
|
+
* (ECONNREFUSED, ENOTFOUND, CERT_HAS_EXPIRED, …) and never carries the query
|
|
1176
|
+
* string, which can hold a store id, or the base URL's userinfo. With either in
|
|
1177
|
+
* the URL the transport error is not kept as the cause, since its own message can
|
|
1178
|
+
* quote the URL. */
|
|
1179
|
+
private networkError;
|
|
1180
|
+
/** A redirect: a 3xx, or one a custom fetch followed. Where a custom fetch sent the
|
|
1181
|
+
* request (`res.url`) is its own business. */
|
|
1182
|
+
private isRedirected;
|
|
1183
|
+
/** The error an answer carries: the service's message (control characters removed,
|
|
1184
|
+
* capped), request id, `type` and the rest of its error object. `unread` says why
|
|
1185
|
+
* the body is missing, when it could not be read. */
|
|
1186
|
+
private errorFromAnswer;
|
|
1187
|
+
/**
|
|
1188
|
+
* Send one call, retrying what can be retried, and return the answer with its body
|
|
1189
|
+
* read (under the same timeout, so a body that trickles in cannot stall the call).
|
|
1190
|
+
* The error body of an answer about to be retried gets at most a second.
|
|
1191
|
+
*
|
|
1192
|
+
* Retried: 429, and a 409 whose error carries `retry_after_ms` (another write to the
|
|
1193
|
+
* store was in flight; nothing was stored), on every method; 408/502/503/504 and
|
|
1194
|
+
* dropped connections on idempotent methods; connect failures on every method. A
|
|
1195
|
+
* retry whose wait is over the cap, or does not fit the deadline, is not made: the
|
|
1196
|
+
* call fails with the error of the response it has. So does a retry the deadline
|
|
1197
|
+
* leaves no time to send, and the retry of an idempotent method or `getImage` that
|
|
1198
|
+
* the deadline cuts short. Any other retry cut short stays a status-0 deadline error:
|
|
1199
|
+
* a write may have been applied.
|
|
1200
|
+
*/
|
|
1201
|
+
private send;
|
|
1202
|
+
/**
|
|
1203
|
+
* One request that answers with BYTES rather than JSON.
|
|
1028
1204
|
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1031
|
-
*
|
|
1032
|
-
|
|
1033
|
-
private backoffSleep;
|
|
1205
|
+
* Only `/memory/image` does this: `request()` insists the body parses to a JSON
|
|
1206
|
+
* object, and a JPEG would come back as "invalid JSON in response" for a call that
|
|
1207
|
+
* succeeded. Retries, timeouts and errors are the same as every other call's.
|
|
1208
|
+
*/
|
|
1034
1209
|
private requestBytes;
|
|
1035
1210
|
/** Validate an idempotency key BEFORE the network. The API answers a malformed
|
|
1036
1211
|
* key with a 400, which on a retry path reads as "my write failed" when in fact
|
|
1037
1212
|
* it was never attempted — cheaper and clearer to reject it here. */
|
|
1038
1213
|
private idemHeader;
|
|
1039
|
-
/**
|
|
1214
|
+
/** Milliseconds to sleep before retry `attempt` (0-based): exponential with jitter,
|
|
1215
|
+
* or what a valid `Retry-After` asks for. */
|
|
1040
1216
|
private backoffMs;
|
|
1041
1217
|
/** Read the body with a hard size cap, so a broken/hostile endpoint can't
|
|
1042
|
-
* make the process buffer gigabytes.
|
|
1043
|
-
|
|
1044
|
-
/** The same cap, for a body that is not text.
|
|
1045
|
-
*
|
|
1046
|
-
* `arrayBuffer()` would buffer whatever arrives. The cap exists for a hostile or
|
|
1047
|
-
* broken `baseUrl`, and an endpoint that returns megabytes is where that costs the
|
|
1048
|
-
* most. One implementation, two callers, so they cannot drift. */
|
|
1218
|
+
* make the process buffer gigabytes. With `withinMs`, a body still arriving after
|
|
1219
|
+
* that long is dropped and the read fails. */
|
|
1049
1220
|
private readCappedBytes;
|
|
1050
1221
|
private request;
|
|
1051
1222
|
}
|