wontopos 2.2.43 → 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 +13 -8
- package/dist/cjs/wontopos.d.cts +9 -3
- package/dist/cjs/wontopos.js +34 -12
- package/dist/wontopos.d.ts +9 -3
- package/dist/wontopos.js +32 -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";
|
|
@@ -180,6 +181,10 @@ try {
|
|
|
180
181
|
}
|
|
181
182
|
```
|
|
182
183
|
|
|
184
|
+
A retired model answers `410`, thrown as `GoneError`: retrying cannot succeed, so name a
|
|
185
|
+
live model (`listModels()` lists them, with `retires_at` on one that is scheduled to
|
|
186
|
+
retire). `deleteStore` still works under a retired model.
|
|
187
|
+
|
|
183
188
|
## A different API host
|
|
184
189
|
|
|
185
190
|
Point the client somewhere other than the default endpoint - a dedicated region,
|
|
@@ -202,14 +207,14 @@ Found something wrong, or something that looks unsafe? Tell us — every report
|
|
|
202
207
|
- Security: <https://wontopos.com/contact?topic=security> (also published at
|
|
203
208
|
[`/.well-known/security.txt`](https://wontopos.com/.well-known/security.txt))
|
|
204
209
|
|
|
205
|
-
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
|
|
206
211
|
memory, describe the shape rather than pasting the contents — we do not need your
|
|
207
212
|
data to fix it.
|
|
208
213
|
|
|
209
214
|
## Changelog
|
|
210
215
|
|
|
211
216
|
The three clients release in lockstep — same version, same surface, same day. Patch
|
|
212
|
-
releases are additive.
|
|
217
|
+
releases are additive. Nine inside 2.2 were not, deliberately and each with its
|
|
213
218
|
reason; the changelog lists them.
|
|
214
219
|
|
|
215
220
|
See [CHANGELOG.md](https://github.com/wontopos/wontopos-node/blob/main/CHANGELOG.md).
|
package/dist/cjs/wontopos.d.cts
CHANGED
|
@@ -106,6 +106,11 @@ export declare class ConflictError extends WosError {
|
|
|
106
106
|
readonly conflictsWith?: string;
|
|
107
107
|
constructor(status: number, message: string, requestId?: string, init?: WosErrorInit);
|
|
108
108
|
}
|
|
109
|
+
/** 410 — the model this call named is retired. Retrying cannot succeed: name a live
|
|
110
|
+
* model instead (`listModels()` lists them). `deleteStore` still works under a
|
|
111
|
+
* retired model. */
|
|
112
|
+
export declare class GoneError extends WosError {
|
|
113
|
+
}
|
|
109
114
|
/** 429 — too many requests. Back off and retry (the client already retries these,
|
|
110
115
|
* unless `Retry-After` asks for more than 30 seconds). */
|
|
111
116
|
export declare class RateLimitError extends WosError {
|
|
@@ -647,9 +652,10 @@ export interface SearchOptions {
|
|
|
647
652
|
export interface WriteOptions {
|
|
648
653
|
idempotencyKey?: string;
|
|
649
654
|
/**
|
|
650
|
-
* An image to store alongside the text
|
|
651
|
-
* `
|
|
652
|
-
*
|
|
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.
|
|
653
659
|
*
|
|
654
660
|
* A caption is required: the service refuses empty `content` (400) even with an
|
|
655
661
|
* image attached.
|
package/dist/cjs/wontopos.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WME = exports.Client = exports.ServerError = exports.RateLimitError = 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;
|
|
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})` : "";
|
|
@@ -456,6 +456,9 @@ class ConflictError extends WosError {
|
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
exports.ConflictError = ConflictError;
|
|
459
|
+
class GoneError extends WosError {
|
|
460
|
+
}
|
|
461
|
+
exports.GoneError = GoneError;
|
|
459
462
|
class RateLimitError extends WosError {
|
|
460
463
|
retryAfter;
|
|
461
464
|
constructor(status, message, requestId, init) {
|
|
@@ -468,6 +471,7 @@ exports.RateLimitError = RateLimitError;
|
|
|
468
471
|
class ServerError extends WosError {
|
|
469
472
|
}
|
|
470
473
|
exports.ServerError = ServerError;
|
|
474
|
+
const GONE_HINT = "This model is retired; listModels() lists the ones you can use.";
|
|
471
475
|
const STATUS_ERRORS = {
|
|
472
476
|
400: BadRequestError,
|
|
473
477
|
401: AuthenticationError,
|
|
@@ -475,6 +479,7 @@ const STATUS_ERRORS = {
|
|
|
475
479
|
403: PermissionDeniedError,
|
|
476
480
|
404: NotFoundError,
|
|
477
481
|
409: ConflictError,
|
|
482
|
+
410: GoneError,
|
|
478
483
|
413: BadRequestError,
|
|
479
484
|
422: BadRequestError,
|
|
480
485
|
429: RateLimitError,
|
|
@@ -503,7 +508,7 @@ const KNOWN_ENGRAM_KEYS = new Set(["form", "tz"]);
|
|
|
503
508
|
function checkSearchOpts(opts) {
|
|
504
509
|
checkOpts(opts, KNOWN_SEARCH_KEYS, "search");
|
|
505
510
|
const o = opts;
|
|
506
|
-
optRange(o.max_images
|
|
511
|
+
optRange(o.max_images != null ? o.max_images : o.extra?.max_images, "max_images", 0, MAX_IMAGES_MAX);
|
|
507
512
|
}
|
|
508
513
|
function checkOpts(opts, known, what) {
|
|
509
514
|
for (const k of Object.keys(opts)) {
|
|
@@ -553,6 +558,17 @@ function warnOnceUnknownKeys(obj, known, warned, message) {
|
|
|
553
558
|
console.warn(message(k));
|
|
554
559
|
}
|
|
555
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
|
+
}
|
|
556
572
|
function warnOnUnknownFilters(filters) {
|
|
557
573
|
warnOnceUnknownKeys(filters, KNOWN_FILTER_KEYS, warnedFilterKeys, (k) => `wontopos: unknown search filter ${JSON.stringify(k)} — the API drops keys it does not know, ` +
|
|
558
574
|
`so this filter has NO effect and the search is wider than you think. ` +
|
|
@@ -713,22 +729,22 @@ class Client {
|
|
|
713
729
|
if (opts.image !== undefined)
|
|
714
730
|
body.image = normalizeImage(opts.image);
|
|
715
731
|
warnOnUnknownMetadata(metadata);
|
|
716
|
-
return this.post("/api/v1/memory/store", body, opts
|
|
732
|
+
return this.post("/api/v1/memory/store", body, writeKey(opts, true));
|
|
717
733
|
}
|
|
718
734
|
async store(content, userId, metadata = {}, opts = {}) {
|
|
719
735
|
return this.add(content, userId, metadata, opts);
|
|
720
736
|
}
|
|
721
737
|
async addTurn(userMsg, assistantMsg, userId, opts = {}) {
|
|
722
|
-
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));
|
|
723
739
|
}
|
|
724
740
|
async addBulk(content, userId, category = "general", timestamp, opts = {}) {
|
|
725
|
-
const body = { user_id: this.uid(userId), content, category };
|
|
741
|
+
const body = { user_id: this.uid(userId), content, category: category ?? "general" };
|
|
726
742
|
if (timestamp)
|
|
727
743
|
body.timestamp = timestamp;
|
|
728
|
-
return this.post("/api/v1/memory/bulk-store", body, opts
|
|
744
|
+
return this.post("/api/v1/memory/bulk-store", body, writeKey(opts));
|
|
729
745
|
}
|
|
730
746
|
async update(oldMemoryId, newContent, userId, opts = {}) {
|
|
731
|
-
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));
|
|
732
748
|
}
|
|
733
749
|
async search(query, userId, limit = 10, opts = {}) {
|
|
734
750
|
checkSearchOpts(opts);
|
|
@@ -736,7 +752,7 @@ class Client {
|
|
|
736
752
|
limit ??= 10;
|
|
737
753
|
checkCount(limit, "limit");
|
|
738
754
|
const { extra, ...known } = opts;
|
|
739
|
-
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 });
|
|
740
756
|
return mergeResults(r);
|
|
741
757
|
}
|
|
742
758
|
async searchSelf(query, userId, limit = 10, opts = {}) {
|
|
@@ -745,7 +761,7 @@ class Client {
|
|
|
745
761
|
limit ??= 10;
|
|
746
762
|
checkCount(limit, "limit");
|
|
747
763
|
const { extra, ...known } = opts;
|
|
748
|
-
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 });
|
|
749
765
|
return { memories: asRecords(r.memories), self_memories: asRecords(r.self_memories) };
|
|
750
766
|
}
|
|
751
767
|
async searchFull(query, userId, limit = 10, opts = {}) {
|
|
@@ -754,7 +770,7 @@ class Client {
|
|
|
754
770
|
limit ??= 10;
|
|
755
771
|
checkCount(limit, "limit");
|
|
756
772
|
const { extra, ...known } = opts;
|
|
757
|
-
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 });
|
|
758
774
|
return {
|
|
759
775
|
...r,
|
|
760
776
|
memories: asRecords(r.memories),
|
|
@@ -889,9 +905,13 @@ class Client {
|
|
|
889
905
|
throw truncatedWalk(`stopped after ${MAX_PAGES} pages — the store did not end.`);
|
|
890
906
|
}
|
|
891
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
|
+
}
|
|
892
912
|
const limit = optRange(opts.limit, "limit", PAGE_LIMIT_MIN, PAGE_LIMIT_MAX);
|
|
893
913
|
const body = {};
|
|
894
|
-
if (opts.include
|
|
914
|
+
if (opts.include != null)
|
|
895
915
|
body.include = opts.include;
|
|
896
916
|
if (limit !== undefined)
|
|
897
917
|
body.limit = limit;
|
|
@@ -1072,6 +1092,8 @@ class Client {
|
|
|
1072
1092
|
errorFromAnswer(res, body, retryAfter, mayBeDeleted = false, unread) {
|
|
1073
1093
|
const e = parseErrorText(new TextDecoder().decode(body));
|
|
1074
1094
|
let msg = cleanServerText(e.message) || `HTTP ${res.status}`;
|
|
1095
|
+
if (res.status === 410)
|
|
1096
|
+
msg += ` ${GONE_HINT}`;
|
|
1075
1097
|
if (unread)
|
|
1076
1098
|
msg += ` (the error body could not be read: ${cleanServerText(unread, 512)})`;
|
|
1077
1099
|
const requestId = e.requestId === undefined ? undefined : cleanServerText(e.requestId, 256) || undefined;
|
package/dist/wontopos.d.ts
CHANGED
|
@@ -106,6 +106,11 @@ export declare class ConflictError extends WosError {
|
|
|
106
106
|
readonly conflictsWith?: string;
|
|
107
107
|
constructor(status: number, message: string, requestId?: string, init?: WosErrorInit);
|
|
108
108
|
}
|
|
109
|
+
/** 410 — the model this call named is retired. Retrying cannot succeed: name a live
|
|
110
|
+
* model instead (`listModels()` lists them). `deleteStore` still works under a
|
|
111
|
+
* retired model. */
|
|
112
|
+
export declare class GoneError extends WosError {
|
|
113
|
+
}
|
|
109
114
|
/** 429 — too many requests. Back off and retry (the client already retries these,
|
|
110
115
|
* unless `Retry-After` asks for more than 30 seconds). */
|
|
111
116
|
export declare class RateLimitError extends WosError {
|
|
@@ -647,9 +652,10 @@ export interface SearchOptions {
|
|
|
647
652
|
export interface WriteOptions {
|
|
648
653
|
idempotencyKey?: string;
|
|
649
654
|
/**
|
|
650
|
-
* An image to store alongside the text
|
|
651
|
-
* `
|
|
652
|
-
*
|
|
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.
|
|
653
659
|
*
|
|
654
660
|
* A caption is required: the service refuses empty `content` (400) even with an
|
|
655
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})` : "";
|
|
@@ -443,6 +443,8 @@ export class ConflictError extends WosError {
|
|
|
443
443
|
this.conflictsWith = typeof c === "string" ? c : undefined;
|
|
444
444
|
}
|
|
445
445
|
}
|
|
446
|
+
export class GoneError extends WosError {
|
|
447
|
+
}
|
|
446
448
|
export class RateLimitError extends WosError {
|
|
447
449
|
retryAfter;
|
|
448
450
|
constructor(status, message, requestId, init) {
|
|
@@ -453,6 +455,7 @@ export class RateLimitError extends WosError {
|
|
|
453
455
|
}
|
|
454
456
|
export class ServerError extends WosError {
|
|
455
457
|
}
|
|
458
|
+
const GONE_HINT = "This model is retired; listModels() lists the ones you can use.";
|
|
456
459
|
const STATUS_ERRORS = {
|
|
457
460
|
400: BadRequestError,
|
|
458
461
|
401: AuthenticationError,
|
|
@@ -460,6 +463,7 @@ const STATUS_ERRORS = {
|
|
|
460
463
|
403: PermissionDeniedError,
|
|
461
464
|
404: NotFoundError,
|
|
462
465
|
409: ConflictError,
|
|
466
|
+
410: GoneError,
|
|
463
467
|
413: BadRequestError,
|
|
464
468
|
422: BadRequestError,
|
|
465
469
|
429: RateLimitError,
|
|
@@ -488,7 +492,7 @@ const KNOWN_ENGRAM_KEYS = new Set(["form", "tz"]);
|
|
|
488
492
|
function checkSearchOpts(opts) {
|
|
489
493
|
checkOpts(opts, KNOWN_SEARCH_KEYS, "search");
|
|
490
494
|
const o = opts;
|
|
491
|
-
optRange(o.max_images
|
|
495
|
+
optRange(o.max_images != null ? o.max_images : o.extra?.max_images, "max_images", 0, MAX_IMAGES_MAX);
|
|
492
496
|
}
|
|
493
497
|
function checkOpts(opts, known, what) {
|
|
494
498
|
for (const k of Object.keys(opts)) {
|
|
@@ -538,6 +542,17 @@ function warnOnceUnknownKeys(obj, known, warned, message) {
|
|
|
538
542
|
console.warn(message(k));
|
|
539
543
|
}
|
|
540
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
|
+
}
|
|
541
556
|
function warnOnUnknownFilters(filters) {
|
|
542
557
|
warnOnceUnknownKeys(filters, KNOWN_FILTER_KEYS, warnedFilterKeys, (k) => `wontopos: unknown search filter ${JSON.stringify(k)} — the API drops keys it does not know, ` +
|
|
543
558
|
`so this filter has NO effect and the search is wider than you think. ` +
|
|
@@ -698,22 +713,22 @@ export class Client {
|
|
|
698
713
|
if (opts.image !== undefined)
|
|
699
714
|
body.image = normalizeImage(opts.image);
|
|
700
715
|
warnOnUnknownMetadata(metadata);
|
|
701
|
-
return this.post("/api/v1/memory/store", body, opts
|
|
716
|
+
return this.post("/api/v1/memory/store", body, writeKey(opts, true));
|
|
702
717
|
}
|
|
703
718
|
async store(content, userId, metadata = {}, opts = {}) {
|
|
704
719
|
return this.add(content, userId, metadata, opts);
|
|
705
720
|
}
|
|
706
721
|
async addTurn(userMsg, assistantMsg, userId, opts = {}) {
|
|
707
|
-
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));
|
|
708
723
|
}
|
|
709
724
|
async addBulk(content, userId, category = "general", timestamp, opts = {}) {
|
|
710
|
-
const body = { user_id: this.uid(userId), content, category };
|
|
725
|
+
const body = { user_id: this.uid(userId), content, category: category ?? "general" };
|
|
711
726
|
if (timestamp)
|
|
712
727
|
body.timestamp = timestamp;
|
|
713
|
-
return this.post("/api/v1/memory/bulk-store", body, opts
|
|
728
|
+
return this.post("/api/v1/memory/bulk-store", body, writeKey(opts));
|
|
714
729
|
}
|
|
715
730
|
async update(oldMemoryId, newContent, userId, opts = {}) {
|
|
716
|
-
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));
|
|
717
732
|
}
|
|
718
733
|
async search(query, userId, limit = 10, opts = {}) {
|
|
719
734
|
checkSearchOpts(opts);
|
|
@@ -721,7 +736,7 @@ export class Client {
|
|
|
721
736
|
limit ??= 10;
|
|
722
737
|
checkCount(limit, "limit");
|
|
723
738
|
const { extra, ...known } = opts;
|
|
724
|
-
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 });
|
|
725
740
|
return mergeResults(r);
|
|
726
741
|
}
|
|
727
742
|
async searchSelf(query, userId, limit = 10, opts = {}) {
|
|
@@ -730,7 +745,7 @@ export class Client {
|
|
|
730
745
|
limit ??= 10;
|
|
731
746
|
checkCount(limit, "limit");
|
|
732
747
|
const { extra, ...known } = opts;
|
|
733
|
-
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 });
|
|
734
749
|
return { memories: asRecords(r.memories), self_memories: asRecords(r.self_memories) };
|
|
735
750
|
}
|
|
736
751
|
async searchFull(query, userId, limit = 10, opts = {}) {
|
|
@@ -739,7 +754,7 @@ export class Client {
|
|
|
739
754
|
limit ??= 10;
|
|
740
755
|
checkCount(limit, "limit");
|
|
741
756
|
const { extra, ...known } = opts;
|
|
742
|
-
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 });
|
|
743
758
|
return {
|
|
744
759
|
...r,
|
|
745
760
|
memories: asRecords(r.memories),
|
|
@@ -874,9 +889,13 @@ export class Client {
|
|
|
874
889
|
throw truncatedWalk(`stopped after ${MAX_PAGES} pages — the store did not end.`);
|
|
875
890
|
}
|
|
876
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
|
+
}
|
|
877
896
|
const limit = optRange(opts.limit, "limit", PAGE_LIMIT_MIN, PAGE_LIMIT_MAX);
|
|
878
897
|
const body = {};
|
|
879
|
-
if (opts.include
|
|
898
|
+
if (opts.include != null)
|
|
880
899
|
body.include = opts.include;
|
|
881
900
|
if (limit !== undefined)
|
|
882
901
|
body.limit = limit;
|
|
@@ -1057,6 +1076,8 @@ export class Client {
|
|
|
1057
1076
|
errorFromAnswer(res, body, retryAfter, mayBeDeleted = false, unread) {
|
|
1058
1077
|
const e = parseErrorText(new TextDecoder().decode(body));
|
|
1059
1078
|
let msg = cleanServerText(e.message) || `HTTP ${res.status}`;
|
|
1079
|
+
if (res.status === 410)
|
|
1080
|
+
msg += ` ${GONE_HINT}`;
|
|
1060
1081
|
if (unread)
|
|
1061
1082
|
msg += ` (the error body could not be read: ${cleanServerText(unread, 512)})`;
|
|
1062
1083
|
const requestId = e.requestId === undefined ? undefined : cleanServerText(e.requestId, 256) || undefined;
|