wontopos 2.1.1 → 2.2.1
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/dist/wontopos.d.ts +48 -16
- package/dist/wontopos.js +69 -23
- package/package.json +1 -1
package/dist/wontopos.d.ts
CHANGED
|
@@ -4,9 +4,15 @@
|
|
|
4
4
|
* npm install wontopos
|
|
5
5
|
*
|
|
6
6
|
* import { Client } from "wontopos";
|
|
7
|
-
* const mem = new Client({ apiKey: "wos-...",
|
|
8
|
-
* await mem.
|
|
9
|
-
*
|
|
7
|
+
* const mem = new Client({ apiKey: "wos-...", userId: "alice" }); // set the store once
|
|
8
|
+
* await mem.createStore(); // create it (uses the client's userId)
|
|
9
|
+
* await mem.add("she prefers tea over coffee"); // no userId needed
|
|
10
|
+
* const hits = await mem.search("what does alice drink?");
|
|
11
|
+
*
|
|
12
|
+
* Set `userId` once on the client and every call uses it; override any single call
|
|
13
|
+
* by passing `userId` to it. Stores are explicit: the store must exist first
|
|
14
|
+
* (`createStore`) or calls return 404. Every account starts with a `default` store,
|
|
15
|
+
* so with no `userId` anywhere the zero-setup path just works.
|
|
10
16
|
*
|
|
11
17
|
* The API key picks *which memory* (your account); `model` picks *which engine*
|
|
12
18
|
* reads it. All models share one memory, so you can store
|
|
@@ -56,6 +62,9 @@ export interface ClientOptions {
|
|
|
56
62
|
timeoutMs?: number;
|
|
57
63
|
/** Default model for every call (sent as `X-WOS-Model`). See `listModels()`. */
|
|
58
64
|
model?: string;
|
|
65
|
+
/** Default store for every call. Override per call by passing `userId`. Defaults
|
|
66
|
+
* to the account's built-in `default` store. */
|
|
67
|
+
userId?: string;
|
|
59
68
|
}
|
|
60
69
|
/** Wontopos memory client. Store and recall memories, isolated per `userId`. */
|
|
61
70
|
export declare class Client {
|
|
@@ -63,36 +72,59 @@ export declare class Client {
|
|
|
63
72
|
private readonly headers;
|
|
64
73
|
private readonly timeoutMs;
|
|
65
74
|
private readonly apiKey;
|
|
75
|
+
private readonly model;
|
|
76
|
+
/** The store every call uses unless one passes `userId`. */
|
|
77
|
+
private readonly defaultUser;
|
|
66
78
|
constructor(opts: ClientOptions);
|
|
79
|
+
/** Resolve a call's store: the explicit userId, else the client default. */
|
|
80
|
+
private uid;
|
|
67
81
|
/**
|
|
68
82
|
* A client that uses `model` (sent as `X-WOS-Model`). Use it to set the default
|
|
69
83
|
* (`new Client({ apiKey, model })`) or to override one call
|
|
70
84
|
* (`client.withModel("tablet-1").recall(...)`).
|
|
71
85
|
*/
|
|
72
86
|
withModel(model: string): Client;
|
|
87
|
+
/** A client bound to `userId` as its default store (everything else kept). */
|
|
88
|
+
withUser(userId: string): Client;
|
|
73
89
|
/** Store one memory. `metadata` optional (e.g. { event_date: "2026-03-01" }). */
|
|
74
|
-
add(content: string, userId
|
|
90
|
+
add(content: string, userId?: string, metadata?: Record<string, unknown>): Promise<any>;
|
|
75
91
|
/** Store a conversation turn (user + assistant) into short-term + long-term memory. */
|
|
76
|
-
addTurn(userId: string, userMsg: string, assistantMsg: string): Promise<any>;
|
|
92
|
+
addTurn(userId: string | undefined, userMsg: string, assistantMsg: string): Promise<any>;
|
|
77
93
|
/** Bulk-ingest a large blob of text (chunked + embedded server-side). For backfilling. */
|
|
78
|
-
addBulk(content: string, userId
|
|
94
|
+
addBulk(content: string, userId?: string, category?: string, timestamp?: string): Promise<any>;
|
|
79
95
|
/** Supersede an old memory with new content (a fact that changed). */
|
|
80
|
-
update(userId: string, oldMemoryId: string, newContent: string): Promise<any>;
|
|
81
|
-
/** Semantic search over a
|
|
82
|
-
search(query: string, userId
|
|
96
|
+
update(userId: string | undefined, oldMemoryId: string, newContent: string): Promise<any>;
|
|
97
|
+
/** Semantic search over a store's memories. Returns memories, most relevant first. */
|
|
98
|
+
search(query: string, userId?: string, limit?: number, opts?: Record<string, unknown>): Promise<Memory[]>;
|
|
83
99
|
/** One-call LLM context: short-term turns + long-term matches + surrounding context. */
|
|
84
|
-
recall(query: string, userId
|
|
100
|
+
recall(query: string, userId?: string): Promise<RecallResult>;
|
|
101
|
+
/** Run a built-in engram ("deep_recall" | "timeline" | "gather"). Returns the merged result. */
|
|
102
|
+
engram(name: string, query: string, userId?: string): Promise<any>;
|
|
85
103
|
/** Recent conversation turns (short-term memory). */
|
|
86
|
-
history(userId
|
|
87
|
-
/** Memory counts for a
|
|
88
|
-
stats(userId
|
|
104
|
+
history(userId?: string): Promise<unknown[]>;
|
|
105
|
+
/** Memory counts for a store: { total_memories, short_term_turns }. */
|
|
106
|
+
stats(userId?: string): Promise<any>;
|
|
89
107
|
/** Available models: `[{ id, name, available, memory }, ...]`. Needs no API key. */
|
|
90
108
|
listModels(): Promise<ModelInfo[]>;
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
/** Create a store — the `userId` you read and write under. Stores are explicit:
|
|
110
|
+
* a store must exist before you `add` to or `search` it, otherwise those calls
|
|
111
|
+
* return 404. Idempotent. Every account starts with a `default` store.
|
|
112
|
+
* Returns `{ user_id, status }` (`status` is `"created"` or `"exists"`). */
|
|
113
|
+
createStore(userId?: string): Promise<any>;
|
|
114
|
+
/** List your stores: `[{ user_id, created_at }, ...]` (`default` first). */
|
|
115
|
+
listStores(): Promise<Array<{
|
|
116
|
+
user_id: string;
|
|
117
|
+
created_at: string;
|
|
118
|
+
}>>;
|
|
119
|
+
/** Delete a store and ALL its memories. Returns `{ user_id, status }`. */
|
|
120
|
+
deleteStore(userId: string): Promise<any>;
|
|
121
|
+
/** Delete a single memory by id. `userId` optional (uses the default store). */
|
|
122
|
+
delete(userId: string | undefined, memoryId: string): Promise<any>;
|
|
123
|
+
/** Delete ALL memories for a store (GDPR erase). `userId` is required on purpose -
|
|
124
|
+
* this is destructive, so it never falls back to the default store. */
|
|
94
125
|
deleteAll(userId: string): Promise<any>;
|
|
95
126
|
private post;
|
|
127
|
+
private request;
|
|
96
128
|
}
|
|
97
129
|
/** Back-compat alias: older code used `WME`. */
|
|
98
130
|
export declare const WME: typeof Client;
|
package/dist/wontopos.js
CHANGED
|
@@ -4,9 +4,15 @@
|
|
|
4
4
|
* npm install wontopos
|
|
5
5
|
*
|
|
6
6
|
* import { Client } from "wontopos";
|
|
7
|
-
* const mem = new Client({ apiKey: "wos-...",
|
|
8
|
-
* await mem.
|
|
9
|
-
*
|
|
7
|
+
* const mem = new Client({ apiKey: "wos-...", userId: "alice" }); // set the store once
|
|
8
|
+
* await mem.createStore(); // create it (uses the client's userId)
|
|
9
|
+
* await mem.add("she prefers tea over coffee"); // no userId needed
|
|
10
|
+
* const hits = await mem.search("what does alice drink?");
|
|
11
|
+
*
|
|
12
|
+
* Set `userId` once on the client and every call uses it; override any single call
|
|
13
|
+
* by passing `userId` to it. Stores are explicit: the store must exist first
|
|
14
|
+
* (`createStore`) or calls return 404. Every account starts with a `default` store,
|
|
15
|
+
* so with no `userId` anywhere the zero-setup path just works.
|
|
10
16
|
*
|
|
11
17
|
* The API key picks *which memory* (your account); `model` picks *which engine*
|
|
12
18
|
* reads it. All models share one memory, so you can store
|
|
@@ -26,22 +32,31 @@ export class WosError extends Error {
|
|
|
26
32
|
this.status = status;
|
|
27
33
|
}
|
|
28
34
|
}
|
|
35
|
+
const DEFAULT_USER = "default";
|
|
29
36
|
/** Wontopos memory client. Store and recall memories, isolated per `userId`. */
|
|
30
37
|
export class Client {
|
|
31
38
|
base;
|
|
32
39
|
headers;
|
|
33
40
|
timeoutMs;
|
|
34
41
|
apiKey;
|
|
42
|
+
model;
|
|
43
|
+
/** The store every call uses unless one passes `userId`. */
|
|
44
|
+
defaultUser;
|
|
35
45
|
constructor(opts) {
|
|
36
46
|
if (!opts?.apiKey)
|
|
37
47
|
throw new Error("apiKey is required");
|
|
38
48
|
this.apiKey = opts.apiKey;
|
|
39
49
|
this.base = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
40
50
|
this.timeoutMs = opts.timeoutMs ?? 30_000;
|
|
41
|
-
|
|
51
|
+
this.model = opts.model ?? DEFAULT_MODEL;
|
|
52
|
+
this.defaultUser = opts.userId || DEFAULT_USER;
|
|
42
53
|
this.headers = { "X-API-Key": opts.apiKey, "Content-Type": "application/json" };
|
|
43
|
-
if (model)
|
|
44
|
-
this.headers["X-WOS-Model"] = model;
|
|
54
|
+
if (this.model)
|
|
55
|
+
this.headers["X-WOS-Model"] = this.model;
|
|
56
|
+
}
|
|
57
|
+
/** Resolve a call's store: the explicit userId, else the client default. */
|
|
58
|
+
uid(userId) {
|
|
59
|
+
return userId || this.defaultUser;
|
|
45
60
|
}
|
|
46
61
|
/**
|
|
47
62
|
* A client that uses `model` (sent as `X-WOS-Model`). Use it to set the default
|
|
@@ -49,46 +64,56 @@ export class Client {
|
|
|
49
64
|
* (`client.withModel("tablet-1").recall(...)`).
|
|
50
65
|
*/
|
|
51
66
|
withModel(model) {
|
|
52
|
-
return new Client({ apiKey: this.apiKey, baseUrl: this.base, timeoutMs: this.timeoutMs, model });
|
|
67
|
+
return new Client({ apiKey: this.apiKey, baseUrl: this.base, timeoutMs: this.timeoutMs, model, userId: this.defaultUser });
|
|
68
|
+
}
|
|
69
|
+
/** A client bound to `userId` as its default store (everything else kept). */
|
|
70
|
+
withUser(userId) {
|
|
71
|
+
return new Client({ apiKey: this.apiKey, baseUrl: this.base, timeoutMs: this.timeoutMs, model: this.model, userId });
|
|
53
72
|
}
|
|
54
73
|
// ----- write -----
|
|
74
|
+
// `userId` is optional in every call below - omit it to use the client's default
|
|
75
|
+
// store (set via `new Client({ apiKey, userId })` or `withUser`).
|
|
55
76
|
/** Store one memory. `metadata` optional (e.g. { event_date: "2026-03-01" }). */
|
|
56
77
|
add(content, userId, metadata = {}) {
|
|
57
|
-
return this.post("/api/v1/memory/store", { user_id: userId, content, metadata });
|
|
78
|
+
return this.post("/api/v1/memory/store", { user_id: this.uid(userId), content, metadata });
|
|
58
79
|
}
|
|
59
80
|
/** Store a conversation turn (user + assistant) into short-term + long-term memory. */
|
|
60
81
|
addTurn(userId, userMsg, assistantMsg) {
|
|
61
|
-
return this.post("/api/v1/memory/store-turn", { user_id: userId, user_msg: userMsg, assistant_msg: assistantMsg });
|
|
82
|
+
return this.post("/api/v1/memory/store-turn", { user_id: this.uid(userId), user_msg: userMsg, assistant_msg: assistantMsg });
|
|
62
83
|
}
|
|
63
84
|
/** Bulk-ingest a large blob of text (chunked + embedded server-side). For backfilling. */
|
|
64
85
|
addBulk(content, userId, category = "general", timestamp) {
|
|
65
|
-
const body = { user_id: userId, content, category };
|
|
86
|
+
const body = { user_id: this.uid(userId), content, category };
|
|
66
87
|
if (timestamp)
|
|
67
88
|
body.timestamp = timestamp;
|
|
68
89
|
return this.post("/api/v1/memory/bulk-store", body);
|
|
69
90
|
}
|
|
70
91
|
/** Supersede an old memory with new content (a fact that changed). */
|
|
71
92
|
update(userId, oldMemoryId, newContent) {
|
|
72
|
-
return this.post("/api/v1/memory/supersede", { user_id: userId, old_memory_id: oldMemoryId, new_content: newContent });
|
|
93
|
+
return this.post("/api/v1/memory/supersede", { user_id: this.uid(userId), old_memory_id: oldMemoryId, new_content: newContent });
|
|
73
94
|
}
|
|
74
95
|
// ----- read -----
|
|
75
|
-
/** Semantic search over a
|
|
96
|
+
/** Semantic search over a store's memories. Returns memories, most relevant first. */
|
|
76
97
|
async search(query, userId, limit = 10, opts = {}) {
|
|
77
|
-
const r = await this.post("/api/v1/memory/search", { user_id: userId, query, max_results: limit, ...opts });
|
|
98
|
+
const r = await this.post("/api/v1/memory/search", { user_id: this.uid(userId), query, max_results: limit, ...opts });
|
|
78
99
|
return (r.memories ?? []);
|
|
79
100
|
}
|
|
80
101
|
/** One-call LLM context: short-term turns + long-term matches + surrounding context. */
|
|
81
102
|
recall(query, userId) {
|
|
82
|
-
return this.post("/api/v1/memory/recall", { user_id: userId, query });
|
|
103
|
+
return this.post("/api/v1/memory/recall", { user_id: this.uid(userId), query });
|
|
104
|
+
}
|
|
105
|
+
/** Run a built-in engram ("deep_recall" | "timeline" | "gather"). Returns the merged result. */
|
|
106
|
+
engram(name, query, userId) {
|
|
107
|
+
return this.post("/api/v1/engram/run", { name, user_id: this.uid(userId), query });
|
|
83
108
|
}
|
|
84
109
|
/** Recent conversation turns (short-term memory). */
|
|
85
110
|
async history(userId) {
|
|
86
|
-
const r = await this.post("/api/v1/memory/history", { user_id: userId });
|
|
111
|
+
const r = await this.post("/api/v1/memory/history", { user_id: this.uid(userId) });
|
|
87
112
|
return (r.turns ?? []);
|
|
88
113
|
}
|
|
89
|
-
/** Memory counts for a
|
|
114
|
+
/** Memory counts for a store: { total_memories, short_term_turns }. */
|
|
90
115
|
stats(userId) {
|
|
91
|
-
return this.post("/api/v1/memory/stats", { user_id: userId });
|
|
116
|
+
return this.post("/api/v1/memory/stats", { user_id: this.uid(userId) });
|
|
92
117
|
}
|
|
93
118
|
// ----- models -----
|
|
94
119
|
/** Available models: `[{ id, name, available, memory }, ...]`. Needs no API key. */
|
|
@@ -99,25 +124,46 @@ export class Client {
|
|
|
99
124
|
const data = await res.json();
|
|
100
125
|
return (data.models ?? []);
|
|
101
126
|
}
|
|
127
|
+
// ----- stores -----
|
|
128
|
+
/** Create a store — the `userId` you read and write under. Stores are explicit:
|
|
129
|
+
* a store must exist before you `add` to or `search` it, otherwise those calls
|
|
130
|
+
* return 404. Idempotent. Every account starts with a `default` store.
|
|
131
|
+
* Returns `{ user_id, status }` (`status` is `"created"` or `"exists"`). */
|
|
132
|
+
createStore(userId) {
|
|
133
|
+
return this.post("/api/v1/memory/collection", { user_id: this.uid(userId) });
|
|
134
|
+
}
|
|
135
|
+
/** List your stores: `[{ user_id, created_at }, ...]` (`default` first). */
|
|
136
|
+
async listStores() {
|
|
137
|
+
const r = await this.request("GET", "/api/v1/memory/collections");
|
|
138
|
+
return (r.collections ?? []);
|
|
139
|
+
}
|
|
140
|
+
/** Delete a store and ALL its memories. Returns `{ user_id, status }`. */
|
|
141
|
+
deleteStore(userId) {
|
|
142
|
+
return this.request("DELETE", "/api/v1/memory/collection", { user_id: userId });
|
|
143
|
+
}
|
|
102
144
|
// ----- delete -----
|
|
103
|
-
/** Delete a single memory by id. */
|
|
145
|
+
/** Delete a single memory by id. `userId` optional (uses the default store). */
|
|
104
146
|
delete(userId, memoryId) {
|
|
105
|
-
return this.post("/api/v1/memory/forget", { user_id: userId, memory_id: memoryId });
|
|
147
|
+
return this.post("/api/v1/memory/forget", { user_id: this.uid(userId), memory_id: memoryId });
|
|
106
148
|
}
|
|
107
|
-
/** Delete ALL memories for a
|
|
149
|
+
/** Delete ALL memories for a store (GDPR erase). `userId` is required on purpose -
|
|
150
|
+
* this is destructive, so it never falls back to the default store. */
|
|
108
151
|
deleteAll(userId) {
|
|
109
152
|
return this.post("/api/v1/memory/forget", { user_id: userId });
|
|
110
153
|
}
|
|
111
154
|
// ----- internal -----
|
|
112
|
-
|
|
155
|
+
post(path, body) {
|
|
156
|
+
return this.request("POST", path, body);
|
|
157
|
+
}
|
|
158
|
+
async request(method, path, body) {
|
|
113
159
|
const ctrl = new AbortController();
|
|
114
160
|
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
115
161
|
let res;
|
|
116
162
|
try {
|
|
117
163
|
res = await fetch(`${this.base}${path}`, {
|
|
118
|
-
method
|
|
164
|
+
method,
|
|
119
165
|
headers: this.headers,
|
|
120
|
-
body: JSON.stringify(body),
|
|
166
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
121
167
|
signal: ctrl.signal,
|
|
122
168
|
});
|
|
123
169
|
}
|
package/package.json
CHANGED