wontopos 2.2.16 → 2.2.18

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.
@@ -171,6 +171,13 @@ export interface MemoryPage {
171
171
  next_cursor: string | null;
172
172
  [key: string]: unknown;
173
173
  }
174
+ /** `searchSelf` result: the main lane plus the assistant's own words, split. */
175
+ export interface SelfSearchResult {
176
+ /** Main lane — what others said / general memories. */
177
+ memories: Memory[];
178
+ /** The assistant's own words (stored with speaker "me"); `[]` on non-self models. */
179
+ self_memories: Memory[];
180
+ }
174
181
  export interface ModelInfo {
175
182
  id: string;
176
183
  name: string;
@@ -273,7 +280,7 @@ export declare class Client {
273
280
  withTimeout(timeoutMs: number): Client;
274
281
  /** A client with a different retry budget (everything else kept). 0 disables retries. */
275
282
  withRetries(maxRetries: number): Client;
276
- /** Store one memory. `metadata` optional (e.g. { event_date: "2026-03-01" }).
283
+ /** Store one memory. `metadata` optional (e.g. { event_date: "2026-03-01T00:00:00Z" } — RFC3339).
277
284
  * `metadata.speaker`: "me" = the assistant's own words, or a person's name (up to 50 per store). */
278
285
  add(content: string, userId?: string, metadata?: Record<string, unknown>): Promise<StoreResult>;
279
286
  /** Alias of `add` — store one memory. Same surface as the Python SDK's `store`. */
@@ -286,6 +293,12 @@ export declare class Client {
286
293
  update(oldMemoryId: string, newContent: string, userId?: string): Promise<UpdateResult>;
287
294
  /** Semantic search over a store's memories. Returns memories, most relevant first. */
288
295
  search(query: string, userId?: string, limit?: number, opts?: SearchOptions): Promise<Memory[]>;
296
+ /** Search a self-memory model (Scroll 1.2+): both lanes from ONE call. Returns
297
+ * `{ memories, self_memories }` — `memories` is the main lane (what others said /
298
+ * general memories), `self_memories` is the assistant's OWN words (stored with
299
+ * speaker "me"), kept separate so the reader never confuses who said what. On a model
300
+ * without a self lane, `self_memories` is `[]`. `userId` optional (default store). */
301
+ searchSelf(query: string, userId?: string, limit?: number, opts?: SearchOptions): Promise<SelfSearchResult>;
289
302
  /** One-call LLM context: short-term turns + long-term matches + surrounding context. */
290
303
  recall(query: string, userId?: string): Promise<RecallResult>;
291
304
  /** Run a built-in engram ("deep_recall" | "timeline" | "gather"). Returns the merged result. */
package/dist/wontopos.js CHANGED
@@ -37,7 +37,7 @@
37
37
  * runtime's (never disabled by this SDK; Node 18+ floors TLS at 1.2). Prefer
38
38
  * `Client.fromEnv()` over keys in source code.
39
39
  */
40
- const VERSION = "2.2.16";
40
+ const VERSION = "2.2.17";
41
41
  /** Runtime info helps support debug a report ("node 18 on Windows...") —
42
42
  * platform only, never anything identifying. Browsers have no `process` (and
43
43
  * silently drop the UA header anyway). */
@@ -298,7 +298,7 @@ export class Client {
298
298
  // ----- write -----
299
299
  // `userId` is optional in every call below - omit it to use the client's default
300
300
  // store (set via `new Client({ apiKey, userId })` or `withUser`).
301
- /** Store one memory. `metadata` optional (e.g. { event_date: "2026-03-01" }).
301
+ /** Store one memory. `metadata` optional (e.g. { event_date: "2026-03-01T00:00:00Z" } — RFC3339).
302
302
  * `metadata.speaker`: "me" = the assistant's own words, or a person's name (up to 50 per store). */
303
303
  add(content, userId, metadata = {}) {
304
304
  return this.post("/api/v1/memory/store", { user_id: this.uid(userId), content, metadata });
@@ -330,6 +330,15 @@ export class Client {
330
330
  const r = await this.post("/api/v1/memory/search", { ...opts, user_id: this.uid(userId), query, max_results: limit });
331
331
  return (r.memories ?? []);
332
332
  }
333
+ /** Search a self-memory model (Scroll 1.2+): both lanes from ONE call. Returns
334
+ * `{ memories, self_memories }` — `memories` is the main lane (what others said /
335
+ * general memories), `self_memories` is the assistant's OWN words (stored with
336
+ * speaker "me"), kept separate so the reader never confuses who said what. On a model
337
+ * without a self lane, `self_memories` is `[]`. `userId` optional (default store). */
338
+ async searchSelf(query, userId, limit = 10, opts = {}) {
339
+ const r = await this.post("/api/v1/memory/search", { ...opts, user_id: this.uid(userId), query, max_results: limit });
340
+ return { memories: (r.memories ?? []), self_memories: (r.self_memories ?? []) };
341
+ }
333
342
  /** One-call LLM context: short-term turns + long-term matches + surrounding context. */
334
343
  recall(query, userId) {
335
344
  return this.post("/api/v1/memory/recall", { user_id: this.uid(userId), query });
@@ -625,15 +634,24 @@ export class Client {
625
634
  throw errorFor(res.status, msg, requestId);
626
635
  }
627
636
  if (!text)
628
- return null;
637
+ return {};
638
+ let data;
629
639
  try {
630
- return JSON.parse(text);
640
+ data = JSON.parse(text);
631
641
  }
632
642
  catch (e) {
633
643
  // A 2xx with a corrupt body is a real failure — surface it, don't leak
634
644
  // a raw SyntaxError (parity with the Rust SDK).
635
645
  throw new WosError(res.status, `invalid JSON in response: ${e?.message ?? e}`);
636
646
  }
647
+ // Enforce a JSON OBJECT: every method reads the result with `.field`, so a
648
+ // body that parses to null / a number / a string / an array (a broken or
649
+ // hostile server) must be a clean WosError, not a `null.memories` TypeError.
650
+ if (data === null || typeof data !== "object" || Array.isArray(data)) {
651
+ const got = data === null ? "null" : Array.isArray(data) ? "array" : typeof data;
652
+ throw new WosError(res.status, `expected a JSON object in the response, got ${got}`);
653
+ }
654
+ return data;
637
655
  }
638
656
  throw new WosError(0, "retries exhausted"); // unreachable; keeps the compiler happy
639
657
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wontopos",
3
- "version": "2.2.16",
3
+ "version": "2.2.18",
4
4
  "description": "Wontopos — long-term memory for AI agents. Pure semantic retrieval, identical recall in every language, ~100× lower LLM bill.",
5
5
  "keywords": [
6
6
  "memory",