wontopos 2.2.45 → 2.2.46
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 +21 -16
- package/dist/cjs/wontopos.d.cts +64 -52
- package/dist/cjs/wontopos.js +3 -3
- package/dist/wontopos.d.ts +64 -52
- package/dist/wontopos.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,8 +24,8 @@ const ctx = await mem.recall("what does alice drink?", "alice");
|
|
|
24
24
|
## Why
|
|
25
25
|
|
|
26
26
|
- **The same in every language** — identical recall whichever language a memory was written in (Korean · Japanese · Chinese · English).
|
|
27
|
-
- **No LLM
|
|
28
|
-
- **Bounded retrieval** — `recall()` returns
|
|
27
|
+
- **No LLM reads your memories** — no language model reads your stored memories, on any model. You pay retrieval, not generation.
|
|
28
|
+
- **Bounded retrieval** — `recall()` returns the recent turns, at most `limit` long-term memories (default 10, up to 20) and at most `context_limit` rows of the surrounding conversation (default 10, up to 20), however much you've stored.
|
|
29
29
|
|
|
30
30
|
## Methods
|
|
31
31
|
|
|
@@ -38,7 +38,7 @@ writes or searches puts the payload first and the store second — `mem.add("...
|
|
|
38
38
|
Most of them let you leave it out for the client's default store. Five take it
|
|
39
39
|
positionally and cannot — `get`, `getImage`, `delete`, `lineage` and `forgetImage` want
|
|
40
40
|
an explicit `undefined` there, because a second required argument follows it. Python
|
|
41
|
-
omits it in all five
|
|
41
|
+
omits it in all five, and Rust takes it positionally (`None` for the default store, where there is one).
|
|
42
42
|
Let your editor confirm the order: every signature is typed. A store is one isolated memory space per end-user, agent, or topic. WHO said each memory inside a store is the `speaker` tag below — storing the assistant's own words never needs a separate id.
|
|
43
43
|
|
|
44
44
|
## Who said it (speakers)
|
|
@@ -56,19 +56,22 @@ await mem.search("what did Bob say about deadlines?", "alice", 10, { speaker: "B
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
`listSpeakers()` shows the registered people with per-person memory counts;
|
|
59
|
-
`removeSpeaker()` unregisters (memories stay
|
|
59
|
+
`removeSpeaker()` unregisters (memories stay; the tag goes, except on `tablet-2`, which keeps it on memories already stored). A store registers
|
|
60
60
|
up to 50 people to start (a limit we plan to raise); `"me"` never needs
|
|
61
61
|
registration and never counts against it.
|
|
62
62
|
|
|
63
63
|
## Recall caching
|
|
64
64
|
|
|
65
|
-
Opt in per search and repeated
|
|
66
|
-
|
|
65
|
+
Opt in per search and a repeated query reuses the previous result at 10% of the
|
|
66
|
+
normal rate; an extended one reuses part of it (Tablet and Scroll models).
|
|
67
67
|
|
|
68
68
|
It is not free to turn on: the FIRST call writes the cache and bills the query
|
|
69
|
-
tokens at 2x for a `5m` TTL, 3x for `1h`.
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
tokens at 2x for a `5m` TTL, 3x for `1h`. The same query again inside the TTL bills
|
|
70
|
+
its query and its results at 0.1x. A query that extends the cached one (its text plus
|
|
71
|
+
more) bills the cached part at 0.1x, the new part at the write rate and its results
|
|
72
|
+
at the normal rate. A store keeps one cached query per model and set of options, so a
|
|
73
|
+
different query replaces it. So it pays for a query you repeat or extend, and costs
|
|
74
|
+
more for one you issue once — do not switch it on globally. Any write to the store invalidates its cache
|
|
72
75
|
at once, so a hit can never predate a new memory.
|
|
73
76
|
|
|
74
77
|
```ts
|
|
@@ -82,11 +85,11 @@ Built in, no configuration needed:
|
|
|
82
85
|
|
|
83
86
|
- **Automatic retries** — 429 and a 409 for a write already in flight always, and 408 /
|
|
84
87
|
502 / 503 / 504 or a connection error only when a retry cannot double-process a write.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
|
|
88
|
+
A write may already have landed when any of those four comes back, so a POST write gets
|
|
89
|
+
429, that 409 and connect-level failures only. The calls that are safe to send again
|
|
90
|
+
retry all four: the reads sent as POST (`search`, `recall`, `get`, `listMemories`,
|
|
91
|
+
`stats`, ...) and the GET and DELETE calls (`ping`, `listStores`, `listSpeakers`,
|
|
92
|
+
`listModels`, `listEngrams`, `usage`, `deleteStore`, `removeSpeaker`, `forgetImage`). Twice, with exponential backoff + jitter, honoring the server's
|
|
90
93
|
`Retry-After` up to 30s. Tune with `new Client({ maxRetries })`; `0` disables.
|
|
91
94
|
- **Redirects refused** — the API key never follows a 3xx to another host.
|
|
92
95
|
- **Timeouts** — 30s per attempt by default (`timeoutMs`), and a total budget for
|
|
@@ -147,7 +150,8 @@ Built in, none of it configurable off:
|
|
|
147
150
|
Every method returns a documented shape — `StoreResult`, `UpdateResult`,
|
|
148
151
|
`RecallResult`, `EngramResult`, `StatsResult`, `SpeakersList`, `Memory[]`, ... —
|
|
149
152
|
each with an index signature, so new server fields flow through without an SDK
|
|
150
|
-
update. `
|
|
153
|
+
update. `searchSelf`'s result and `getImage`'s bytes are built by the client and
|
|
154
|
+
carry only their own fields. `search` options are typed too (`SearchOptions`: `cache_control`,
|
|
151
155
|
`speaker`, plus `extra` for pass-through).
|
|
152
156
|
|
|
153
157
|
```ts
|
|
@@ -157,7 +161,8 @@ const hits: Memory[] = await mem.search("what did Bob say?", "alice", 10, { spea
|
|
|
157
161
|
console.log(hits[0].speaker, hits[0].time_bucket); // typed: string | undefined
|
|
158
162
|
```
|
|
159
163
|
|
|
160
|
-
`hits`
|
|
164
|
+
`hits` holds memories best-first, then the assistant's own words and image memories in
|
|
165
|
+
their own order. Take it in the order given. `similarity` is a raw
|
|
161
166
|
closeness score, not the ranking key: what produces the order is internal and is
|
|
162
167
|
not returned, so sorting by `similarity` overrides the ranking and makes results
|
|
163
168
|
worse. There is no `score` field.
|
package/dist/cjs/wontopos.d.cts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* (`createStore`) or calls return 404. Every account starts with a `default` store,
|
|
15
15
|
* so with no `userId` anywhere the zero-setup path just works.
|
|
16
16
|
*
|
|
17
|
-
* The API key picks *which memory* (your
|
|
17
|
+
* The API key picks *which memory* (your workspace); `model` picks *which engine*
|
|
18
18
|
* reads it. Models on the shared pool read the same memory, so you can store with
|
|
19
19
|
* one and recall with another; `listModels()` reports each model's `memory` as
|
|
20
20
|
* `"shared"` or `"isolated"`, and an isolated one starts empty. Set a default in
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
* `mem.withModel("tablet-1").recall(...)`.
|
|
23
23
|
*
|
|
24
24
|
* Recall quality does not depend on which language a memory was written in: a
|
|
25
|
-
* memory stored in one language is found by a question asked in another.
|
|
26
|
-
*
|
|
25
|
+
* memory stored in one language is found by a question asked in another. No language
|
|
26
|
+
* model reads your stored memories.
|
|
27
27
|
*
|
|
28
28
|
* Reliability: every call retries transient failures with exponential backoff +
|
|
29
29
|
* jitter, honoring `Retry-After` up to 30s — 429 and a 409 that says another write
|
|
30
30
|
* to the store was in flight, always; 408/502/503/504 and connection errors only when
|
|
31
|
-
* a retry can never double-process a write (
|
|
32
|
-
* time). Tune with `maxRetries` (0 disables) and `timeoutMs`, or per call site via
|
|
31
|
+
* a retry can never double-process a write (reads, the DELETE calls, or a failure at
|
|
32
|
+
* connect time). Tune with `maxRetries` (0 disables) and `timeoutMs`, or per call site via
|
|
33
33
|
* the `withTimeout()` / `withRetries()` clones.
|
|
34
34
|
*
|
|
35
35
|
* Debugging: set `WONTOPOS_LOG=debug` to log method/path/status/timing/retries
|
|
@@ -89,7 +89,9 @@ export declare class BadRequestError extends WosError {
|
|
|
89
89
|
/** 401 — the API key is missing, wrong, or revoked. */
|
|
90
90
|
export declare class AuthenticationError extends WosError {
|
|
91
91
|
}
|
|
92
|
-
/** 402 — no card on file
|
|
92
|
+
/** 402 — no card on file, the balance is depleted, or the month's spend cap for the
|
|
93
|
+
* account's tier is reached (`details.reason` is `tier_cap_reached`). Top up to
|
|
94
|
+
* continue; a top-up also raises the tier. */
|
|
93
95
|
export declare class PaymentRequiredError extends WosError {
|
|
94
96
|
}
|
|
95
97
|
/** 403 — the key/model isn't allowed to do this. */
|
|
@@ -194,8 +196,9 @@ export interface StatusResult {
|
|
|
194
196
|
/**
|
|
195
197
|
* An image attached to a memory, passed to `add`/`store` via `opts.image`.
|
|
196
198
|
*
|
|
197
|
-
* Both edges must be 700px or more
|
|
198
|
-
*
|
|
199
|
+
* Both edges must be 700px or more and the long edge at most 2500px, and the image
|
|
200
|
+
* file at most 7MB; anything else is refused (400) with the reason. A request body is
|
|
201
|
+
* capped at 10MB.
|
|
199
202
|
*
|
|
200
203
|
* What the service keeps is NOT your original. An image whose long edge is over
|
|
201
204
|
* 1568px is downscaled to 1568 before anything else happens, and that smaller
|
|
@@ -241,8 +244,9 @@ export interface ImageBytes {
|
|
|
241
244
|
* The image as stored. Write it to a file, or wrap it in a Blob to show it.
|
|
242
245
|
*
|
|
243
246
|
* This is the service's copy, not necessarily your upload: anything over 1568px
|
|
244
|
-
* on its long edge was downscaled on the way in, and re-encoded to
|
|
245
|
-
* was a JPEG (see `ImageInput`). Take the file extension from
|
|
247
|
+
* on its long edge (2500 at most) was downscaled on the way in, and re-encoded to
|
|
248
|
+
* WebP unless it was a JPEG (see `ImageInput`). Take the file extension from
|
|
249
|
+
* `contentType`.
|
|
246
250
|
*/
|
|
247
251
|
bytes: Uint8Array;
|
|
248
252
|
/** Sniffed from the BYTES, not from whatever the upload was named — e.g. `image/jpeg`. */
|
|
@@ -317,7 +321,8 @@ export interface LineageStep {
|
|
|
317
321
|
is_current?: boolean;
|
|
318
322
|
[key: string]: unknown;
|
|
319
323
|
}
|
|
320
|
-
/** `lineage` → the
|
|
324
|
+
/** `lineage` → the edits that followed one memory, from the id passed forward to the
|
|
325
|
+
* version in force, oldest first. */
|
|
321
326
|
export interface LineageResult {
|
|
322
327
|
memory_id?: string;
|
|
323
328
|
chain: LineageStep[];
|
|
@@ -360,8 +365,8 @@ export interface SearchResult {
|
|
|
360
365
|
/** Image memories the answer carried (one by default on an image-capable model,
|
|
361
366
|
* up to `max_images`); `[]` when there were none. */
|
|
362
367
|
images: Memory[];
|
|
363
|
-
/** Re-ask passes
|
|
364
|
-
* than you asked for means
|
|
368
|
+
/** Re-ask passes that added memories. Present only when `verify` above 0 was sent;
|
|
369
|
+
* lower than you asked for means a pass found nothing new, or could not run. */
|
|
365
370
|
verify_used?: number;
|
|
366
371
|
[key: string]: unknown;
|
|
367
372
|
}
|
|
@@ -414,7 +419,7 @@ export interface UsageResult {
|
|
|
414
419
|
output_tokens?: number;
|
|
415
420
|
since?: string;
|
|
416
421
|
};
|
|
417
|
-
/** The workspace this key belongs to, over the window. */
|
|
422
|
+
/** The workspace this key belongs to, over the window: every key in it, not only this one. */
|
|
418
423
|
workspace?: {
|
|
419
424
|
workspace_id?: string | null;
|
|
420
425
|
requests?: number;
|
|
@@ -542,9 +547,8 @@ export interface SpeakersList {
|
|
|
542
547
|
[key: string]: unknown;
|
|
543
548
|
}
|
|
544
549
|
/**
|
|
545
|
-
* Narrow a search to part of a store.
|
|
546
|
-
*
|
|
547
|
-
* many matches sit inside it.
|
|
550
|
+
* Narrow a search to part of a store. A narrow filter can return fewer than `limit`
|
|
551
|
+
* even when the store holds more inside it.
|
|
548
552
|
*
|
|
549
553
|
* Retrieval behaves the same in every language, so these behave
|
|
550
554
|
* identically in every language. Unlisted keys are dropped by the API rather than
|
|
@@ -565,7 +569,8 @@ export interface SearchFilters {
|
|
|
565
569
|
time_from?: string;
|
|
566
570
|
time_to?: string;
|
|
567
571
|
/** WHEN THE CONTENT HAPPENED (`metadata.event_date`), not when it was written —
|
|
568
|
-
* this is the one you usually want.
|
|
572
|
+
* this is the one you usually want. A memory stored without an `event_date` is
|
|
573
|
+
* matched by when it was stored. */
|
|
569
574
|
event_from?: string;
|
|
570
575
|
event_to?: string;
|
|
571
576
|
/** Drop matches the engine scored below this importance (0–1). */
|
|
@@ -578,9 +583,11 @@ export declare function _resetFilterWarnings(): void;
|
|
|
578
583
|
* could not be told from an option that worked. Put a genuinely new one under
|
|
579
584
|
* `extra`. */
|
|
580
585
|
export interface SearchOptions {
|
|
581
|
-
/** Recall caching.
|
|
582
|
-
*
|
|
583
|
-
*
|
|
586
|
+
/** Recall caching. The same query again inside the TTL bills at 0.1×; one that
|
|
587
|
+
* extends the cached query bills only its cached part at 0.1×, the new part at the
|
|
588
|
+
* write rate and its results at the normal rate. The FIRST call writes the cache
|
|
589
|
+
* and bills the query tokens at 2× (`5m`) or 3× (`1h`), so this only pays for a
|
|
590
|
+
* query you repeat or extend. Do not enable it globally. */
|
|
584
591
|
cache_control?: {
|
|
585
592
|
ttl: "5m" | "1h";
|
|
586
593
|
};
|
|
@@ -591,9 +598,9 @@ export interface SearchOptions {
|
|
|
591
598
|
/**
|
|
592
599
|
* Re-ask passes, 0–3. After the first retrieval the service asks the engine again up
|
|
593
600
|
* to this many times, each time telling it what was already returned so it skips
|
|
594
|
-
* those and reaches further back.
|
|
601
|
+
* those and reaches further back. Raising it adds no language model call at any
|
|
595
602
|
* value. Stops early when a pass finds nothing new; `verify_used` in the response
|
|
596
|
-
* says how many
|
|
603
|
+
* says how many passes added memories.
|
|
597
604
|
*
|
|
598
605
|
* Each pass is another engine call and can add up to `limit` more memories, so it
|
|
599
606
|
* costs more — you are billed for what is delivered. Default 0. Worth it on questions
|
|
@@ -859,15 +866,16 @@ export declare class Client {
|
|
|
859
866
|
addBulk(content: string, userId?: string, category?: string, timestamp?: string, opts?: WriteOptions): Promise<StatusResult>;
|
|
860
867
|
/** Supersede an old memory with new content. Payload first, userId last — same shape as add/search. */
|
|
861
868
|
update(oldMemoryId: string, newContent: string, userId?: string, opts?: WriteOptions): Promise<UpdateResult>;
|
|
862
|
-
/** Search a store's memories.
|
|
869
|
+
/** Search a store's memories. They come most relevant first; the assistant's own
|
|
870
|
+
* words and image memories, when there are any, follow them in their own order.
|
|
863
871
|
*
|
|
864
872
|
* `limit` is 5-20, and out of range is refused rather than clamped: asking for 50
|
|
865
873
|
* and silently receiving 20 reads as "that is all there is". The default is 10.
|
|
866
874
|
*
|
|
867
|
-
* `limit` bounds `memories`, not the returned array
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
* it as well, so it can hold more than `limit`. They are billed either way. Size a
|
|
875
|
+
* `limit` bounds `memories`, not the returned array, and each `verify` pass can add
|
|
876
|
+
* up to `limit` more. The assistant's own words (on a model that lists
|
|
877
|
+
* `self_memories` in its capabilities) and image memories (one unless `max_images`
|
|
878
|
+
* says otherwise, on a model that lists `images`) come back after them in it as well, so it can hold more than `limit`. They are billed either way. Size a
|
|
871
879
|
* prompt window on the array you get back, not on `limit`. `searchFull()` hands the
|
|
872
880
|
* fields back apart.
|
|
873
881
|
*
|
|
@@ -891,7 +899,7 @@ export declare class Client {
|
|
|
891
899
|
* const r = await mem.searchFull("the day we moved", "alice", 10,
|
|
892
900
|
* { max_images: 3, verify: 2 });
|
|
893
901
|
* r.images.length; // the photos, apart from the text memories
|
|
894
|
-
* r.verify_used; //
|
|
902
|
+
* r.verify_used; // re-ask passes that added memories (each billed for what it added)
|
|
895
903
|
*
|
|
896
904
|
* Each option needs a model that lists it in its `listModels()` capabilities
|
|
897
905
|
* (`images`, `re_ask`) and is refused (403) on any other rather than accepted and
|
|
@@ -928,7 +936,8 @@ export declare class Client {
|
|
|
928
936
|
}): Promise<EngramResult>;
|
|
929
937
|
/** Recent conversation turns (short-term memory). */
|
|
930
938
|
history(userId?: string): Promise<HistoryTurn[]>;
|
|
931
|
-
/** Memory counts for a store: { total_memories, short_term_turns }.
|
|
939
|
+
/** Memory counts for a store: { total_memories, short_term_turns }. `total_memories`
|
|
940
|
+
* can be larger than the number `listMemories` lists. */
|
|
932
941
|
stats(userId?: string): Promise<StatsResult>;
|
|
933
942
|
/**
|
|
934
943
|
* What this key has spent, and what is left — the numbers behind "can I keep going?".
|
|
@@ -936,18 +945,17 @@ export declare class Client {
|
|
|
936
945
|
* Free: it carries no charge and skips the balance gate, because an account at zero
|
|
937
946
|
* still has to be able to find out why. Rate-limited instead.
|
|
938
947
|
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
* because that is what gates the next call whichever key makes it.
|
|
948
|
+
* `key` is THIS key's own lifetime spend. `workspace` and `stores` cover the window
|
|
949
|
+
* for the workspace this key belongs to, every key in it included. `balance_cents` is
|
|
950
|
+
* account-wide, because that is what gates the next call whichever key makes it.
|
|
942
951
|
*
|
|
943
952
|
* const u = await mem.usage(7);
|
|
944
953
|
* if (u.balance_cents! < 100) stop();
|
|
945
954
|
*/
|
|
946
955
|
usage(days?: number): Promise<UsageResult>;
|
|
947
956
|
/** Fetch ONE memory by id — the text you stored, and its metadata.
|
|
948
|
-
* The id is what `add`/`store` or `listMemories` returned.
|
|
949
|
-
*
|
|
950
|
-
* or an invalidated memory rejects with `NotFoundError`. Pass `undefined` as
|
|
957
|
+
* The id is what `add`/`store` or `listMemories` returned. An unknown id or one
|
|
958
|
+
* from another store rejects with `NotFoundError`. Pass `undefined` as
|
|
951
959
|
* `userId` for the default store — it is positional here. */
|
|
952
960
|
get(userId: string | undefined, memoryId: string): Promise<Memory>;
|
|
953
961
|
/** List a store's stored memories — the text you stored, plus its metadata.
|
|
@@ -993,9 +1001,10 @@ export declare class Client {
|
|
|
993
1001
|
* Fetch the bytes of an image memory — the picture the SERVICE holds.
|
|
994
1002
|
*
|
|
995
1003
|
* Not necessarily your upload, in size OR in format: an image whose long edge was
|
|
996
|
-
* over 1568px was downscaled to 1568 on the way in and re-encoded —
|
|
997
|
-
* formats as WebP, so a PNG comes back as `image/webp`; JPEG stays JPEG
|
|
998
|
-
*
|
|
1004
|
+
* over 1568px (2500 at most) was downscaled to 1568 on the way in and re-encoded —
|
|
1005
|
+
* lossless formats as WebP, so a PNG comes back as `image/webp`; JPEG stays JPEG;
|
|
1006
|
+
* kept as sent when the re-encode came out bigger — and that smaller picture is what
|
|
1007
|
+
* is stored and comes back here. Nothing on our side ever
|
|
999
1008
|
* uses more than 1568, so the extra pixels would be bytes nobody reads.
|
|
1000
1009
|
* Keep your own copy for the full-resolution file.
|
|
1001
1010
|
*
|
|
@@ -1100,11 +1109,13 @@ export declare class Client {
|
|
|
1100
1109
|
skipIds?: string[];
|
|
1101
1110
|
}): Promise<RevisionsResult>;
|
|
1102
1111
|
/**
|
|
1103
|
-
* The
|
|
1112
|
+
* The edits that followed one memory: from the id you pass forward to the version in
|
|
1113
|
+
* force, oldest first.
|
|
1104
1114
|
*
|
|
1105
|
-
* `is_current` marks the version in force.
|
|
1106
|
-
* say, and when did it change"
|
|
1107
|
-
*
|
|
1115
|
+
* `is_current` marks the version in force. The chain runs forward only, so to answer
|
|
1116
|
+
* "what did this used to say, and when did it change" pass the first version's id;
|
|
1117
|
+
* the current version's id (what `search` returns) comes back alone. `revisions()`
|
|
1118
|
+
* tells you HOW MUCH a store moved, this tells you what happened to one fact.
|
|
1108
1119
|
*/
|
|
1109
1120
|
lineage(userId: string | undefined, memoryId: string): Promise<LineageResult>;
|
|
1110
1121
|
/**
|
|
@@ -1126,8 +1137,7 @@ export declare class Client {
|
|
|
1126
1137
|
* `AuthenticationError` (bad key), `PaymentRequiredError` (valid key but no card /
|
|
1127
1138
|
* depleted balance), or `APIConnectionError` (unreachable). Makes one metered request. */
|
|
1128
1139
|
ping(): Promise<boolean>;
|
|
1129
|
-
/** Available models: `[{ id, name, available, memory, capabilities, retires_at? }, ...]`.
|
|
1130
|
-
* Needs no API key. */
|
|
1140
|
+
/** Available models: `[{ id, name, available, memory, capabilities, retires_at? }, ...]`. */
|
|
1131
1141
|
listModels(): Promise<ModelInfo[]>;
|
|
1132
1142
|
/**
|
|
1133
1143
|
* The engrams (and delivery forms) the selected model can actually run.
|
|
@@ -1160,7 +1170,9 @@ export declare class Client {
|
|
|
1160
1170
|
addSpeaker(speaker: string, userId?: string): Promise<SpeakerOpResult>;
|
|
1161
1171
|
/** The store's registered people, each with its memory count. */
|
|
1162
1172
|
listSpeakers(userId?: string): Promise<SpeakersList>;
|
|
1163
|
-
/** Unregister a person. Their memories stay
|
|
1173
|
+
/** Unregister a person. Their memories stay, and the name can no longer tag a new
|
|
1174
|
+
* memory or filter a search. The tag goes from stored memories too, except on
|
|
1175
|
+
* `tablet-2`, which keeps it on memories already stored with it. Retried like
|
|
1164
1176
|
* `deleteStore`, with the same note on a 404 after an ambiguous failure. */
|
|
1165
1177
|
removeSpeaker(speaker: string, userId?: string): Promise<SpeakerOpResult>;
|
|
1166
1178
|
/** Delete a single memory by id. Pass `undefined` as `userId` for the default
|
|
@@ -1210,12 +1222,12 @@ export declare class Client {
|
|
|
1210
1222
|
*
|
|
1211
1223
|
* Retried: 429, and a 409 whose error carries `retry_after_ms` (another write to the
|
|
1212
1224
|
* store was in flight; nothing was stored), on every method; 408/502/503/504 and
|
|
1213
|
-
* dropped connections on
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1216
|
-
*
|
|
1217
|
-
* only reads that the deadline cuts short. Any other retry cut
|
|
1218
|
-
* deadline error: a write may have been applied.
|
|
1225
|
+
* dropped connections on a call that only reads (an idempotent method, or a POST
|
|
1226
|
+
* that only reads); connect failures on every method. A retry whose wait is over the
|
|
1227
|
+
* cap, or does not fit the deadline, is not made: the call fails with the error of
|
|
1228
|
+
* the response it has. So does a retry the deadline leaves no time to send, and the
|
|
1229
|
+
* retry of a call that only reads that the deadline cuts short. Any other retry cut
|
|
1230
|
+
* short stays a status-0 deadline error: a write may have been applied.
|
|
1219
1231
|
*/
|
|
1220
1232
|
private send;
|
|
1221
1233
|
/**
|
package/dist/cjs/wontopos.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WME = exports.Client = exports.ServerError = exports.RateLimitError = exports.GoneError = exports.ConflictError = exports.NotFoundError = exports.PermissionDeniedError = exports.PaymentRequiredError = exports.AuthenticationError = exports.BadRequestError = exports.APIConnectionError = exports.WosError = exports.CONTEXT_LIMIT_MAX = exports.CONTEXT_LIMIT_MIN = exports.SEARCH_LIMIT_MAX = exports.SEARCH_LIMIT_MIN = void 0;
|
|
4
4
|
exports._resetStoreIdWarnings = _resetStoreIdWarnings;
|
|
5
5
|
exports._resetFilterWarnings = _resetFilterWarnings;
|
|
6
|
-
const VERSION = "2.2.
|
|
6
|
+
const VERSION = "2.2.46";
|
|
7
7
|
const RUNTIME = (() => {
|
|
8
8
|
const p = globalThis?.process;
|
|
9
9
|
return p?.version ? ` (node/${p.version}; ${p.platform}-${p.arch})` : "";
|
|
@@ -1113,8 +1113,8 @@ class Client {
|
|
|
1113
1113
|
}
|
|
1114
1114
|
const attempts = this.maxRetries + 1;
|
|
1115
1115
|
const upper = method.toUpperCase();
|
|
1116
|
-
const idempotent = IDEMPOTENT_METHODS.has(upper);
|
|
1117
1116
|
const logPath = path.split("?")[0];
|
|
1117
|
+
const idempotent = IDEMPOTENT_METHODS.has(upper) || reads || (upper === "POST" && READ_POSTS.has(logPath));
|
|
1118
1118
|
const deadlineAt = this.deadlineAt();
|
|
1119
1119
|
const headers = extraHeaders ? { ...this.headers, ...extraHeaders } : this.headers;
|
|
1120
1120
|
let ambiguous = false;
|
|
@@ -1135,7 +1135,7 @@ class Client {
|
|
|
1135
1135
|
};
|
|
1136
1136
|
const cutShort = () => {
|
|
1137
1137
|
const why = att.why();
|
|
1138
|
-
if (why === "deadline" &&
|
|
1138
|
+
if (why === "deadline" && idempotent && previous) {
|
|
1139
1139
|
return previous;
|
|
1140
1140
|
}
|
|
1141
1141
|
return new APIConnectionError(0, this.abortMessage(why));
|
package/dist/wontopos.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* (`createStore`) or calls return 404. Every account starts with a `default` store,
|
|
15
15
|
* so with no `userId` anywhere the zero-setup path just works.
|
|
16
16
|
*
|
|
17
|
-
* The API key picks *which memory* (your
|
|
17
|
+
* The API key picks *which memory* (your workspace); `model` picks *which engine*
|
|
18
18
|
* reads it. Models on the shared pool read the same memory, so you can store with
|
|
19
19
|
* one and recall with another; `listModels()` reports each model's `memory` as
|
|
20
20
|
* `"shared"` or `"isolated"`, and an isolated one starts empty. Set a default in
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
* `mem.withModel("tablet-1").recall(...)`.
|
|
23
23
|
*
|
|
24
24
|
* Recall quality does not depend on which language a memory was written in: a
|
|
25
|
-
* memory stored in one language is found by a question asked in another.
|
|
26
|
-
*
|
|
25
|
+
* memory stored in one language is found by a question asked in another. No language
|
|
26
|
+
* model reads your stored memories.
|
|
27
27
|
*
|
|
28
28
|
* Reliability: every call retries transient failures with exponential backoff +
|
|
29
29
|
* jitter, honoring `Retry-After` up to 30s — 429 and a 409 that says another write
|
|
30
30
|
* to the store was in flight, always; 408/502/503/504 and connection errors only when
|
|
31
|
-
* a retry can never double-process a write (
|
|
32
|
-
* time). Tune with `maxRetries` (0 disables) and `timeoutMs`, or per call site via
|
|
31
|
+
* a retry can never double-process a write (reads, the DELETE calls, or a failure at
|
|
32
|
+
* connect time). Tune with `maxRetries` (0 disables) and `timeoutMs`, or per call site via
|
|
33
33
|
* the `withTimeout()` / `withRetries()` clones.
|
|
34
34
|
*
|
|
35
35
|
* Debugging: set `WONTOPOS_LOG=debug` to log method/path/status/timing/retries
|
|
@@ -89,7 +89,9 @@ export declare class BadRequestError extends WosError {
|
|
|
89
89
|
/** 401 — the API key is missing, wrong, or revoked. */
|
|
90
90
|
export declare class AuthenticationError extends WosError {
|
|
91
91
|
}
|
|
92
|
-
/** 402 — no card on file
|
|
92
|
+
/** 402 — no card on file, the balance is depleted, or the month's spend cap for the
|
|
93
|
+
* account's tier is reached (`details.reason` is `tier_cap_reached`). Top up to
|
|
94
|
+
* continue; a top-up also raises the tier. */
|
|
93
95
|
export declare class PaymentRequiredError extends WosError {
|
|
94
96
|
}
|
|
95
97
|
/** 403 — the key/model isn't allowed to do this. */
|
|
@@ -194,8 +196,9 @@ export interface StatusResult {
|
|
|
194
196
|
/**
|
|
195
197
|
* An image attached to a memory, passed to `add`/`store` via `opts.image`.
|
|
196
198
|
*
|
|
197
|
-
* Both edges must be 700px or more
|
|
198
|
-
*
|
|
199
|
+
* Both edges must be 700px or more and the long edge at most 2500px, and the image
|
|
200
|
+
* file at most 7MB; anything else is refused (400) with the reason. A request body is
|
|
201
|
+
* capped at 10MB.
|
|
199
202
|
*
|
|
200
203
|
* What the service keeps is NOT your original. An image whose long edge is over
|
|
201
204
|
* 1568px is downscaled to 1568 before anything else happens, and that smaller
|
|
@@ -241,8 +244,9 @@ export interface ImageBytes {
|
|
|
241
244
|
* The image as stored. Write it to a file, or wrap it in a Blob to show it.
|
|
242
245
|
*
|
|
243
246
|
* This is the service's copy, not necessarily your upload: anything over 1568px
|
|
244
|
-
* on its long edge was downscaled on the way in, and re-encoded to
|
|
245
|
-
* was a JPEG (see `ImageInput`). Take the file extension from
|
|
247
|
+
* on its long edge (2500 at most) was downscaled on the way in, and re-encoded to
|
|
248
|
+
* WebP unless it was a JPEG (see `ImageInput`). Take the file extension from
|
|
249
|
+
* `contentType`.
|
|
246
250
|
*/
|
|
247
251
|
bytes: Uint8Array;
|
|
248
252
|
/** Sniffed from the BYTES, not from whatever the upload was named — e.g. `image/jpeg`. */
|
|
@@ -317,7 +321,8 @@ export interface LineageStep {
|
|
|
317
321
|
is_current?: boolean;
|
|
318
322
|
[key: string]: unknown;
|
|
319
323
|
}
|
|
320
|
-
/** `lineage` → the
|
|
324
|
+
/** `lineage` → the edits that followed one memory, from the id passed forward to the
|
|
325
|
+
* version in force, oldest first. */
|
|
321
326
|
export interface LineageResult {
|
|
322
327
|
memory_id?: string;
|
|
323
328
|
chain: LineageStep[];
|
|
@@ -360,8 +365,8 @@ export interface SearchResult {
|
|
|
360
365
|
/** Image memories the answer carried (one by default on an image-capable model,
|
|
361
366
|
* up to `max_images`); `[]` when there were none. */
|
|
362
367
|
images: Memory[];
|
|
363
|
-
/** Re-ask passes
|
|
364
|
-
* than you asked for means
|
|
368
|
+
/** Re-ask passes that added memories. Present only when `verify` above 0 was sent;
|
|
369
|
+
* lower than you asked for means a pass found nothing new, or could not run. */
|
|
365
370
|
verify_used?: number;
|
|
366
371
|
[key: string]: unknown;
|
|
367
372
|
}
|
|
@@ -414,7 +419,7 @@ export interface UsageResult {
|
|
|
414
419
|
output_tokens?: number;
|
|
415
420
|
since?: string;
|
|
416
421
|
};
|
|
417
|
-
/** The workspace this key belongs to, over the window. */
|
|
422
|
+
/** The workspace this key belongs to, over the window: every key in it, not only this one. */
|
|
418
423
|
workspace?: {
|
|
419
424
|
workspace_id?: string | null;
|
|
420
425
|
requests?: number;
|
|
@@ -542,9 +547,8 @@ export interface SpeakersList {
|
|
|
542
547
|
[key: string]: unknown;
|
|
543
548
|
}
|
|
544
549
|
/**
|
|
545
|
-
* Narrow a search to part of a store.
|
|
546
|
-
*
|
|
547
|
-
* many matches sit inside it.
|
|
550
|
+
* Narrow a search to part of a store. A narrow filter can return fewer than `limit`
|
|
551
|
+
* even when the store holds more inside it.
|
|
548
552
|
*
|
|
549
553
|
* Retrieval behaves the same in every language, so these behave
|
|
550
554
|
* identically in every language. Unlisted keys are dropped by the API rather than
|
|
@@ -565,7 +569,8 @@ export interface SearchFilters {
|
|
|
565
569
|
time_from?: string;
|
|
566
570
|
time_to?: string;
|
|
567
571
|
/** WHEN THE CONTENT HAPPENED (`metadata.event_date`), not when it was written —
|
|
568
|
-
* this is the one you usually want.
|
|
572
|
+
* this is the one you usually want. A memory stored without an `event_date` is
|
|
573
|
+
* matched by when it was stored. */
|
|
569
574
|
event_from?: string;
|
|
570
575
|
event_to?: string;
|
|
571
576
|
/** Drop matches the engine scored below this importance (0–1). */
|
|
@@ -578,9 +583,11 @@ export declare function _resetFilterWarnings(): void;
|
|
|
578
583
|
* could not be told from an option that worked. Put a genuinely new one under
|
|
579
584
|
* `extra`. */
|
|
580
585
|
export interface SearchOptions {
|
|
581
|
-
/** Recall caching.
|
|
582
|
-
*
|
|
583
|
-
*
|
|
586
|
+
/** Recall caching. The same query again inside the TTL bills at 0.1×; one that
|
|
587
|
+
* extends the cached query bills only its cached part at 0.1×, the new part at the
|
|
588
|
+
* write rate and its results at the normal rate. The FIRST call writes the cache
|
|
589
|
+
* and bills the query tokens at 2× (`5m`) or 3× (`1h`), so this only pays for a
|
|
590
|
+
* query you repeat or extend. Do not enable it globally. */
|
|
584
591
|
cache_control?: {
|
|
585
592
|
ttl: "5m" | "1h";
|
|
586
593
|
};
|
|
@@ -591,9 +598,9 @@ export interface SearchOptions {
|
|
|
591
598
|
/**
|
|
592
599
|
* Re-ask passes, 0–3. After the first retrieval the service asks the engine again up
|
|
593
600
|
* to this many times, each time telling it what was already returned so it skips
|
|
594
|
-
* those and reaches further back.
|
|
601
|
+
* those and reaches further back. Raising it adds no language model call at any
|
|
595
602
|
* value. Stops early when a pass finds nothing new; `verify_used` in the response
|
|
596
|
-
* says how many
|
|
603
|
+
* says how many passes added memories.
|
|
597
604
|
*
|
|
598
605
|
* Each pass is another engine call and can add up to `limit` more memories, so it
|
|
599
606
|
* costs more — you are billed for what is delivered. Default 0. Worth it on questions
|
|
@@ -859,15 +866,16 @@ export declare class Client {
|
|
|
859
866
|
addBulk(content: string, userId?: string, category?: string, timestamp?: string, opts?: WriteOptions): Promise<StatusResult>;
|
|
860
867
|
/** Supersede an old memory with new content. Payload first, userId last — same shape as add/search. */
|
|
861
868
|
update(oldMemoryId: string, newContent: string, userId?: string, opts?: WriteOptions): Promise<UpdateResult>;
|
|
862
|
-
/** Search a store's memories.
|
|
869
|
+
/** Search a store's memories. They come most relevant first; the assistant's own
|
|
870
|
+
* words and image memories, when there are any, follow them in their own order.
|
|
863
871
|
*
|
|
864
872
|
* `limit` is 5-20, and out of range is refused rather than clamped: asking for 50
|
|
865
873
|
* and silently receiving 20 reads as "that is all there is". The default is 10.
|
|
866
874
|
*
|
|
867
|
-
* `limit` bounds `memories`, not the returned array
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
* it as well, so it can hold more than `limit`. They are billed either way. Size a
|
|
875
|
+
* `limit` bounds `memories`, not the returned array, and each `verify` pass can add
|
|
876
|
+
* up to `limit` more. The assistant's own words (on a model that lists
|
|
877
|
+
* `self_memories` in its capabilities) and image memories (one unless `max_images`
|
|
878
|
+
* says otherwise, on a model that lists `images`) come back after them in it as well, so it can hold more than `limit`. They are billed either way. Size a
|
|
871
879
|
* prompt window on the array you get back, not on `limit`. `searchFull()` hands the
|
|
872
880
|
* fields back apart.
|
|
873
881
|
*
|
|
@@ -891,7 +899,7 @@ export declare class Client {
|
|
|
891
899
|
* const r = await mem.searchFull("the day we moved", "alice", 10,
|
|
892
900
|
* { max_images: 3, verify: 2 });
|
|
893
901
|
* r.images.length; // the photos, apart from the text memories
|
|
894
|
-
* r.verify_used; //
|
|
902
|
+
* r.verify_used; // re-ask passes that added memories (each billed for what it added)
|
|
895
903
|
*
|
|
896
904
|
* Each option needs a model that lists it in its `listModels()` capabilities
|
|
897
905
|
* (`images`, `re_ask`) and is refused (403) on any other rather than accepted and
|
|
@@ -928,7 +936,8 @@ export declare class Client {
|
|
|
928
936
|
}): Promise<EngramResult>;
|
|
929
937
|
/** Recent conversation turns (short-term memory). */
|
|
930
938
|
history(userId?: string): Promise<HistoryTurn[]>;
|
|
931
|
-
/** Memory counts for a store: { total_memories, short_term_turns }.
|
|
939
|
+
/** Memory counts for a store: { total_memories, short_term_turns }. `total_memories`
|
|
940
|
+
* can be larger than the number `listMemories` lists. */
|
|
932
941
|
stats(userId?: string): Promise<StatsResult>;
|
|
933
942
|
/**
|
|
934
943
|
* What this key has spent, and what is left — the numbers behind "can I keep going?".
|
|
@@ -936,18 +945,17 @@ export declare class Client {
|
|
|
936
945
|
* Free: it carries no charge and skips the balance gate, because an account at zero
|
|
937
946
|
* still has to be able to find out why. Rate-limited instead.
|
|
938
947
|
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
* because that is what gates the next call whichever key makes it.
|
|
948
|
+
* `key` is THIS key's own lifetime spend. `workspace` and `stores` cover the window
|
|
949
|
+
* for the workspace this key belongs to, every key in it included. `balance_cents` is
|
|
950
|
+
* account-wide, because that is what gates the next call whichever key makes it.
|
|
942
951
|
*
|
|
943
952
|
* const u = await mem.usage(7);
|
|
944
953
|
* if (u.balance_cents! < 100) stop();
|
|
945
954
|
*/
|
|
946
955
|
usage(days?: number): Promise<UsageResult>;
|
|
947
956
|
/** Fetch ONE memory by id — the text you stored, and its metadata.
|
|
948
|
-
* The id is what `add`/`store` or `listMemories` returned.
|
|
949
|
-
*
|
|
950
|
-
* or an invalidated memory rejects with `NotFoundError`. Pass `undefined` as
|
|
957
|
+
* The id is what `add`/`store` or `listMemories` returned. An unknown id or one
|
|
958
|
+
* from another store rejects with `NotFoundError`. Pass `undefined` as
|
|
951
959
|
* `userId` for the default store — it is positional here. */
|
|
952
960
|
get(userId: string | undefined, memoryId: string): Promise<Memory>;
|
|
953
961
|
/** List a store's stored memories — the text you stored, plus its metadata.
|
|
@@ -993,9 +1001,10 @@ export declare class Client {
|
|
|
993
1001
|
* Fetch the bytes of an image memory — the picture the SERVICE holds.
|
|
994
1002
|
*
|
|
995
1003
|
* Not necessarily your upload, in size OR in format: an image whose long edge was
|
|
996
|
-
* over 1568px was downscaled to 1568 on the way in and re-encoded —
|
|
997
|
-
* formats as WebP, so a PNG comes back as `image/webp`; JPEG stays JPEG
|
|
998
|
-
*
|
|
1004
|
+
* over 1568px (2500 at most) was downscaled to 1568 on the way in and re-encoded —
|
|
1005
|
+
* lossless formats as WebP, so a PNG comes back as `image/webp`; JPEG stays JPEG;
|
|
1006
|
+
* kept as sent when the re-encode came out bigger — and that smaller picture is what
|
|
1007
|
+
* is stored and comes back here. Nothing on our side ever
|
|
999
1008
|
* uses more than 1568, so the extra pixels would be bytes nobody reads.
|
|
1000
1009
|
* Keep your own copy for the full-resolution file.
|
|
1001
1010
|
*
|
|
@@ -1100,11 +1109,13 @@ export declare class Client {
|
|
|
1100
1109
|
skipIds?: string[];
|
|
1101
1110
|
}): Promise<RevisionsResult>;
|
|
1102
1111
|
/**
|
|
1103
|
-
* The
|
|
1112
|
+
* The edits that followed one memory: from the id you pass forward to the version in
|
|
1113
|
+
* force, oldest first.
|
|
1104
1114
|
*
|
|
1105
|
-
* `is_current` marks the version in force.
|
|
1106
|
-
* say, and when did it change"
|
|
1107
|
-
*
|
|
1115
|
+
* `is_current` marks the version in force. The chain runs forward only, so to answer
|
|
1116
|
+
* "what did this used to say, and when did it change" pass the first version's id;
|
|
1117
|
+
* the current version's id (what `search` returns) comes back alone. `revisions()`
|
|
1118
|
+
* tells you HOW MUCH a store moved, this tells you what happened to one fact.
|
|
1108
1119
|
*/
|
|
1109
1120
|
lineage(userId: string | undefined, memoryId: string): Promise<LineageResult>;
|
|
1110
1121
|
/**
|
|
@@ -1126,8 +1137,7 @@ export declare class Client {
|
|
|
1126
1137
|
* `AuthenticationError` (bad key), `PaymentRequiredError` (valid key but no card /
|
|
1127
1138
|
* depleted balance), or `APIConnectionError` (unreachable). Makes one metered request. */
|
|
1128
1139
|
ping(): Promise<boolean>;
|
|
1129
|
-
/** Available models: `[{ id, name, available, memory, capabilities, retires_at? }, ...]`.
|
|
1130
|
-
* Needs no API key. */
|
|
1140
|
+
/** Available models: `[{ id, name, available, memory, capabilities, retires_at? }, ...]`. */
|
|
1131
1141
|
listModels(): Promise<ModelInfo[]>;
|
|
1132
1142
|
/**
|
|
1133
1143
|
* The engrams (and delivery forms) the selected model can actually run.
|
|
@@ -1160,7 +1170,9 @@ export declare class Client {
|
|
|
1160
1170
|
addSpeaker(speaker: string, userId?: string): Promise<SpeakerOpResult>;
|
|
1161
1171
|
/** The store's registered people, each with its memory count. */
|
|
1162
1172
|
listSpeakers(userId?: string): Promise<SpeakersList>;
|
|
1163
|
-
/** Unregister a person. Their memories stay
|
|
1173
|
+
/** Unregister a person. Their memories stay, and the name can no longer tag a new
|
|
1174
|
+
* memory or filter a search. The tag goes from stored memories too, except on
|
|
1175
|
+
* `tablet-2`, which keeps it on memories already stored with it. Retried like
|
|
1164
1176
|
* `deleteStore`, with the same note on a 404 after an ambiguous failure. */
|
|
1165
1177
|
removeSpeaker(speaker: string, userId?: string): Promise<SpeakerOpResult>;
|
|
1166
1178
|
/** Delete a single memory by id. Pass `undefined` as `userId` for the default
|
|
@@ -1210,12 +1222,12 @@ export declare class Client {
|
|
|
1210
1222
|
*
|
|
1211
1223
|
* Retried: 429, and a 409 whose error carries `retry_after_ms` (another write to the
|
|
1212
1224
|
* store was in flight; nothing was stored), on every method; 408/502/503/504 and
|
|
1213
|
-
* dropped connections on
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1216
|
-
*
|
|
1217
|
-
* only reads that the deadline cuts short. Any other retry cut
|
|
1218
|
-
* deadline error: a write may have been applied.
|
|
1225
|
+
* dropped connections on a call that only reads (an idempotent method, or a POST
|
|
1226
|
+
* that only reads); connect failures on every method. A retry whose wait is over the
|
|
1227
|
+
* cap, or does not fit the deadline, is not made: the call fails with the error of
|
|
1228
|
+
* the response it has. So does a retry the deadline leaves no time to send, and the
|
|
1229
|
+
* retry of a call that only reads that the deadline cuts short. Any other retry cut
|
|
1230
|
+
* short stays a status-0 deadline error: a write may have been applied.
|
|
1219
1231
|
*/
|
|
1220
1232
|
private send;
|
|
1221
1233
|
/**
|
package/dist/wontopos.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const VERSION = "2.2.
|
|
1
|
+
const VERSION = "2.2.46";
|
|
2
2
|
const RUNTIME = (() => {
|
|
3
3
|
const p = globalThis?.process;
|
|
4
4
|
return p?.version ? ` (node/${p.version}; ${p.platform}-${p.arch})` : "";
|
|
@@ -1097,8 +1097,8 @@ export class Client {
|
|
|
1097
1097
|
}
|
|
1098
1098
|
const attempts = this.maxRetries + 1;
|
|
1099
1099
|
const upper = method.toUpperCase();
|
|
1100
|
-
const idempotent = IDEMPOTENT_METHODS.has(upper);
|
|
1101
1100
|
const logPath = path.split("?")[0];
|
|
1101
|
+
const idempotent = IDEMPOTENT_METHODS.has(upper) || reads || (upper === "POST" && READ_POSTS.has(logPath));
|
|
1102
1102
|
const deadlineAt = this.deadlineAt();
|
|
1103
1103
|
const headers = extraHeaders ? { ...this.headers, ...extraHeaders } : this.headers;
|
|
1104
1104
|
let ambiguous = false;
|
|
@@ -1119,7 +1119,7 @@ export class Client {
|
|
|
1119
1119
|
};
|
|
1120
1120
|
const cutShort = () => {
|
|
1121
1121
|
const why = att.why();
|
|
1122
|
-
if (why === "deadline" &&
|
|
1122
|
+
if (why === "deadline" && idempotent && previous) {
|
|
1123
1123
|
return previous;
|
|
1124
1124
|
}
|
|
1125
1125
|
return new APIConnectionError(0, this.abortMessage(why));
|