wontopos 2.2.44 → 2.2.45
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 -8
- package/dist/cjs/wontopos.d.cts +4 -3
- package/dist/cjs/wontopos.js +26 -11
- package/dist/wontopos.d.ts +4 -3
- package/dist/wontopos.js +26 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ npm install wontopos
|
|
|
5
5
|
```
|
|
6
6
|
|
|
7
7
|
Get an API key in the [console](https://wontopos.com). Keys look like `wos-live-...`;
|
|
8
|
-
|
|
8
|
+
`Client.fromEnv()` reads `WONTOPOS_API_KEY` from the environment instead.
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
11
|
import { Client } from "wontopos";
|
|
@@ -35,10 +35,10 @@ Where the store id goes depends on whether the method takes a payload. A method
|
|
|
35
35
|
writes or searches puts the payload first and the store second — `mem.add("...", "alice")`,
|
|
36
36
|
`mem.search("...", "alice")`. A method that only addresses a store takes it first —
|
|
37
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.
|
|
39
|
-
positionally and cannot — `get`, `delete`, `lineage` and `forgetImage` want
|
|
40
|
-
`undefined` there, because a second required argument follows it. Python
|
|
41
|
-
all
|
|
38
|
+
Most of them let you leave it out for the client's default store. Five take it
|
|
39
|
+
positionally and cannot — `get`, `getImage`, `delete`, `lineage` and `forgetImage` want
|
|
40
|
+
an explicit `undefined` there, because a second required argument follows it. Python
|
|
41
|
+
omits it in all five; this is the one place the three clients differ in shape rather than meaning.
|
|
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)
|
|
@@ -112,6 +112,7 @@ This one needs `npm i undici` — Node's global `fetch` is built on undici, but
|
|
|
112
112
|
package itself is not installed for you.
|
|
113
113
|
|
|
114
114
|
```ts
|
|
115
|
+
import { Client } from "wontopos";
|
|
115
116
|
import { ProxyAgent } from "undici";
|
|
116
117
|
|
|
117
118
|
const agent = new ProxyAgent(process.env.HTTPS_PROXY!);
|
|
@@ -147,7 +148,7 @@ Every method returns a documented shape — `StoreResult`, `UpdateResult`,
|
|
|
147
148
|
`RecallResult`, `EngramResult`, `StatsResult`, `SpeakersList`, `Memory[]`, ... —
|
|
148
149
|
each with an index signature, so new server fields flow through without an SDK
|
|
149
150
|
update. `search` options are typed too (`SearchOptions`: `cache_control`,
|
|
150
|
-
`speaker`, plus pass-through).
|
|
151
|
+
`speaker`, plus `extra` for pass-through).
|
|
151
152
|
|
|
152
153
|
```ts
|
|
153
154
|
import { type Memory } from "wontopos";
|
|
@@ -206,14 +207,14 @@ Found something wrong, or something that looks unsafe? Tell us — every report
|
|
|
206
207
|
- Security: <https://wontopos.com/contact?topic=security> (also published at
|
|
207
208
|
[`/.well-known/security.txt`](https://wontopos.com/.well-known/security.txt))
|
|
208
209
|
|
|
209
|
-
Include the SDK version (
|
|
210
|
+
Include the SDK version (the one in package.json) and the language. If it involves a store id or a
|
|
210
211
|
memory, describe the shape rather than pasting the contents — we do not need your
|
|
211
212
|
data to fix it.
|
|
212
213
|
|
|
213
214
|
## Changelog
|
|
214
215
|
|
|
215
216
|
The three clients release in lockstep — same version, same surface, same day. Patch
|
|
216
|
-
releases are additive.
|
|
217
|
+
releases are additive. Nine inside 2.2 were not, deliberately and each with its
|
|
217
218
|
reason; the changelog lists them.
|
|
218
219
|
|
|
219
220
|
See [CHANGELOG.md](https://github.com/wontopos/wontopos-node/blob/main/CHANGELOG.md).
|
package/dist/cjs/wontopos.d.cts
CHANGED
|
@@ -652,9 +652,10 @@ export interface SearchOptions {
|
|
|
652
652
|
export interface WriteOptions {
|
|
653
653
|
idempotencyKey?: string;
|
|
654
654
|
/**
|
|
655
|
-
* An image to store alongside the text
|
|
656
|
-
* `
|
|
657
|
-
*
|
|
655
|
+
* An image to store alongside the text, read by `add` (and `store`) only: `addTurn`,
|
|
656
|
+
* `addBulk` and `update` warn about it and do not send it. Needs a model that lists
|
|
657
|
+
* `images` in its `listModels()` capabilities; any other refuses the write rather than
|
|
658
|
+
* store the caption and quietly drop the image.
|
|
658
659
|
*
|
|
659
660
|
* A caption is required: the service refuses empty `content` (400) even with an
|
|
660
661
|
* image attached.
|
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.45";
|
|
7
7
|
const RUNTIME = (() => {
|
|
8
8
|
const p = globalThis?.process;
|
|
9
9
|
return p?.version ? ` (node/${p.version}; ${p.platform}-${p.arch})` : "";
|
|
@@ -508,7 +508,7 @@ const KNOWN_ENGRAM_KEYS = new Set(["form", "tz"]);
|
|
|
508
508
|
function checkSearchOpts(opts) {
|
|
509
509
|
checkOpts(opts, KNOWN_SEARCH_KEYS, "search");
|
|
510
510
|
const o = opts;
|
|
511
|
-
optRange(o.max_images
|
|
511
|
+
optRange(o.max_images != null ? o.max_images : o.extra?.max_images, "max_images", 0, MAX_IMAGES_MAX);
|
|
512
512
|
}
|
|
513
513
|
function checkOpts(opts, known, what) {
|
|
514
514
|
for (const k of Object.keys(opts)) {
|
|
@@ -558,6 +558,17 @@ function warnOnceUnknownKeys(obj, known, warned, message) {
|
|
|
558
558
|
console.warn(message(k));
|
|
559
559
|
}
|
|
560
560
|
}
|
|
561
|
+
function givenOpts(known) {
|
|
562
|
+
return Object.fromEntries(Object.entries(known).filter(([, v]) => v !== null));
|
|
563
|
+
}
|
|
564
|
+
const ADD_KEYS = new Set(["idempotencyKey", "image"]);
|
|
565
|
+
const WRITE_KEYS = new Set(["idempotencyKey"]);
|
|
566
|
+
const warnedWriteKeys = new Set();
|
|
567
|
+
function writeKey(opts, takesImage = false) {
|
|
568
|
+
warnOnceUnknownKeys(opts, takesImage ? ADD_KEYS : WRITE_KEYS, warnedWriteKeys, (k) => `wontopos: write option ${JSON.stringify(k)} is not sent. ` +
|
|
569
|
+
(takesImage ? "add takes idempotencyKey and image." : "This call takes idempotencyKey only."));
|
|
570
|
+
return opts.idempotencyKey;
|
|
571
|
+
}
|
|
561
572
|
function warnOnUnknownFilters(filters) {
|
|
562
573
|
warnOnceUnknownKeys(filters, KNOWN_FILTER_KEYS, warnedFilterKeys, (k) => `wontopos: unknown search filter ${JSON.stringify(k)} — the API drops keys it does not know, ` +
|
|
563
574
|
`so this filter has NO effect and the search is wider than you think. ` +
|
|
@@ -718,22 +729,22 @@ class Client {
|
|
|
718
729
|
if (opts.image !== undefined)
|
|
719
730
|
body.image = normalizeImage(opts.image);
|
|
720
731
|
warnOnUnknownMetadata(metadata);
|
|
721
|
-
return this.post("/api/v1/memory/store", body, opts
|
|
732
|
+
return this.post("/api/v1/memory/store", body, writeKey(opts, true));
|
|
722
733
|
}
|
|
723
734
|
async store(content, userId, metadata = {}, opts = {}) {
|
|
724
735
|
return this.add(content, userId, metadata, opts);
|
|
725
736
|
}
|
|
726
737
|
async addTurn(userMsg, assistantMsg, userId, opts = {}) {
|
|
727
|
-
return this.post("/api/v1/memory/store-turn", { user_id: this.uid(userId), user_msg: userMsg, assistant_msg: assistantMsg }, opts
|
|
738
|
+
return this.post("/api/v1/memory/store-turn", { user_id: this.uid(userId), user_msg: userMsg, assistant_msg: assistantMsg }, writeKey(opts));
|
|
728
739
|
}
|
|
729
740
|
async addBulk(content, userId, category = "general", timestamp, opts = {}) {
|
|
730
|
-
const body = { user_id: this.uid(userId), content, category };
|
|
741
|
+
const body = { user_id: this.uid(userId), content, category: category ?? "general" };
|
|
731
742
|
if (timestamp)
|
|
732
743
|
body.timestamp = timestamp;
|
|
733
|
-
return this.post("/api/v1/memory/bulk-store", body, opts
|
|
744
|
+
return this.post("/api/v1/memory/bulk-store", body, writeKey(opts));
|
|
734
745
|
}
|
|
735
746
|
async update(oldMemoryId, newContent, userId, opts = {}) {
|
|
736
|
-
return this.post("/api/v1/memory/supersede", { user_id: this.uid(userId), old_memory_id: oldMemoryId, new_content: newContent }, opts
|
|
747
|
+
return this.post("/api/v1/memory/supersede", { user_id: this.uid(userId), old_memory_id: oldMemoryId, new_content: newContent }, writeKey(opts));
|
|
737
748
|
}
|
|
738
749
|
async search(query, userId, limit = 10, opts = {}) {
|
|
739
750
|
checkSearchOpts(opts);
|
|
@@ -741,7 +752,7 @@ class Client {
|
|
|
741
752
|
limit ??= 10;
|
|
742
753
|
checkCount(limit, "limit");
|
|
743
754
|
const { extra, ...known } = opts;
|
|
744
|
-
const r = await this.post("/api/v1/memory/search", { ...extra, ...known, user_id: this.uid(userId), query, max_results: limit });
|
|
755
|
+
const r = await this.post("/api/v1/memory/search", { ...extra, ...givenOpts(known), user_id: this.uid(userId), query, max_results: limit });
|
|
745
756
|
return mergeResults(r);
|
|
746
757
|
}
|
|
747
758
|
async searchSelf(query, userId, limit = 10, opts = {}) {
|
|
@@ -750,7 +761,7 @@ class Client {
|
|
|
750
761
|
limit ??= 10;
|
|
751
762
|
checkCount(limit, "limit");
|
|
752
763
|
const { extra, ...known } = opts;
|
|
753
|
-
const r = await this.post("/api/v1/memory/search", { ...extra, ...known, user_id: this.uid(userId), query, max_results: limit });
|
|
764
|
+
const r = await this.post("/api/v1/memory/search", { ...extra, ...givenOpts(known), user_id: this.uid(userId), query, max_results: limit });
|
|
754
765
|
return { memories: asRecords(r.memories), self_memories: asRecords(r.self_memories) };
|
|
755
766
|
}
|
|
756
767
|
async searchFull(query, userId, limit = 10, opts = {}) {
|
|
@@ -759,7 +770,7 @@ class Client {
|
|
|
759
770
|
limit ??= 10;
|
|
760
771
|
checkCount(limit, "limit");
|
|
761
772
|
const { extra, ...known } = opts;
|
|
762
|
-
const r = await this.post("/api/v1/memory/search", { ...extra, ...known, user_id: this.uid(userId), query, max_results: limit });
|
|
773
|
+
const r = await this.post("/api/v1/memory/search", { ...extra, ...givenOpts(known), user_id: this.uid(userId), query, max_results: limit });
|
|
763
774
|
return {
|
|
764
775
|
...r,
|
|
765
776
|
memories: asRecords(r.memories),
|
|
@@ -894,9 +905,13 @@ class Client {
|
|
|
894
905
|
throw truncatedWalk(`stopped after ${MAX_PAGES} pages — the store did not end.`);
|
|
895
906
|
}
|
|
896
907
|
async revisions(userId, opts = {}) {
|
|
908
|
+
const inc = opts.include;
|
|
909
|
+
if (inc !== undefined && inc !== null && inc !== "revised" && inc !== "unrevised") {
|
|
910
|
+
throw new Error(`include must be "revised" or "unrevised", got ${JSON.stringify(inc)}.`);
|
|
911
|
+
}
|
|
897
912
|
const limit = optRange(opts.limit, "limit", PAGE_LIMIT_MIN, PAGE_LIMIT_MAX);
|
|
898
913
|
const body = {};
|
|
899
|
-
if (opts.include
|
|
914
|
+
if (opts.include != null)
|
|
900
915
|
body.include = opts.include;
|
|
901
916
|
if (limit !== undefined)
|
|
902
917
|
body.limit = limit;
|
package/dist/wontopos.d.ts
CHANGED
|
@@ -652,9 +652,10 @@ export interface SearchOptions {
|
|
|
652
652
|
export interface WriteOptions {
|
|
653
653
|
idempotencyKey?: string;
|
|
654
654
|
/**
|
|
655
|
-
* An image to store alongside the text
|
|
656
|
-
* `
|
|
657
|
-
*
|
|
655
|
+
* An image to store alongside the text, read by `add` (and `store`) only: `addTurn`,
|
|
656
|
+
* `addBulk` and `update` warn about it and do not send it. Needs a model that lists
|
|
657
|
+
* `images` in its `listModels()` capabilities; any other refuses the write rather than
|
|
658
|
+
* store the caption and quietly drop the image.
|
|
658
659
|
*
|
|
659
660
|
* A caption is required: the service refuses empty `content` (400) even with an
|
|
660
661
|
* image attached.
|
package/dist/wontopos.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const VERSION = "2.2.
|
|
1
|
+
const VERSION = "2.2.45";
|
|
2
2
|
const RUNTIME = (() => {
|
|
3
3
|
const p = globalThis?.process;
|
|
4
4
|
return p?.version ? ` (node/${p.version}; ${p.platform}-${p.arch})` : "";
|
|
@@ -492,7 +492,7 @@ const KNOWN_ENGRAM_KEYS = new Set(["form", "tz"]);
|
|
|
492
492
|
function checkSearchOpts(opts) {
|
|
493
493
|
checkOpts(opts, KNOWN_SEARCH_KEYS, "search");
|
|
494
494
|
const o = opts;
|
|
495
|
-
optRange(o.max_images
|
|
495
|
+
optRange(o.max_images != null ? o.max_images : o.extra?.max_images, "max_images", 0, MAX_IMAGES_MAX);
|
|
496
496
|
}
|
|
497
497
|
function checkOpts(opts, known, what) {
|
|
498
498
|
for (const k of Object.keys(opts)) {
|
|
@@ -542,6 +542,17 @@ function warnOnceUnknownKeys(obj, known, warned, message) {
|
|
|
542
542
|
console.warn(message(k));
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
|
+
function givenOpts(known) {
|
|
546
|
+
return Object.fromEntries(Object.entries(known).filter(([, v]) => v !== null));
|
|
547
|
+
}
|
|
548
|
+
const ADD_KEYS = new Set(["idempotencyKey", "image"]);
|
|
549
|
+
const WRITE_KEYS = new Set(["idempotencyKey"]);
|
|
550
|
+
const warnedWriteKeys = new Set();
|
|
551
|
+
function writeKey(opts, takesImage = false) {
|
|
552
|
+
warnOnceUnknownKeys(opts, takesImage ? ADD_KEYS : WRITE_KEYS, warnedWriteKeys, (k) => `wontopos: write option ${JSON.stringify(k)} is not sent. ` +
|
|
553
|
+
(takesImage ? "add takes idempotencyKey and image." : "This call takes idempotencyKey only."));
|
|
554
|
+
return opts.idempotencyKey;
|
|
555
|
+
}
|
|
545
556
|
function warnOnUnknownFilters(filters) {
|
|
546
557
|
warnOnceUnknownKeys(filters, KNOWN_FILTER_KEYS, warnedFilterKeys, (k) => `wontopos: unknown search filter ${JSON.stringify(k)} — the API drops keys it does not know, ` +
|
|
547
558
|
`so this filter has NO effect and the search is wider than you think. ` +
|
|
@@ -702,22 +713,22 @@ export class Client {
|
|
|
702
713
|
if (opts.image !== undefined)
|
|
703
714
|
body.image = normalizeImage(opts.image);
|
|
704
715
|
warnOnUnknownMetadata(metadata);
|
|
705
|
-
return this.post("/api/v1/memory/store", body, opts
|
|
716
|
+
return this.post("/api/v1/memory/store", body, writeKey(opts, true));
|
|
706
717
|
}
|
|
707
718
|
async store(content, userId, metadata = {}, opts = {}) {
|
|
708
719
|
return this.add(content, userId, metadata, opts);
|
|
709
720
|
}
|
|
710
721
|
async addTurn(userMsg, assistantMsg, userId, opts = {}) {
|
|
711
|
-
return this.post("/api/v1/memory/store-turn", { user_id: this.uid(userId), user_msg: userMsg, assistant_msg: assistantMsg }, opts
|
|
722
|
+
return this.post("/api/v1/memory/store-turn", { user_id: this.uid(userId), user_msg: userMsg, assistant_msg: assistantMsg }, writeKey(opts));
|
|
712
723
|
}
|
|
713
724
|
async addBulk(content, userId, category = "general", timestamp, opts = {}) {
|
|
714
|
-
const body = { user_id: this.uid(userId), content, category };
|
|
725
|
+
const body = { user_id: this.uid(userId), content, category: category ?? "general" };
|
|
715
726
|
if (timestamp)
|
|
716
727
|
body.timestamp = timestamp;
|
|
717
|
-
return this.post("/api/v1/memory/bulk-store", body, opts
|
|
728
|
+
return this.post("/api/v1/memory/bulk-store", body, writeKey(opts));
|
|
718
729
|
}
|
|
719
730
|
async update(oldMemoryId, newContent, userId, opts = {}) {
|
|
720
|
-
return this.post("/api/v1/memory/supersede", { user_id: this.uid(userId), old_memory_id: oldMemoryId, new_content: newContent }, opts
|
|
731
|
+
return this.post("/api/v1/memory/supersede", { user_id: this.uid(userId), old_memory_id: oldMemoryId, new_content: newContent }, writeKey(opts));
|
|
721
732
|
}
|
|
722
733
|
async search(query, userId, limit = 10, opts = {}) {
|
|
723
734
|
checkSearchOpts(opts);
|
|
@@ -725,7 +736,7 @@ export class Client {
|
|
|
725
736
|
limit ??= 10;
|
|
726
737
|
checkCount(limit, "limit");
|
|
727
738
|
const { extra, ...known } = opts;
|
|
728
|
-
const r = await this.post("/api/v1/memory/search", { ...extra, ...known, user_id: this.uid(userId), query, max_results: limit });
|
|
739
|
+
const r = await this.post("/api/v1/memory/search", { ...extra, ...givenOpts(known), user_id: this.uid(userId), query, max_results: limit });
|
|
729
740
|
return mergeResults(r);
|
|
730
741
|
}
|
|
731
742
|
async searchSelf(query, userId, limit = 10, opts = {}) {
|
|
@@ -734,7 +745,7 @@ export class Client {
|
|
|
734
745
|
limit ??= 10;
|
|
735
746
|
checkCount(limit, "limit");
|
|
736
747
|
const { extra, ...known } = opts;
|
|
737
|
-
const r = await this.post("/api/v1/memory/search", { ...extra, ...known, user_id: this.uid(userId), query, max_results: limit });
|
|
748
|
+
const r = await this.post("/api/v1/memory/search", { ...extra, ...givenOpts(known), user_id: this.uid(userId), query, max_results: limit });
|
|
738
749
|
return { memories: asRecords(r.memories), self_memories: asRecords(r.self_memories) };
|
|
739
750
|
}
|
|
740
751
|
async searchFull(query, userId, limit = 10, opts = {}) {
|
|
@@ -743,7 +754,7 @@ export class Client {
|
|
|
743
754
|
limit ??= 10;
|
|
744
755
|
checkCount(limit, "limit");
|
|
745
756
|
const { extra, ...known } = opts;
|
|
746
|
-
const r = await this.post("/api/v1/memory/search", { ...extra, ...known, user_id: this.uid(userId), query, max_results: limit });
|
|
757
|
+
const r = await this.post("/api/v1/memory/search", { ...extra, ...givenOpts(known), user_id: this.uid(userId), query, max_results: limit });
|
|
747
758
|
return {
|
|
748
759
|
...r,
|
|
749
760
|
memories: asRecords(r.memories),
|
|
@@ -878,9 +889,13 @@ export class Client {
|
|
|
878
889
|
throw truncatedWalk(`stopped after ${MAX_PAGES} pages — the store did not end.`);
|
|
879
890
|
}
|
|
880
891
|
async revisions(userId, opts = {}) {
|
|
892
|
+
const inc = opts.include;
|
|
893
|
+
if (inc !== undefined && inc !== null && inc !== "revised" && inc !== "unrevised") {
|
|
894
|
+
throw new Error(`include must be "revised" or "unrevised", got ${JSON.stringify(inc)}.`);
|
|
895
|
+
}
|
|
881
896
|
const limit = optRange(opts.limit, "limit", PAGE_LIMIT_MIN, PAGE_LIMIT_MAX);
|
|
882
897
|
const body = {};
|
|
883
|
-
if (opts.include
|
|
898
|
+
if (opts.include != null)
|
|
884
899
|
body.include = opts.include;
|
|
885
900
|
if (limit !== undefined)
|
|
886
901
|
body.limit = limit;
|