wontopos 2.2.34 → 2.2.36
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 +107 -9
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/wontopos.js +1582 -0
- package/dist/wontopos.d.ts +132 -60
- package/dist/wontopos.js +410 -134
- package/package.json +8 -10
package/README.md
CHANGED
|
@@ -23,15 +23,23 @@ const ctx = await mem.recall("what does alice drink?", "alice");
|
|
|
23
23
|
|
|
24
24
|
## Why
|
|
25
25
|
|
|
26
|
-
- **
|
|
27
|
-
- **No LLM in the loop** — `store` / `search` / `recall` never call a language model. You pay
|
|
28
|
-
- **Bounded retrieval** — `recall()` returns a small, fixed-size slice
|
|
26
|
+
- **The same in every language** — identical recall whichever language a memory was written in (Korean · Japanese · Chinese · English).
|
|
27
|
+
- **No LLM in the loop** — `store` / `search` / `recall` never call a language model. You pay retrieval, not generation.
|
|
28
|
+
- **Bounded retrieval** — `recall()` returns a small, fixed-size slice regardless of how much you've stored (~1,000 tokens on `tablet-2`, the default engine).
|
|
29
29
|
|
|
30
30
|
## Methods
|
|
31
31
|
|
|
32
32
|
`add` · `addTurn` · `addBulk` · `update` · `search` · `searchFull` · `recall` · `history` · `stats` · `get` · `listMemories` · `delete` · `deleteAll`
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Where the store id goes depends on whether the method takes a payload. A method that
|
|
35
|
+
writes or searches puts the payload first and the store second — `mem.add("...", "alice")`,
|
|
36
|
+
`mem.search("...", "alice")`. A method that only addresses a store takes it first —
|
|
37
|
+
`mem.listMemories("alice")`, `mem.stats("alice")`, `mem.delete("alice", memoryId)`.
|
|
38
|
+
Most of them let you leave it out for the client's default store. Four take it
|
|
39
|
+
positionally and cannot — `get`, `delete`, `lineage` and `forgetImage` want an explicit
|
|
40
|
+
`undefined` there, because a second required argument follows it. Python omits it in
|
|
41
|
+
all four; this is the one place the three clients differ in shape rather than meaning.
|
|
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.
|
|
35
43
|
|
|
36
44
|
## Who said it (speakers)
|
|
37
45
|
|
|
@@ -72,11 +80,23 @@ const hits = await mem.search("...the conversation so far...", "alice", 10,
|
|
|
72
80
|
|
|
73
81
|
Built in, no configuration needed:
|
|
74
82
|
|
|
75
|
-
- **Automatic retries** — 429
|
|
83
|
+
- **Automatic retries** — 429 always, and 502 / 503 or a connection error only when a
|
|
84
|
+
retry cannot double-process a write. The writes and the searches are POSTs, and a
|
|
85
|
+
502 on one of those may have been returned *after* the service already stored and
|
|
86
|
+
billed it, so those get 429 and connect-level failures only. The reads and the
|
|
87
|
+
deletes that address a whole store — `listStores`, `listSpeakers`, `deleteStore`,
|
|
88
|
+
`removeSpeaker`, `forgetImage` — are GET or DELETE and do retry a 502. Twice, with
|
|
76
89
|
exponential backoff + jitter, honoring the server's `Retry-After`. Tune with
|
|
77
90
|
`new Client({ maxRetries })`; `0` disables.
|
|
78
91
|
- **Redirects refused** — the API key never follows a 3xx to another host.
|
|
79
|
-
- **Timeouts** — 30s per attempt by default (`timeoutMs`)
|
|
92
|
+
- **Timeouts** — 30s per attempt by default (`timeoutMs`), and a total budget for
|
|
93
|
+
the whole call across every retry with `deadlineMs` / `withDeadline(ms)`. At the
|
|
94
|
+
defaults one call can hold for 30s + backoff + 30s + backoff + 30s, which a
|
|
95
|
+
request handler with five seconds cannot use.
|
|
96
|
+
- **Cancellable** — pass the caller's `AbortSignal` (`new Client({ signal })` or
|
|
97
|
+
`withSignal(signal)`). Aborting ends the request in flight and any backoff sleep
|
|
98
|
+
waiting to retry it.
|
|
99
|
+
- **CommonJS and ESM** — `require("wontopos")` and `import` both resolve.
|
|
80
100
|
- **Key never in logs** — `JSON.stringify(client)` and Node's `console.log(client)`
|
|
81
101
|
print a masked key.
|
|
82
102
|
- **Wipe guard** — `delete()` without a `memoryId` throws instead of silently
|
|
@@ -162,10 +182,13 @@ try {
|
|
|
162
182
|
}
|
|
163
183
|
```
|
|
164
184
|
|
|
165
|
-
##
|
|
185
|
+
## A different API host
|
|
186
|
+
|
|
187
|
+
Point the client somewhere other than the default endpoint - a dedicated region,
|
|
188
|
+
a proxy of your own, or a local test server:
|
|
166
189
|
|
|
167
190
|
```ts
|
|
168
|
-
const mem = new Client({ apiKey: "...", baseUrl: "https://
|
|
191
|
+
const mem = new Client({ apiKey: "...", baseUrl: "https://api.example.com" });
|
|
169
192
|
```
|
|
170
193
|
|
|
171
194
|
## Links
|
|
@@ -189,7 +212,82 @@ data to fix it.
|
|
|
189
212
|
|
|
190
213
|
The three clients release in lockstep — same version, same surface, same day.
|
|
191
214
|
Patch releases are additive: nothing is removed or reordered within a minor line.
|
|
192
|
-
|
|
215
|
+
Two have bent that, deliberately and named at the top of their entry — 2.2.34 moved the
|
|
216
|
+
default engine, and 2.2.35 gives `search` the count range `recall` has always had. A
|
|
217
|
+
rule you can bend without saying so is not a rule, so both are stated rather than left
|
|
218
|
+
for a reader to hit.
|
|
219
|
+
|
|
220
|
+
- **2.2.36** — an outside review, read by a different model with no knowledge of why
|
|
221
|
+
any of this was written. The one that mattered: `recall()` promised in its own
|
|
222
|
+
documentation that a count outside 5–20 was refused rather than clamped, and
|
|
223
|
+
nothing checked — so `{ limit: 500 }` travelled to the service and failed there, for a
|
|
224
|
+
mistake visible before opening a socket. `context_limit` (0–20) was unchecked the same way.
|
|
225
|
+
Both are refused here now, and `0` still passes for `context_limit` because "attach none" is
|
|
226
|
+
an answer, not a missing value.
|
|
227
|
+
An argument mistake now throws a plain `Error`, not a `WosError`. A `WosError` with
|
|
228
|
+
status 0 is `APIConnectionError` — "the request never got a response" — so
|
|
229
|
+
`if (e.status === 0) retry()` would have retried a typo forever. And `recall` is
|
|
230
|
+
now `async`: validating inside a non-async method threw synchronously, so
|
|
231
|
+
`mem.recall(...).catch(h)` walked past the handler while the same mistake in
|
|
232
|
+
`search` landed in it.
|
|
233
|
+
New `deadlineMs` / `withDeadline(ms)`: a TOTAL budget for one call across every
|
|
234
|
+
retry. `timeoutMs` bounds one ATTEMPT, so at the defaults a call could hold for 30s
|
|
235
|
+
+ backoff + 30s + backoff + 30s and a request handler with five seconds had no way
|
|
236
|
+
to say so. New `signal` / `withSignal(signal)`: cancel work in flight — an abort
|
|
237
|
+
ends the request AND any backoff sleep waiting to retry it.
|
|
238
|
+
`require("wontopos")` now resolves: the package ships CommonJS and ESM from one
|
|
239
|
+
source. Previously `"type": "module"` with no `require` condition meant Node's CJS
|
|
240
|
+
resolver could not resolve this package at all.
|
|
241
|
+
`replayed` is set only when the service did not send that field itself.
|
|
242
|
+
- **2.2.35** — fixes, and **two behaviour changes**, both listed first because a patch
|
|
243
|
+
release is not the place to find one by surprise.
|
|
244
|
+
|
|
245
|
+
⚠️ **`search`'s count is now 5–20, and out of range is refused rather than
|
|
246
|
+
adjusted.** `recall` has carried that range from the start; search had no contract
|
|
247
|
+
anywhere, so the clients sent whatever they were given and the service capped at 50
|
|
248
|
+
with no floor. `search(q, limit=50)` and `search(q, limit=3)` both worked on 2.2.34
|
|
249
|
+
and now raise. The default is still 10, so a call that passes no count is unaffected.
|
|
250
|
+
Asking for 20 and silently getting 10 reads as "that is all there is", which is why
|
|
251
|
+
this refuses instead of clamping.
|
|
252
|
+
|
|
253
|
+
⚠️ **A Rust `limit` of 0 is no longer rewritten to 10.** It was, and the caller whose
|
|
254
|
+
prompt budget computed zero was handed ten memories and the bill for them. It is now
|
|
255
|
+
refused under the range above rather than quietly changed to something nobody asked
|
|
256
|
+
for.
|
|
257
|
+
|
|
258
|
+
The fixes: a `null` idempotency key no longer becomes the literal key `"null"`, which
|
|
259
|
+
had made every write on that path share one key so the second onward stored nothing
|
|
260
|
+
(TypeScript). The async client no longer reads an explicit `retries=2` as "the caller
|
|
261
|
+
said nothing" (Python). The image read is actually streamed, so the 64MB cap bounds a
|
|
262
|
+
compressed body instead of measuring bytes already in memory (Python async), and that
|
|
263
|
+
route's ERROR body is capped too (Rust). `iter_images` stops on a repeated cursor the
|
|
264
|
+
way `iter_memories` always did (Python). `iterImages` no longer throws on the ordinary
|
|
265
|
+
end of a walk (TypeScript). `get_image` retries a 429 and a connect-level failure like
|
|
266
|
+
every other call — it had none at all — in the **sync Python client and TypeScript**;
|
|
267
|
+
the async Python client and the Rust crate still make a single attempt there, and say
|
|
268
|
+
so at the method. An empty or control-character API key is refused at the call site
|
|
269
|
+
rather than at the network in **Python and Rust**; TypeScript still refuses only empty
|
|
270
|
+
and whitespace. And a page walk that reaches its ceiling now raises instead of
|
|
271
|
+
returning a truncated list that looks complete.
|
|
272
|
+
- **2.2.34** — the default engine is `tablet-2`: same token price as `tablet-1`, and
|
|
273
|
+
the one that serves images and re-ask. Pin the old one with
|
|
274
|
+
`model="tablet-1"` for the previous behaviour exactly. (The engine's own default
|
|
275
|
+
count differs between the two, but these SDKs always send one, so a call through
|
|
276
|
+
them is unaffected.) New `search_full` /
|
|
277
|
+
`searchFull` keeps every field the answer came with — `search` was merging away
|
|
278
|
+
the photos and `verify_used`, both of which you were billed for. Also: results arrive
|
|
279
|
+
best-first — take the order as given. `similarity` is a raw closeness score, and
|
|
280
|
+
sorting by it makes results worse.
|
|
281
|
+
- **2.2.33** — `get_image` can return a different FORMAT than you uploaded: the
|
|
282
|
+
service re-encodes on downscale, so a large PNG comes back as WebP. Take the file
|
|
283
|
+
extension from the response Content-Type, not from what you sent.
|
|
284
|
+
- **2.2.32** — `get_image` returns the picture the SERVICE holds, not your original.
|
|
285
|
+
An image whose long edge is over 1568px is downscaled on the way in, and that
|
|
286
|
+
smaller picture is what is stored and handed back. Keep your own copy if you need
|
|
287
|
+
the full file.
|
|
288
|
+
- **2.2.31** — images, by-speaker, lineage and revisions are SDK methods in all three
|
|
289
|
+
clients; `search` and `recall` take `verify`, `max_images` and recall's `limit` /
|
|
290
|
+
`context_limit`.
|
|
193
291
|
- **2.2.30** — documentation only: this changelog, which had not been updated
|
|
194
292
|
in the shipped package since 2.2.10.
|
|
195
293
|
- **2.2.29** — a store id that was PASSED but unusable no longer becomes the
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|