Warum WOS

Langzeitgedächtnis für KI-Agenten.

WOS ist eine Memory-API. Sie speichern die Erinnerungen eines Nutzers einmal, rufen dann zu jeder Abfrage nur die relevanten ab und übergeben sie an den Prompt Ihres Modells.

Der Abruf ist rein semantisch, ohne Keyword- oder BM25-Matching, daher ist die Recall-Qualität in allen Sprachen identisch. Jede Abfrage liefert einen kleinen, begrenzten Kontext zurück, unabhängig davon, wie viel Sie gespeichert haben, und über Ihre gespeicherten Erinnerungen läuft niemals ein Modell.

Kernoperationen

  • store - speichert eine Erinnerung für einen Nutzer.
  • recall - liefert die relevanten Erinnerungen zu einer Abfrage. Dies ist der zentrale Aufruf.
  • search - rohe semantische Suche über gespeicherte Erinnerungen.
  • supersede - aktualisiert oder ersetzt eine veraltete Erinnerung.
  • forget - löscht eine einzelne Erinnerung oder einen ganzen Nutzer (DSGVO).
Wählen Sie links einen Abschnitt für Details zu jedem Thema.
Modell

Drei Modelle, eine Linie.

WOS-Modelle sind danach benannt, wie Menschen im Lauf der Geschichte Wissen bewahrt haben - Tablet, Scroll, Codex. Steintafel, Schriftrolle, gebundenes Buch: Jedes leistet mehr für Ihren Agenten als das vorherige.

Tablet

Live
In Stein gemeißelt · store & recall

Eine schlanke, schnelle und kostengünstige Art, Erinnerungen einzuschreiben und abzurufen - das Fundament, auf dem jedes Modell aufbaut.

Scroll

Live
Entrollt · LLM-gestützter Abruf

Ergänzt ein Sprachmodell, das Ihre Frage genauer liest und einen vollständigeren Kontext zurückbringt - verstreute Belege kommen so wieder zusammen, statt dass ein Teil fehlt.

Codex

Demnächst
Gebunden & indexiert · selbststeuernd

Schlägt von selbst die richtige Seite auf - wählt in jedem Moment das passende Gedächtnis und die passenden Werkzeuge und wird mit jeder Nutzung schärfer.

Der vollständige Benchmark-Bericht zu Tablet 1 steht auf der Benchmark-Seite.

Kosten

Zahlen Sie uns $2. Sparen Sie ein Vielfaches davon bei Ihrem LLM.

WOS führt Ihrem LLM ~1.200 Tokens pro Abfrage zu - einen begrenzten, relevanten Ausschnitt - statt die gesamte Historie in jeden Prompt zu stopfen. Der Abstand ist enorm und wächst mit Ihrer Historie.

LLM-Kosten pro 1.000 Abfragen Basierend auf Tablet 1
Nutzerhistorie100K
Abfragen / Monat1,000
Ihr LLM
45× günstiger - Sie sparen $244/Monat
Ohne WOS$250.00
Mit WOS$5.50

Jeder für WOS ausgegebene $1 spart ~$98 beim LLM. Größere Historie oder ein teureres Modell → größerer ROI.

Woher die Einsparungen kommen

  • Ohne WOS packen Sie die gesamte Historie in jeden Prompt - 100K tokens × $2.50/1M = $0.25 pro Abfrage, zu GPT-4o-Eingabepreisen (bei Modellen der Opus-Klasse etwa das Doppelte).
  • Mit WOS nehmen Sie die Daten einmal auf ($2/1M); danach ist jede Abfrage ein winziger Abruf ($3/1M × 1,200) plus Ihr LLM auf nur ~1.200 Tokens.
  • Je weniger Tokens Ihr LLM liest, desto weniger zahlen Sie - und WOS hält diese Zahl konstant, während das Gedächtnis wächst.
Kontext-Verkleinerung = Historie ÷ zugeführte Tokens, nicht Kosten (der Rechner oben bepreist jeden Abruf).  25K → 21× · 100K → 83× · 200K → 167×.
Mehrsprachigkeit

Jede Sprache, dieselbe Genauigkeit.

Der Abruf ist rein semantisch - ausschließlich Embeddings, null Keyword- oder BM25-Matching. Die Recall-Qualität ist daher identisch, ob Ihre Nutzer auf 日本語, 中文, Español oder Englisch schreiben.

Lexikalisches Matching wie BM25 ist auf die Gestalt einer bestimmten Sprache abgestimmt - Morphologie, Leerzeichen, Schriftsystem. In einem mehrsprachigen Store heißt das: Die Abrufqualität variiert je nach Sprache. WOS verwendet überhaupt kein lexikalisches Matching, sodass jede Sprache denselben Weg nimmt.

Ein Store, drei Sprachen zugleich

Sie wählen keine Sprache pro Store - mischen Sie frei. Unten enthält das Gedächtnis eines Nutzers gleichzeitig Japanisch, Englisch und Spanisch, und jede Frage findet die richtige Erinnerung, unabhängig von der Sprache. Dies ist ein echter Austausch mit der Live-API:

# one user, three languages stored together
mem.add("彼女はコーヒーより紅茶が好き", user_id="alice")                      # Japanese
mem.add("she works at a design studio in Brooklyn", user_id="alice")       # English
mem.add("A ella le encanta hacer senderismo los sábados", user_id="alice")  # Spanish
Tatsächliche Ergebnisse - jede Frage wechselt in eine andere Sprache
"¿Qué bebe ella?"               -> 彼女はコーヒーより紅茶が好き
"what does she do on weekends?" -> A ella le encanta hacer senderismo los sábados
"彼女の仕事は?"                  -> she works at a design studio in Brooklyn

Kein Übersetzungsschritt, keine Spracherkennung, keine Konfiguration pro Sprache. Erinnerungen und Fragen werden nach Bedeutung eingeordnet, nicht nach Sprache - passt die Bedeutung, spielt die Sprache keine Rolle.

Drei Sprachen sind hier nur das, was auf eine Seite passt - es gibt keine Liste unterstützter Sprachen, auf der man stehen müsste. Derselbe Live-Test besteht auch mit Erinnerungen auf 中文, Русский und العربية, alle gegen die Produktions-API verifiziert.

Warum wir Keywords bewusst verbannt haben

Lexikalisches Scoring wie BM25 stärkt den Abruf für manche Sprachen mehr als für andere - hinderlich, wenn ein Store viele Sprachen enthält. Wir haben es daher vollständig aus der Engine entfernt und setzen diese Regel im Code-Review durch: Mit jeglichem lexikalischem Scoring im Pfad würde die Recall-Qualität je nach Sprache abweichen.

LongMemEval ist rein englischsprachig und misst daher keinen mehrsprachigen Recall. Die Demo oben zeigt, wie Sie ihn direkt gegen die Live-API verifizieren können.
Architektur

Kein Modell läuft über Ihre Erinnerungen.

Die Speicherung erfolgt wortgetreu, und die Engine sucht über Embeddings - günstig, schnell und deterministisch. Über Ihre gespeicherten Erinnerungen läuft niemals ein Modell. Tablet verwendet gar kein Modell; Scroll und Codex setzen für stärkere Ergebnisse eines um die Engine herum ein, doch es sieht immer nur Ihre Abfrage, nie das, was Sie gespeichert haben.

  • Deterministische Engine. Die Engine liefert für dieselbe Abfrage jedes Mal dieselben Erinnerungen - deshalb stammt die Varianz in unserem Benchmark allein vom Reader-Modell.
  • Günstig im großen Maßstab. Keine Generierungskosten beim Speichern oder Abrufen - Ihre Rechnung folgt dem Speicherplatz, nicht der Modellnutzung, während das Gedächtnis wächst.

Ihre Worte, unangetastet

Ein verbreitetes Design lässt beim Schreiben ein Sprachmodell laufen, um "Fakten" aus dem Text zu extrahieren und umzuschreiben. Dieses Design bezahlt dreifach: Generierungskosten bei jedem Schreibvorgang, zusätzliche Latenz und die Speicherung der Paraphrase eines Modells statt der ursprünglichen Worte. WOS trifft die entgegengesetzte Wahl - es speichert das Gesagte unverändert und lässt Ihr LLM die Interpretation zur Lesezeit übernehmen, mit dem Originaltext in der Hand.

Was WOS nicht ist: keine Vektor-Datenbank, die Sie betreiben müssen, und kein RAG-Framework, das Sie zusammenbauen müssen. Über Ihre gespeicherten Daten läuft niemals ein Modell - dieser Pfad besteht rein aus Embeddings. Scroll und Codex nutzen zwar ein Sprachmodell für stärkere Ergebnisse, doch es sieht immer nur Ihre Abfrage, nie Ihre gespeicherten Erinnerungen - und es trainiert niemals auf Ihren Daten oder sammelt sie.
Nachweis

90.7%, gemessen und reproduzierbar.

90.7% auf LongMemEval-S, gemittelt über 5 unabhängige Läufe (σ 0.5%, keiner handverlesen), bewertet vom kanonischen GPT-4o-Judge des Benchmarks.

Auf demselben Benchmark schwanken die Ergebnisse stark mit dem Bewertungsprotokoll - dem Judge, dem Prompt und dem, was die Abrufschicht tun darf. Wir verwenden den kanonischen GPT-4o-Judge des Benchmarks von dritter Seite wie veröffentlicht, passen nichts an den Test an und veröffentlichen den Bewertungscode und den Reader-Prompt, sodass jeder die 90.7% exakt reproduzieren kann.

Das Protokoll in einer Tabelle

PunktUnser Vorgehen
DatensatzLongMemEval-S (bereinigt), ~240K Tokens Historie pro Frage
JudgeDer kanonische GPT-4o-Judge des Benchmarks - eine dritte Partei, nicht wir
Läufe5 unabhängige Läufe, jeder Wert veröffentlicht, Mittelwert berichtet (σ 0.5%)
ReaderFestes Reader-Modell und fester Prompt, wortwörtlich veröffentlicht

Was es ehrlich hält: ein Judge von dritter Seite, der unverändert veröffentlichte Reader-Prompt, rein semantischer Abruf und die Veröffentlichung jedes Laufs - nicht nur des besten. Die Abruf-Engine ist deterministisch - führen Sie sie erneut aus, erhalten Sie dieselben Erinnerungen.

Wir erklimmen härtere Benchmarks

Wir testen auf dem härtesten Standard-Benchmark, den wir noch nicht bezwungen haben - und die Zahl ist die Bestmarke über alle WOS-Modelle hinweg, neu geschrieben, sobald ein besseres erscheint. Überschreiten wir klar 94%, steigen wir zu einem härteren Benchmark auf.

LongMemEval-SIn Arbeit
Tablet 185.2%
Scroll 190.7%
GPT-4o-Judge · Bestwert über alle WOS-Modelle94% zum Aufstieg
Vollständigen Bericht ansehen
Preise

Zwei Token-Preise pro Modell,
plus $0.0001 pro Anfrage.

Pro Million Tokens plus pauschal $0.0001 pro Anfrage, Bezahlung nach Verbrauch. Kein Abonnement, keine Speichermiete, keine Gedächtnisgrenzen. Sie zahlen, wenn Ihr Agent schreibt oder liest - nie für das, was er sich merkt.

ModellEingabe / 1MAusgabe / 1M
Tablet 1$2$3Live
Scroll 1$4$8Live
Codex 1--Noch offen
  • $0.0001 pro Anfrage. Eine Pauschalgebühr auf jeden API-Aufruf, zusätzlich zur Token-Nutzung.
  • Speicherung ist kostenlos. Die Aufnahme wird einmal bezahlt; das Aufbewahren kostet Sie nichts. Kein Mengenlimit, keine Aufbewahrungsgrenze.
  • Wir speichern es. Wir trainieren nie darauf, verwenden es nicht und sehen es nicht ein. Das Gedächtnis Ihres Agenten gehört Ihnen - wir organisieren es nur, damit Sie es abrufen können.
  • Warum Tablet so günstig ist: Seine Engine führt kein Modell aus, unsere Kosten sind also Embeddings und Festplatten - keine GPUs. Scroll und Codex ergänzen ein Modell, und genau das deckt ihr höherer Preis ab.
Andere Abrechnungsmodelle berechnen monatlich das gespeicherte Volumen oder deckeln die Anzahl der Erinnerungen je nach Tarif. WOS berechnet für gespeicherte Daten nichts, unabhängig von Volumen oder Alter.

Rate-Limits nach Nutzungsstufe →

Für Entwickler

Drei Aufrufe: Speichern, Abrufen, Antworten.

Eine API. Der Aufruf recall() liefert Kurzzeit-, Langzeit- und Umgebungskontext in einem einzigen Roundtrip - bereit zum Einfügen in Ihren Prompt.

1

Speichern

add() speichert Fakten und Gespräche: die Worte deines Nutzers, die eigenen des Assistenten (speaker "me") oder die einer benannten Person. Beim Eingang eingebettet, ohne LLM-Aufruf.

2

Abrufen

recall() liefert Kurzzeit + Langzeit + Kontext in einem Aufruf - ein begrenzter Kontext fester Größe.

3

Antworten

Übergeben Sie diesen begrenzten Kontext an Ihr LLM - beliebiger Anbieter, Ihr Schlüssel.

from wontopos import Client
mem = Client(api_key="wos-...")
mem.add("she prefers tea over coffee", user_id="alice")
mem.add("I suggested the jasmine tea", user_id="alice", speaker="me")  # its own words
# one call: short + long + context
ctx = mem.recall("what does alice drink?", user_id="alice")

Erinnerungen tragen einen Sprecher. Standard sind die Worte deines Nutzers, speaker "me" speichert, was der Assistent selbst gesagt hat, und ein Name wie "Bob" merkt sich, wer es gesagt hat — Erinnern nach Person.

Sprecher sind explizit, wie Stores. Registriere die Person zuerst, speichere dann unter ihrem Namen: ein Tippfehler wird nie still zu einer neuen Person. Ein Store registriert zunächst bis zu 50 Personen (wir planen mehr), und "me" braucht nie Registrierung und zählt nie.
Schnellstart

Ihr erster Recall in 5 Minuten.

Ein Schlüssel, eine Installationszeile, drei Aufrufe - und Ihr Agent hat ein Gedächtnis. Jedes Snippet auf dieser Seite wurde tatsächlich ausgeführt; die Antworten sind wortwörtlich wiedergegeben.

1

API-Schlüssel erstellen

Erstellen Sie einen in der Konsole. Ein 155 Zeichen langer Schlüssel, der mit wos-live- beginnt, wird einmal angezeigt. Bewahren Sie ihn in einer Umgebungsvariable auf - niemals im Code.

2

Installieren

pip install wontopos        # Python
npm install wontopos        # TypeScript / JavaScript
cargo add wontopos          # Rust
# curl - nothing to install, just set WOS_API_KEY
3

Store anlegen, dann speichern & abrufen

Ein Store ist die user_id, unter der Sie lesen und schreiben. Stores sind explizit: Legen Sie zuerst einen an (der Aufruf unten), dann speichern Sie hinein und rufen daraus ab. Speichern - beim Eingang eingebettet, kein LLM-Aufruf. Abrufen - Kurzzeit + Langzeit + Kontext in einem Roundtrip.

from wontopos import Client

mem = Client(api_key="wos-live-...", user_id="alice")  # set the store once
mem.create_store()              # create it (stores are explicit)
mem.add("she prefers tea over coffee")  # no user_id needed

# one call → short-term + long-term + context
ctx = mem.recall("what does alice drink?")
import { Client } from "wontopos";

const mem = new Client({ apiKey: "wos-live-...", userId: "alice" });  // set the store once
await mem.createStore();            // create it (stores are explicit)
await mem.add("she prefers tea over coffee");  // no userId needed

// one call → short-term + long-term + context
const ctx = await mem.recall("what does alice drink?");
use wontopos::Client;

let mem = Client::new("wos-live-...").with_user("alice");  // set the store once
mem.create_store(None).await?;            // create it (stores are explicit)
mem.add("she prefers tea over coffee", None, json!({})).await?;

// one call → short-term + long-term + context
let ctx = mem.recall("what does alice drink?", None).await?;
# create the store once - stores are explicit
curl -X POST https://api.wontopos.com/api/v1/memory/collection \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice"}'

# store - embedded on the way in, no LLM call
curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"she prefers tea over coffee"}'

# one call → short-term + long-term + context
curl -X POST https://api.wontopos.com/api/v1/memory/recall \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what does alice drink?"}'
Tatsächliche Antwort - create_store()
{"user_id": "alice", "status": "created"}
Tatsächliche Antwort - add()
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}
Store einmal setzen. Übergeben Sie user_id an den Client, und jeder Aufruf verwendet sie - kein Wiederholen nötig; überschreiben Sie einen einzelnen Aufruf, indem Sie ihm user_id übergeben. Stores sind explizit: Das Speichern in einen oder Abrufen aus einem Store, der nicht existiert, liefert 404 - legen Sie ihn zuerst an. Jedes Konto startet mit einem default-Store, sodass der Pfad ganz ohne user_id ohne jede Einrichtung funktioniert. Siehe Stores zum Auflisten und Verwalten.

recall() liefert vier Blöcke - short_term (jüngste Gesprächszüge), long_term (relevante Erinnerungen), context (das Umfeld des besten Treffers) und eine instruction, die dem LLM sagt, wie es sie verwenden soll. Fügen Sie das Ganze in Ihren Prompt ein.

Funktioniert in jeder Sprache. Speichern Sie auf Englisch, fragen Sie auf Koreanisch, Japanisch oder Chinesisch - dieselbe Erinnerung kommt zurück. Embedding-Suche, kein Keyword-Matching.

Jede Methode, pro Sprache →

Stores

Stores - anlegen, auflisten, löschen.

Ein Store ist die user_id, unter der Sie lesen und schreiben - ein isolierter Gedächtnisraum pro Endnutzer, Agent oder Thema. Stores sind explizit: Legen Sie einen an, bevor Sie hineinspeichern oder daraus abrufen, sonst liefert der Aufruf 404. Jedes Konto startet mit einem default-Store, Sie können also ohne Create-Aufruf beginnen.

Wie die Isolation verschachtelt ist. Ein Konto besitzt Workspaces; jeder Workspace isoliert sein eigenes Gedächtnis, seine API-Schlüssel und seine Nutzung (die Abrechnung erfolgt gemeinsam auf Kontoebene). Ein Store liegt innerhalb eines Workspace: Schlüssel im selben Workspace teilen sich dessen Stores, und verschiedene Workspaces sehen niemals das Gedächtnis des jeweils anderen. account → workspace → store (user_id) → memories.
mem.create_store("alice")        # create (idempotent)
mem.list_stores()              # [{"user_id","created_at"}, ...]
mem.delete_store("alice")        # delete the store + all its memories
await mem.createStore("alice");
await mem.listStores();          // [{ user_id, created_at }, ...]
await mem.deleteStore("alice");     // store + all its memories
mem.create_store("alice").await?;
let stores = mem.list_stores().await?;
mem.delete_store("alice").await?;
# create
curl -X POST https://api.wontopos.com/api/v1/memory/collection \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" -d '{"user_id":"alice"}'
# list
curl https://api.wontopos.com/api/v1/memory/collections -H "X-API-Key: $WOS_API_KEY"
# delete (store + all its memories)
curl -X DELETE https://api.wontopos.com/api/v1/memory/collection \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" -d '{"user_id":"alice"}'
Tatsächliche Antwort - create
{ "user_id": "alice", "status": "created" }   // "exists" if it already did
Tatsächliche Antwort - list
{ "collections": [
  { "user_id": "default", "created_at": "2026-06-26T02:23:14Z" },
  { "user_id": "alice",   "created_at": "2026-06-26T02:24:01Z" }
], "count": 2 }
Recall auf einen Store, der nicht existiert
{ "error": { "type": "not_found_error",
  "message": "Store 'ghost' does not exist. Create it first with
              POST /api/v1/memory/collection {\"user_id\":\"ghost\"}, then store or recall." } }
Verwenden Sie einen Store pro Endnutzer ("alice", "user_42"), um die Erinnerungen jeder Person getrennt zu halten, oder einen einzelnen default-Store für einen persönlichen Agenten. Stores lassen sich auch in der Konsole anlegen und durchsehen (Memory ids → Issue), ganz ohne Code. Das Löschen eines Stores ist endgültig - es entfernt jede Erinnerung darin.
Recall-Caching

Wiederholte Abrufe, zum Zehntel des Preises.

Aktiviere es pro Anfrage, und WOS cached das Suchergebnis unter dem Abfragetext, mit denselben Präfixregeln wie beim Prompt Caching von LLMs. Solange der Cache warm ist, nutzt eine wiederholte oder erweiterte Abfrage das vorherige Ergebnis wieder, und der gecachte Teil wird mit 10% des normalen Token-Preises berechnet.

Nur Tablet und Scroll. Caching funktioniert auf jedem Tablet- und Scroll-Modell, heute und in Zukunft. Codex unterstützt es nicht: Codex denkt über deine Erinnerungen nach und lernt zwischen den Aufrufen, dieselbe Frage kann also berechtigt eine andere Antwort ergeben, und ein gecachtes Ergebnis wäre konstruktionsbedingt falsch. Wer cache_control an Codex sendet, bekommt ein klares 403.

Ein Gespräch, drei Runden

So sieht es wirklich aus, wenn ein Agent immer weiter mit seinem Gedächtnis spricht. Jede Runde schickt das bisherige Gespräch als Abfrage, mit aktiviertem cache_control.

writeRunde 1 - „Alice: Ich bin letzten Frühling nach Lissabon gezogen.“

Die gesamte Abfrage wird gesucht und gecacht: Eingabe zum 2-fachen (TTL 5 Minuten).

extendRunde 2 - derselbe Text plus „Bob: Wie ist das Wetter dort?“

Nur Bobs Satz wird eingebettet und gesucht. Der alte Teil kostet 0,1x, der neue Satz 2x, und der Cache endet jetzt dort.

hitRunde 3 - exakt dieselbe Abfrage noch einmal (ein Retry, ein Refresh)

Gar kein Engine-Aufruf. Alles zu 0,1x: der 90%-Rabatt.

Die Preise

VorgangToken-AbrechnungBedeutung
Cache-Schreiben - TTL 5 MinutenDie erste Anfrage. Ihr Ergebnis wird 5 Minuten aufbewahrt, und jedes Lesen verschiebt das Fenster nach vorn.
Cache-Schreiben - TTL 1 StundeDie erste Anfrage, eine volle Stunde aufbewahrt.
Cache-Lesen - Treffer oder Präfix-Treffer0.1×Jede Anfrage nach dem Schreiben: Der gecachte Teil kostet ein Zehntel des normalen Token-Preises.

Was es spart

Ein konkretes Beispiel: Dein Agent schickt ein Gespräch mit 3.000 Tokens als Abfrage und wiederholt oder verlängert es 10-mal innerhalb von fünf Minuten. Ohne Caching sind das 30.000 Eingabe-Tokens zum vollen Preis. Mit einem 5-Minuten-Cache sind es 6.000 für das erste Schreiben (2x) plus rund 2.700 für die neun Cache-Lesevorgänge: 8.700 abgerechnete Tokens, 71% weniger. Je länger das Gespräch läuft, desto größer die Ersparnis.

Die Präfixregel

Der Abgleich erfolgt am Anfang der Abfrage. Bleibt der Anfang identisch und wird nur neuer Text angehängt, wird der gecachte Teil wiederverwendet und nur der neue Teil gesucht. Ändert sich etwas vor dem Ende des gecachten Textes, kann nichts wiederverwendet werden.

prefix match
cached    [ A B C D E F G ]

○   [ A B C D E F G ] E
✗   [ B C D E F G ] E

Treffer - der Anfang ist unverändert, nur E ist neu
Fehltreffer - der Anfang hat sich geändert, die gesamte Abfrage wird neu gesucht und neu gecacht

Drei Regeln zum Merken

  • Erweitern cached bis zum neuen Ende neu. Nach [A B C D E F G] + E endet der Cache jetzt bei E: Das Ende wird einmal zum Schreibtarif berechnet, und die nächste Runde kann wieder ganz A..E als Präfix abgleichen.
  • Ein zusammenhängendes Präfix pro Anfrage. Eine Abfrage kann nicht in zwei Cache-Segmente geteilt werden; nur ihr Anfang kann übereinstimmen.
  • Schreibvorgänge invalidieren sofort. Jedes store, store-turn, bulk-store, forget, supersede oder Löschen des Stores verwirft dessen Cache. Eine gecachte Antwort kann nie veraltet sein.

So wird es aktiviert

hits = mem.search(
    "...the conversation so far...", user_id="alice",
    cache_control={"ttl": "5m"},   # or "1h"
)
const hits = await mem.search(
  "...the conversation so far...", "alice", 10,
  { cache_control: { ttl: "5m" } },   // or "1h"
);
let hits = mem.search_with(
    "...the conversation so far...", "alice", 10,
    serde_json::json!({"cache_control": {"ttl": "5m"}}),   // or "1h"
).await?;
curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice",
       "query":"...the conversation so far...",
       "cache_control":{"ttl":"5m"}}'   # or "1h"
Antwort - das cache-Objekt meldet, was passiert ist
{ "memories": [ ... ],
  "cache": { "status": "hit",              // "write" | "hit" | "extend"
             "ttl": "5m",
             "cache_read_input_tokens": 412,
             "cache_creation_input_tokens": 0 } }

Für all das brauchst du kein SDK. Caching ist ein Feld in einem HTTP-Aufruf und funktioniert daher aus jeder Programmiersprache. Der curl-Tab ist das universelle Rezept, und die Python-, TypeScript- und Rust-SDKs sind bequeme Hüllen um genau denselben Aufruf.

Das Caching ist innerhalb deines Workspace pro Store und pro Modell isoliert und standardmäßig aus: Ohne cache_control ändert sich an deinen Anfragen nichts.
Wer es gesagt hat

Gedächtnis, das weiß, wer es gesagt hat.

Menschen erinnern sich nach Person: was Bob versprochen hat, was du zugesagt hast. Gib jeder Erinnerung einen Sprecher und dein Agent tut dasselbe, auf jedem Tablet- und Scroll-Modell.

Sprecher sind explizit, wie Stores. Registriere die Person zuerst, speichere dann unter ihrem Namen: ein Tippfehler wird nie still zu einer neuen Person. Ein Store registriert zunächst bis zu 50 Personen (wir planen mehr), und "me" braucht nie Registrierung und zählt nie.

Ein Team, drei Erinnerungen

Ein Store hält viele Stimmen auseinander. Registriere eine Person einmal, speichere jede Äußerung unter ihrem Sprecher und frage später nach Person.

addRegistriere Bob einmal: POST /speakers, oder add_speaker("Bob") in den SDKs.

Der Store kennt Bob jetzt. Das 50er-Limit wird hier bei der Registrierung gezählt; Speicheraufrufe liefern nie einen Limit-Fehler.

BobBob sagt, die Deadline sei auf Dienstag gerutscht. Speichere es mit speaker "Bob".

Die Erinnerung gehört jetzt Bob: jede Suche, die sie zurückgibt, sagt das auch.

meDein Assistent verspricht die Zusammenfassung bis Freitag. Speichere seine eigenen Worte mit speaker "me".

Auch die eigenen Worte werden erinnert, und "me" zählt nie gegen das Limit.

askSpäter: "Was hat Bob zur Deadline gesagt?" Suche mit speaker "Bob".

Nur Bobs Worte kommen zurück. Die Worte einer Person kommen nie als die einer anderen zurück.

Drei Regeln zum Merken

  • "me" ist der Assistent selbst. Nie registriert, nie gezählt. Reserviert und kleingeschrieben: speaker: "Me" oder "ME" liefert 400 invalid_request_error statt stiller Umdeutung.
  • Das Limit zählt bei der Registrierung: zunächst 50 pro Store. Darüber hinaus liefert die Registrierung 400 invalid_request_error mit speaker_limit: 50 im Fehlerbody. Speichern mit unregistriertem Namen liefert ebenfalls 400 und speichert nichts. Suche mit unregistriertem Namen im Filter liefert 404 not_found_error. Verzweige auf Status und Felder, nicht auf den Meldungstext; wir planen, das Limit anzuheben.
  • Labels leben in jeder Leseoperation. Suchergebnisse, der Langzeit-Kontext von recall und Engram-Ergebnisse tragen ihren Sprecher — das Modell weiß immer, wessen Worte es hält. Mit speaker in der Suche kommen nur die Worte einer Person zurück. Ein supersede behält den Sprecher; forget entfernt ihn.
  • Namen sind Unicode: jede Sprache funktioniert. さくら, Иван und 하늘 sind gültige Sprecher, und die Zuordnung verhält sich in jeder Sprache identisch. Der Abgleich ist exakt nach Trim und Unicode-Normalisierung, also sind Bob und bob zwei Personen. Namen sind bis 80 Zeichen lang.
errors - verbatim
# POST /speakers past the limit
{ "type": "error",
  "error": { "type": "invalid_request_error",
             "message": "This store already has 50 registered speakers, ...",
             "speaker_limit": 50 } }

# store with an unregistered name → 400, nothing stored
{ "type": "error",
  "error": { "type": "invalid_request_error",
             "message": "speaker 'Bob' is not registered in this store. Register it first: ...",
             "speaker": "Bob" } }

# search filtered by an unregistered name → 404
{ "type": "error",
  "error": { "type": "not_found_error",
             "message": "speaker 'Bob' is not registered in this store.",
             "speaker": "Bob" } }

Zwei Randnotizen. speaker gehört zu add / store: add_turn merkt sich den ganzen Austausch, Personen-Labels und der Filter kommen aus Erinnerungen mit explizitem speaker. Und Sitzungspassagen (expand) sind Komposite mehrerer Erinnerungen, tragen also kein Label; ein speaker-Filter liefert immer atomare, gelabelte Erinnerungen. Und identischer Inhalt wird auf die erste Erinnerung dedupliziert: ein solcher store liefert status "duplicate" mit expliziter note, ohne angehängten Sprecher.

Wir testen das auf die harte Tour: Erinnerungen ohne Namen im Text, abgerufen pro Person. Die Zuordnung kommt aus dem Sprecher-Register, nicht aus Wortabgleich, und verhält sich daher in jeder Sprache gleich.

So nutzt du es

mem.add_speaker("Bob", user_id="alice")  # once per person; "me" needs no registration
mem.add("Bob said the deadline moved to Tuesday", user_id="alice", speaker="Bob")
mem.add("I promised the summary by Friday", user_id="alice", speaker="me")
hits = mem.search("what did Bob say about the deadline?", user_id="alice", speaker="Bob")
mem.list_speakers(user_id="alice")
mem.remove_speaker("Bob", user_id="alice")  # memories stay, the tag goes
await mem.addSpeaker("Bob", "alice");  # once per person; "me" needs no registration
await mem.add("Bob said the deadline moved to Tuesday", "alice", { speaker: "Bob" });
await mem.add("I promised the summary by Friday", "alice", { speaker: "me" });
const hits = await mem.search("what did Bob say about the deadline?", "alice", 10, { speaker: "Bob" });
await mem.listSpeakers("alice");
await mem.removeSpeaker("Bob", "alice");  // memories stay, the tag goes
mem.add_speaker("Bob", "alice").await?;  # once per person; "me" needs no registration
mem.add("Bob said the deadline moved to Tuesday", "alice", json!({"speaker": "Bob"})).await?;
mem.add("I promised the summary by Friday", "alice", json!({"speaker": "me"})).await?;
let hits = mem.search_with("what did Bob say about the deadline?", "alice", 10, json!({"speaker": "Bob"})).await?;
mem.list_speakers("alice").await?;
mem.remove_speaker("Bob", "alice").await?;  // memories stay, the tag goes
curl -X POST https://api.wontopos.com/api/v1/memory/speakers \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","speaker":"Bob"}'   # once per person

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"Bob said the deadline moved to Tuesday","metadata":{"speaker":"Bob"}}'

curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what did Bob say about the deadline?","speaker":"Bob"}'

curl "https://api.wontopos.com/api/v1/memory/speakers?user_id=alice" -H "X-API-Key: $WOS_API_KEY"

curl -X DELETE https://api.wontopos.com/api/v1/memory/speakers \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","speaker":"Bob"}'   # memories stay, the tag goes
response
{ "memories": [
    { "content": "Bob said the deadline moved to Tuesday",
      "speaker": "Bob", ... } ] }
GET /speakers
{ "user_id": "alice",
  "speakers": [ { "speaker": "Bob", "memories": 2, "created_at": "2026-07-10T04:20:39Z" } ],
  "count": 1, "limit": 50 }

Die Liste zeigt, wen der Store kennt, mit Erinnerungszahl pro Person gegen das Limit. Entfernen löscht nur die Registrierung: die Erinnerungen bleiben, nur das Namenslabel geht.

Add-on · Beta

MCP - Gedächtnis für KI-Tools

Der Kern von WOS sind API und SDKs. Der MCP-Server ist ein Add-on darüber: dasselbe Gedächtnis, eingesteckt in Tools, die du nicht gebaut hast - Claude Code, Claude Desktop, Cursor.

Eine Installationszeile gibt dem Agenten neun Gedächtnis-Tools, die er selbstständig nutzt. Und weil das Gedächtnis im Konto lebt, erinnert jedes andere Tool, was eines schreibt - auch Agenten, die du mit dem SDK baust.

Was damit möglich ist

  • Ein Claude Code, der sich an dein Projekt erinnert. Entscheidungen, Bugfixes, Vorlieben - in der nächsten Sitzung abgerufen, ohne etwas neu zu erklären.
  • In ChatGPT anfangen, in Claude weitermachen. Gleicher Store, gleiches Gedächtnis - das Gespräch wechselt das Tool, statt neu zu starten.
  • Dein eigener Agent bleibt im Kreis. Was Claude Code lernt, ruft ein SDK-Agent ab - und was dein Agent speichert, erinnert Claude Code zurück.

Läuft in Claude Code, Claude Desktop, Cursor, Windsurf und jedem MCP-Host. ChatGPT erreicht dasselbe Gedächtnis über Actions plus die OpenAPI-Spec.

Installation

claude mcp add wontopos --env WONTOPOS_API_KEY=wos-live-... -- npx -y wontopos-mcp

Der Agent bekommt neun Tools - recall · remember · search · update · forget · list_memories · engram · stats · create_store - jedes so beschrieben, dass er selbst weiß, wann er sie nutzt.

Das Add-on selbst ist gratis und auf npm veröffentlicht - du zahlst nur die normalen Nutzungspreise für seine API-Aufrufe. Braucht Node 18+ und einen API-Key aus der Konsole.

Entwicklerseite öffnen

Add-on

OpenAPI-Spec

Die vollständige maschinenlesbare Karte der API - jeder Endpoint, Request, Response und Fehler.

OpenAPI ist das Industriestandard-Format, um eine HTTP-API in einer maschinenlesbaren Datei zu beschreiben.

https://api.wontopos.com/openapi.json

Was damit möglich ist

Postman: File → Import → URL einfügen - alle 16 Endpoints erscheinen als klickbare Collection. ChatGPT: GPT erstellen, Action hinzufügen, dieselbe URL einfügen. Codegen: openapi-generator -i .../openapi.json -g go baut einen Client in einer Sprache, die wir nicht ausliefern.

In Postman importieren, einen Client in einer Sprache generieren, die wir nicht ausliefern, ChatGPT Actions anbinden oder Contract-Checks in CI fahren. Ein Test pinnt sie an die echten Routen - sie kann nicht driften.

Add-on

llms.txt

Die ganze API auf einer Textseite, die eine KI lesen kann.

llms.txt ist eine Web-Konvention: eine Klartextseite an der Site-Root, die einer KI alles Nötige über ein Produkt sagt.

https://wontopos.com/llms.txt

In die IDE oder den Coding-Agenten legen - er weiß sofort, wie man auf WOS baut: Auth, Endpoints, Patterns, Fehler. Mit jedem Release aktualisiert.

Dieselben Fakten wie die OpenAPI-Spec, anderes Publikum: Die Spec ist präzise Struktur für Tools, diese Datei ist Prosa, die eine KI (oder ein Mensch) in einem Zug liest. Beide aktualisieren sich mit jedem Release.

Model Context Protocol · Beta

Dein Gedächtnis in jedem KI-Tool

Ein Befehl gibt Claude Code, Claude Desktop, Cursor oder jedem MCP-Host ein Langzeitgedächtnis auf Basis deines WOS-Kontos. Kein Integrationscode: Der Agent bekommt neun Gedächtnis-Tools und entscheidet selbst, wann er sie nutzt.

MCP ist Beta. Die neun Tools funktionieren heute und sind getestet, aber die Oberfläche kann sich noch ändern, während wir sie fertigstellen. API und SDKs darunter sind stabil und versioniert.

Installation

Claude Code, eine Zeile (Key vorher in der Konsole erstellen):

claude mcp add wontopos --env WONTOPOS_API_KEY=wos-live-... -- npx -y wontopos-mcp
# pick which store it remembers into (optional): add --env WONTOPOS_USER_ID=my-project
# ~/.cursor/mcp.json
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }
# .vscode/mcp.json
{ "servers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }
# ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }
# Claude Desktop and any other MCP host
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }

Add to Cursor →  ·  Add to VS Code →

Optionale Env: WONTOPOS_USER_ID setzt den Standard-Store, WONTOPOS_MODEL die Engine, WONTOPOS_BASE_URL ein Self-Hosted-Deployment. WONTOPOS_READ_ONLY=1 schaltet auf Nur-Lesen (nur Recall/Suche/Liste).

Bevor du einen Store teilst

  • Nutze einen eigenen Key. Keys tragen ihren Workspace: Ein nur für MCP erstellter Key begrenzt, was verbundene Tools überhaupt erreichen - und lässt sich in der Konsole rotieren, ohne die App-Keys anzufassen.
  • Nur-Lese-Modus. WONTOPOS_READ_ONLY=1 registriert gar keine Schreib-Tools: Der Agent kann erinnern, suchen, Erinnerungen auflisten, Engrams ausführen und Statistiken lesen, aber nichts speichern, aktualisieren, vergessen oder löschen. Richtig für Agenten, die Gedächtnis nutzen, nicht besitzen sollen.
  • Tool-Bestätigung anlassen. MCP-Hosts fragen standardmäßig vor jedem Tool-Lauf - lass das besonders für forget an, denn Löschungen teilen sich alle Tools des Stores.
  • Alles Gespeicherte kann jedes Tool mit dem Key abrufen. Speichere niemals Geheimnisse - API-Keys, Passwörter - als Erinnerungen.
  • Erinnerte Inhalte sind Daten, keine Anweisungen. Die Tool-Beschreibungen sagen das dem Agenten explizit. Speichere trotzdem keinen nicht vertrauenswürdigen Fremdtext in einem Store, dem ein autonomer Agent folgt.
  • Löschungen werden ebenfalls geteilt. Ein forget oder delete_all aus einem Tool löscht für alle.
  • "me" meint den Agenten, der in den Store schreibt. Teilen sich mehrere Agenten einen Store, verschmelzen ihre "me"-Stimmen. Gib jedem Agenten einen eigenen Store (WONTOPOS_USER_ID) für getrennte Identitäten.
  • Ein Konto zahlt. Alle verbundenen Tools ziehen vom selben Guthaben und Rate-Limit.

Dann einfach reden

youmerk dir, dass wir freitags releasen

Der Agent ruft das Tool remember auf. Dauerhaft im Store gespeichert: Das Sitzungsende ändert nichts.

new sessionwann releasen wir?

Eine neue Sitzung hat null Verlauf. Der Agent ruft recall auf und antwortet aus dem Gedächtnis: freitags.

Sag einfach

  • "Dieses Repo nutzt pnpm, merk dir das" → remember speichert es; die nächste Sitzung weiß es schon.
  • "Welches Fehlerformat hatten wir letzte Woche festgelegt?" → recall holt die Entscheidung zurück in den Kontext.
  • „Die Deadline ist jetzt Freitag.“ → der Agent merkt, dass es dem widerspricht, was er abgerufen hat, und ruft update auf, um die Erinnerung an Ort und Stelle zu korrigieren.
  • "Das ist falsch, vergiss es" → der Agent findet die Memory-Id und ruft forget auf - dein Host fragt vorher nach.
  • „Was weißt du über mich?“ → list_memories blättert durch alles Gespeicherte, damit der Agent antworten oder aufräumen kann.

Nichts Besonderes zu formulieren - das sind normale Sätze, keine Befehle. Der Agent liest die Tool-Beschreibungen und wählt selbst.

Die neun Tools

  • recall - Kontext in einem Aufruf: jüngste Turns plus relevante Langzeiterinnerungen. Die Tool-Beschreibung weist den Agenten an, es zuerst aufzurufen, wenn Vergangenes zählt.
  • remember - Speichert einen dauerhaften Fakt oder Beschluss. speaker: "me" markiert die eigenen Worte des Agenten; ein registrierter Name, wer es gesagt hat.
  • search - Semantische Suche, optional mit speaker-Filter pro Person.
  • forget - Löscht eine Erinnerung per id.
  • speakers - Registriert, listet oder entfernt die Personen eines Stores.
  • create_store - Stores sind explizit: einer pro Endnutzer, Projekt oder Agent.

SDK oder MCP?

  • Das SDK gehört in eine App, die du schreibst. Dein Code entscheidet exakt, wann gespeichert und was erinnert wird - deterministisch, typisiert, versioniert. Du baust ein Produkt? SDK.
  • MCP steckt man in ein KI-Tool, das du nicht geschrieben hast. Der Agent entscheidet anhand der Tool-Beschreibungen, wann er Gedächtnis nutzt - null Code. Richtig für Claude Code, Claude Desktop, Cursor oder um einem fertigen Assistenten Gedächtnis zu geben.

Darunter dieselbe API, dieselben Stores - eine SDK-App und eine Claude-Code-Sitzung über MCP teilen ein Gedächtnis. Man wählt pro Oberfläche, nicht entweder-oder.

Ein Gedächtnis über alle Tools hinweg

Das Gedächtnis gehört dem Konto, nicht dem Tool. Derselbe Store, aus ChatGPT (Actions plus OpenAPI-Spec) geschrieben, wird in Claude Code und in deinen eigenen Agenten erinnert, und umgekehrt: Ein Gespräch, das in einem Tool beginnt, geht in einem anderen weiter.

Und weil es ein Store ist, kannst du Claude Code verlassen und dort weiterreden, wo du baust: Ein SDK-Agent mit demselben Key und Store erinnert alles, was Claude Code gerade gelernt hat - und was dein Agent speichert, erinnert Claude Code in der nächsten Sitzung.

Läuft lokal über stdio (npx wontopos-mcp): Dein Key bleibt in deiner Umgebung und läuft nie über einen Drittserver. Es umhüllt das TypeScript-SDK, also gelten automatische Retries, Redirect-Ablehnung und Key-Maskierung unverändert.
Model Context Protocol · Beta

Claude Code

Der Hauptweg: ein Befehl im Terminal, und jede Sitzung startet mit Gedächtnis.

  1. Erstelle einen API-Key in der Konsole. Der Key trägt seinen Workspace: ein Key = ein Gedächtnisraum.
  2. Registriere den Server. --scope user macht ihn in jedem Projekt verfügbar; ohne sieht ihn nur das aktuelle Projekt.
  3. Prüfen: /mcp in Claude Code ausführen - wontopos sollte mit neun Tools gelistet sein.
  4. Mach es automatisch: eine Zeile in deiner CLAUDE.md - "wenn Vergangenes zählt, zuerst wontopos recall aufrufen" - und jede Sitzung startet ungefragt mit Gedächtnis.
claude mcp add wontopos --scope user \
  --env WONTOPOS_API_KEY=wos-live-... -- npx -y wontopos-mcp
# pick a store (optional): add --env WONTOPOS_USER_ID=my-project
Model Context Protocol · Beta

Claude Desktop

Füge den Block unten in claude_desktop_config.json ein (Einstellungen → Developer → Edit Config), starte die App neu - die neun Tools erscheinen. Hinweis: claude.ai im Web und mobil braucht einen Remote-MCP-Server, den WOS noch nicht anbietet - die Desktop-App ist der unterstützte Weg.

# claude_desktop_config.json
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }
Model Context Protocol · Beta

Cursor

Füge den Block unten in ~/.cursor/mcp.json ein - oder nutze den Ein-Klick-Button - und starte Cursor neu. Der Agent übernimmt die neun Tools.

# ~/.cursor/mcp.json
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }

Add to Cursor →

Model Context Protocol · Beta

VS Code

VS Code (Copilot-Agentenmodus) liest MCP-Server aus .vscode/mcp.json im Projekt - füge den Block unten ein oder nutze den Ein-Klick-Button.

# .vscode/mcp.json
{ "servers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }

Add to VS Code →

Model Context Protocol · Beta

Windsurf

Windsurf (Cascade) liest ~/.codeium/windsurf/mcp_config.json: Block unten einfügen und neu laden - dieselben neun Tools erscheinen.

# ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }
Model Context Protocol · Beta

ChatGPT

ChatGPTs MCP-Konnektoren akzeptieren nur Remote-Server; der unterstützte Weg ist heute ein Custom GPT mit einer Action: GPT erstellen, Action hinzufügen, die OpenAPI-Spec-URL unten einfügen und den API-Key als Auth-Header setzen. Dieses GPT ruft dann dasselbe Gedächtnis auf wie deine anderen Tools.

# GPT → Configure → Actions → Import from URL
https://api.wontopos.com/openapi.json
# Authentication: API Key · Header name: X-API-Key

Gleicher Store, gleiches Gedächtnis: Was ChatGPT über die Action speichert, erinnert Claude Code über MCP - und umgekehrt.

Model Context Protocol · Beta

Gemini CLI

Gemini CLI liest MCP-Server aus ~/.gemini/settings.json: Block unten einfügen, CLI neu starten - dieselben neun Tools erscheinen auch dort.

# ~/.gemini/settings.json
{ "mcpServers": {
    "wontopos": {
      "command": "npx",
      "args": ["-y", "wontopos-mcp"],
      "env": { "WONTOPOS_API_KEY": "wos-live-...",
               "WONTOPOS_USER_ID": "my-project" }
    } } }
Python-SDK

Python - jede Methode, drei Gruppen.

Schreiben, Lesen, Löschen. Jedes Beispiel unten wurde am 2026-07-10 gegen die Live-API ausgeführt; die Antworten sind wortwörtlich wiedergegeben.

pip install wontopos
from wontopos import Client

mem = Client(api_key="wos-live-...")  # or read from an env var

Modell wählen

Der API-Schlüssel bestimmt, welches Gedächtnis (Ihr Konto); das Modell bestimmt, welche Engine es liest. Alle Modelle teilen sich ein Gedächtnis, Sie können also mit einem speichern und mit einem anderen abrufen. Setzen Sie einen Standard am Client; überschreiben Sie einen einzelnen Aufruf, indem Sie ihm model= übergeben.

mem = Client(api_key="wos-live-...", model="tablet-1")  # default engine
mem.recall("...", user_id="alice")                  # tablet-1
mem.recall("...", user_id="alice", model="scroll-1")  # or pick a model per call

list_models ✓ live-tested

Der Katalog - die IDs, die Sie an model übergeben können, und ob sie jeweils live sind. Modelle mit memory: "shared" lesen denselben Store; "isolated" führt einen eigenen. Benötigt keinen API-Schlüssel.

mem.list_models()
Tatsächliche Antwort
[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"},
 {"id": "scroll-1", "name": "Scroll 1", "available": true, "memory": "shared"},
 {"id": "scroll-1.2", "name": "Scroll 1.2", "available": true, "memory": "shared"}]

ping ✓ live-tested

Verbindung und Gültigkeit des API-Schlüssels in einer Zeile prüfen.

mem.ping()   # True, or raises AuthenticationError / PaymentRequiredError

Der Katalog oben spiegelt stets die aktuell verfügbaren Modelle wider - übergeben Sie eine andere ID, erhalten Sie einen klaren Fehler. Neue Modelle erscheinen dort automatisch, sobald sie ausgeliefert werden.

Schreiben

add ✓ live-tested

Eine Erinnerung speichern. Beim Eingang eingebettet - kein LLM-Aufruf, Sie zahlen nur Embeddings.

mem.add("she prefers tea over coffee", user_id="alice")
mem.add("I promised the summary by Friday", user_id="alice", speaker="me")  # its own words - no registration needed
Tatsächliche Antwort
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

add_turn ✓ live-tested

Einen Gesprächszug (Nutzer + Assistent) zugleich ins Kurzzeit- und Langzeitgedächtnis speichern.

mem.add_turn("hi", "hello!", user_id="alice")
Tatsächliche Antwort
{"status": "ok"}

speaker ✓ live-tested

Jede Erinnerung kann tragen, wer sie gesagt hat. Registriere eine Person einmal und übergib danach ihren Namen als speaker; "me" (die eigenen Worte des Assistenten) braucht nie eine Registrierung. Auch die Suche akzeptiert speaker, um nur die Worte einer Person zu holen.

mem.add_speaker("Bob", user_id="alice")  # once per person; "me" needs no registration
mem.add("I promised to send the report on Friday", user_id="alice", speaker="me")
mem.add("Bob said the deadline moved to Tuesday", user_id="alice", speaker="Bob")
mem.search("what did Bob say about deadlines?", user_id="alice", speaker="Bob")
response
{"memories": [{"content": "Bob said the deadline moved to Tuesday", "speaker": "Bob", ...}]}
Sprecher sind explizit, wie Stores. Registriere die Person zuerst, speichere dann unter ihrem Namen: ein Tippfehler wird nie still zu einer neuen Person. Ein Store registriert zunächst bis zu 50 Personen (wir planen mehr), und "me" braucht nie Registrierung und zählt nie.

add_bulk ✓ live-tested

Einen großen Textblock nachladen. Serverseitig zerlegt und eingebettet - ideal zum Import bestehender Historie.

mem.add_bulk("Alice moved to Brooklyn in March. She works at a design studio downtown.", user_id="alice")
Tatsächliche Antwort
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}

update ✓ live-tested

Ein Fakt hat sich geändert. Die alte Erinnerung wird als ersetzt markiert (für die Historie behalten); die neue nimmt ihren Platz im Recall ein.

mem.update("576700aa-...", "she switched to coffee this year", user_id="alice")
Tatsächliche Antwort
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
 "old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}

Lesen

search ✓ live-tested

Semantische Suche, das Relevanteste zuerst. Reines Embedding - kein Keyword-Matching, jede Sprache findet also jede Erinnerung. Das SDK gibt das memories-Array direkt zurück; der rohe HTTP-Body ist unten abgebildet.

r = mem.search("what does she drink?", user_id="alice", limit=1)
Tatsächliche Antwort (HTTP-Body)
{"memories": [{
   "id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624",
   "content": "she prefers tea over coffee",
   "category": "general",
   "time_bucket": "2026-06",
   "importance": 0.3,
   "similarity": 0.6316057443618774,
   "is_superseded": false,
   "superseded_by": null,
   "created_at": "2026-07-10T04:20:39.688276876Z"
 }], "search_ms": 315, "total_found": 1}
FeldBedeutung
similarityRohe Embedding-Ähnlichkeit zu Ihrer Abfrage (0–1).
is_supersededTrue, wenn dieser Fakt durch update() ersetzt wurde.
search_msServerseitige Abrufzeit.

recall ✓ live-tested

Ein Roundtrip liefert alles, was Ihr LLM braucht - fügen Sie das Ergebnis direkt in Ihren Prompt ein: ein begrenzter Kontext fester Größe, egal wie viel Sie gespeichert haben.

ctx = mem.recall("what does she drink?", user_id="alice")
Tatsächliche Antwort (Struktur - Listen gekürzt)
{"short_term":  {"count": 2, "turns": [{"role": "user", "content": "hi", ...}]},
 "long_term":   {"count": 4, "memories": [{"content": "she prefers tea over coffee",
                                           "similarity": 0.63, ...}]},
 "context":     {"count": 4, "around_top_memory": [
                  "[match] she prefers tea over coffee",
                  "[after] Alice moved to Brooklyn in March. ..."]},
 "instruction": "Use short_term for recent context, long_term for relevant
                 past memories, context for surrounding conversation of the
                 most relevant memory."}

history ✓ live-tested

Jüngste Gesprächszüge (Kurzzeitgedächtnis), älteste zuerst.

turns = mem.history("alice")
Tatsächliche Antwort (HTTP-Body)
{"count": 2, "turns": [
   {"role": "user",      "content": "hi",     "timestamp": "2026-07-10T04:20:40.989011337Z"},
   {"role": "assistant", "content": "hello!", "timestamp": "2026-07-10T04:20:40.989013416Z"}
 ], "user_id": "alice"}

stats ✓ live-tested

Anzahl der Erinnerungen für einen Nutzer.

mem.stats("alice")
Tatsächliche Antwort
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}

get ✓ live-tested

Ruft eine einzelne Erinnerung per id ab - die id, die add oder list_memories zurückgegeben hat. Nur der gespeicherte Originaltext plus Metadaten, nie der Vektor. Eine id aus einem anderen Store oder eine gelöschte/invalidierte Erinnerung ergibt 404.

m = mem.get("alice", memory_id="576700aa-...")
response
{"id": "576700aa-...", "content": "she prefers tea over coffee",
 "category": "general", "source_type": "user_said",
 "created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}

list_memories ✓ live-tested

Listet die Erinnerungen eines Stores auf - nur der gespeicherte Originaltext und seine Metadaten, nie der Vektor. Seitenweise per Cursor: den zurückgegebenen next_cursor für die nächste Seite mitgeben.

page = mem.list_memories("alice", limit=100)
response
{"count": 2, "next_cursor": null, "memories": [
   {"id": "576700aa-...", "content": "she prefers tea over coffee",
    "category": "general", "source_type": "user_said",
    "created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}
 ]}

iter_memories · export_memories

Alle Erinnerungen ohne Cursor-Verwaltung durchlaufen oder den ganzen Store auf einmal holen.

for m in mem.iter_memories("alice"):   # every page, no cursor bookkeeping
    print(m["id"], m["content"])
everything = mem.export_memories("alice")   # the whole store as a list

Löschen

delete ✓ live-tested

Eine einzelne Erinnerung per ID löschen.

mem.delete("alice", memory_id="576700aa-...")
Tatsächliche Antwort
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}

delete_all ✓ live-tested

Alles für einen Nutzer löschen - ein Aufruf, DSGVO-bereit.

mem.delete_all("alice")
Tatsächliche Antwort
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}

Fehler und Zuverlässigkeit

Jeder Fehler ist typisiert - fange den konkreten (Rate-Limit, Auth, Zahlung) oder alle mit dem Basis-WosError.

from wontopos import PaymentRequiredError, NotFoundError
try:
    mem.add("...", user_id="alice")
except NotFoundError:
    mem.create_store("alice")   # store didn't exist yet
except PaymentRequiredError:
    top_up()                       # out of credit - don't retry

rate_limit

Lies das verbleibende Kontingent nach jedem Aufruf und drossle, bevor du das Limit erreichst.

mem.search("...", user_id="alice")
rl = mem.rate_limit   # {"limit": 150, "remaining": 3, "reset": ...}
TypeScript-SDK

TypeScript - jede Methode, drei Gruppen.

Schreiben, Lesen, Löschen. Jedes Beispiel unten wurde am 2026-07-10 gegen die Live-API ausgeführt; die Antworten sind wortwörtlich wiedergegeben.

npm install wontopos
import { Client } from "wontopos";

const mem = new Client({ apiKey: "wos-live-..." });

Modell wählen

Der API-Schlüssel bestimmt, welches Gedächtnis (Ihr Konto); das Modell bestimmt, welche Engine es liest. Alle Modelle teilen sich ein Gedächtnis, Sie können also mit einem speichern und mit einem anderen abrufen. Setzen Sie einen Standard im Konstruktor; überschreiben Sie einen einzelnen Aufruf mit withModel().

const mem = new Client({ apiKey: "wos-live-...", model: "tablet-1" });  // default
mem.recall("...", "alice");                          // tablet-1
mem.withModel("scroll-1").recall("...", "alice");  // or pick a model per call

listModels ✓ live-tested

Der Katalog - die IDs, die Sie an model übergeben können, und ob sie jeweils live sind. Modelle mit memory: "shared" lesen denselben Store; "isolated" führt einen eigenen. Benötigt keinen API-Schlüssel.

await mem.listModels();
Tatsächliche Antwort
[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"},
 {"id": "scroll-1", "name": "Scroll 1", "available": true, "memory": "shared"},
 {"id": "scroll-1.2", "name": "Scroll 1.2", "available": true, "memory": "shared"}]

ping ✓ live-tested

Verbindung und Gültigkeit des API-Schlüssels in einer Zeile prüfen.

await mem.ping();   // true, or throws AuthenticationError / PaymentRequiredError

Der Katalog oben spiegelt stets die aktuell verfügbaren Modelle wider - übergeben Sie eine andere ID, erhalten Sie einen klaren Fehler. Neue Modelle erscheinen dort automatisch, sobald sie ausgeliefert werden.

Schreiben

add ✓ live-tested

Eine Erinnerung speichern. Beim Eingang eingebettet - kein LLM-Aufruf, Sie zahlen nur Embeddings.

await mem.add("she prefers tea over coffee", "alice");
await mem.add("I promised the summary by Friday", "alice", { speaker: "me" });  // its own words - no registration needed
Tatsächliche Antwort
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

addTurn ✓ live-tested

Einen Gesprächszug (Nutzer + Assistent) zugleich ins Kurzzeit- und Langzeitgedächtnis speichern.

await mem.addTurn("hi", "hello!", "alice");
Tatsächliche Antwort
{"status": "ok"}

speaker ✓ live-tested

Jede Erinnerung kann tragen, wer sie gesagt hat. Registriere eine Person einmal und übergib danach ihren Namen als speaker; "me" (die eigenen Worte des Assistenten) braucht nie eine Registrierung. Auch die Suche akzeptiert speaker, um nur die Worte einer Person zu holen.

await mem.addSpeaker("Bob", "alice");  # once per person; "me" needs no registration
await mem.add("I promised to send the report on Friday", "alice", { speaker: "me" });
await mem.add("Bob said the deadline moved to Tuesday", "alice", { speaker: "Bob" });
await mem.search("what did Bob say about deadlines?", "alice", 10, { speaker: "Bob" });
Sprecher sind explizit, wie Stores. Registriere die Person zuerst, speichere dann unter ihrem Namen: ein Tippfehler wird nie still zu einer neuen Person. Ein Store registriert zunächst bis zu 50 Personen (wir planen mehr), und "me" braucht nie Registrierung und zählt nie.

addBulk ✓ live-tested

Einen großen Textblock nachladen. Serverseitig zerlegt und eingebettet - ideal zum Import bestehender Historie.

await mem.addBulk("Alice moved to Brooklyn in March. She works at a design studio downtown.", "alice");
Tatsächliche Antwort
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}

update ✓ live-tested

Ein Fakt hat sich geändert. Die alte Erinnerung wird als ersetzt markiert (für die Historie behalten); die neue nimmt ihren Platz im Recall ein.

await mem.update("576700aa-...", "she switched to coffee this year", "alice");
Tatsächliche Antwort
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
 "old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}

Lesen

search ✓ live-tested

Semantische Suche, das Relevanteste zuerst. Reines Embedding - kein Keyword-Matching, jede Sprache findet also jede Erinnerung. Das SDK gibt das memories-Array direkt zurück; der rohe HTTP-Body ist unten abgebildet.

const r = await mem.search("what does she drink?", "alice", 1);
Tatsächliche Antwort (HTTP-Body)
{"memories": [{
   "id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624",
   "content": "she prefers tea over coffee",
   "category": "general",
   "time_bucket": "2026-06",
   "importance": 0.3,
   "similarity": 0.6316057443618774,
   "is_superseded": false,
   "superseded_by": null,
   "created_at": "2026-07-10T04:20:39.688276876Z"
 }], "search_ms": 315, "total_found": 1}
FeldBedeutung
similarityRohe Embedding-Ähnlichkeit zu Ihrer Abfrage (0–1).
is_supersededTrue, wenn dieser Fakt durch update() ersetzt wurde.
search_msServerseitige Abrufzeit.

recall ✓ live-tested

Ein Roundtrip liefert alles, was Ihr LLM braucht - fügen Sie das Ergebnis direkt in Ihren Prompt ein: ein begrenzter Kontext fester Größe, egal wie viel Sie gespeichert haben.

const ctx = await mem.recall("what does she drink?", "alice");
Tatsächliche Antwort (Struktur - Listen gekürzt)
{"short_term":  {"count": 2, "turns": [{"role": "user", "content": "hi", ...}]},
 "long_term":   {"count": 4, "memories": [{"content": "she prefers tea over coffee",
                                           "similarity": 0.63, ...}]},
 "context":     {"count": 4, "around_top_memory": [
                  "[match] she prefers tea over coffee",
                  "[after] Alice moved to Brooklyn in March. ..."]},
 "instruction": "Use short_term for recent context, long_term for relevant
                 past memories, context for surrounding conversation of the
                 most relevant memory."}

history ✓ live-tested

Jüngste Gesprächszüge (Kurzzeitgedächtnis), älteste zuerst.

const turns = await mem.history("alice");
Tatsächliche Antwort (HTTP-Body)
{"count": 2, "turns": [
   {"role": "user",      "content": "hi",     "timestamp": "2026-07-10T04:20:40.989011337Z"},
   {"role": "assistant", "content": "hello!", "timestamp": "2026-07-10T04:20:40.989013416Z"}
 ], "user_id": "alice"}

stats ✓ live-tested

Anzahl der Erinnerungen für einen Nutzer.

await mem.stats("alice");
Tatsächliche Antwort
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}

get ✓ live-tested

Ruft eine einzelne Erinnerung per id ab - die id, die add oder list_memories zurückgegeben hat. Nur der gespeicherte Originaltext plus Metadaten, nie der Vektor. Eine id aus einem anderen Store oder eine gelöschte/invalidierte Erinnerung ergibt 404.

const m = await mem.get("alice", "576700aa-...");
response
{"id": "576700aa-...", "content": "she prefers tea over coffee",
 "category": "general", "source_type": "user_said",
 "created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}

listMemories ✓ live-tested

Listet die Erinnerungen eines Stores auf - nur der gespeicherte Originaltext und seine Metadaten, nie der Vektor. Seitenweise per Cursor: den zurückgegebenen next_cursor für die nächste Seite mitgeben.

const page = await mem.listMemories("alice", { limit: 100 });
response
{"count": 2, "next_cursor": null, "memories": [
   {"id": "576700aa-...", "content": "she prefers tea over coffee",
    "category": "general", "source_type": "user_said",
    "created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}
 ]}

iterMemories · exportMemories

Alle Erinnerungen ohne Cursor-Verwaltung durchlaufen oder den ganzen Store auf einmal holen.

for await (const m of mem.iterMemories("alice")) console.log(m.id, m.content);
const everything = await mem.exportMemories("alice");

Löschen

delete ✓ live-tested

Eine einzelne Erinnerung per ID löschen.

await mem.delete("alice", "576700aa-...");
Tatsächliche Antwort
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}

deleteAll ✓ live-tested

Alles für einen Nutzer löschen - ein Aufruf, DSGVO-bereit.

await mem.deleteAll("alice");
Tatsächliche Antwort
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}

Fehler und Zuverlässigkeit

Jeder Fehler ist typisiert - fange den konkreten (Rate-Limit, Auth, Zahlung) oder alle mit dem Basis-WosError.

import { NotFoundError, PaymentRequiredError } from "wontopos";
try {
  await mem.add("...", "alice");
} catch (e) {
  if (e instanceof NotFoundError) await mem.createStore("alice");
  else if (e instanceof PaymentRequiredError) topUp();   // out of credit
  else throw e;
}

rateLimit

Lies das verbleibende Kontingent nach jedem Aufruf und drossle, bevor du das Limit erreichst.

await mem.search("...", "alice");
const rl = mem.rateLimit;   // { limit: 150, remaining: 3, reset: ... }
Rust-SDK

Rust - jede Methode, drei Gruppen.

Schreiben, Lesen, Löschen. Jedes Beispiel unten wurde am 2026-07-10 gegen die Live-API ausgeführt; die Antworten sind wortwörtlich wiedergegeben.

cargo add wontopos
use wontopos::Client;

let mem = Client::new("wos-live-...");

Modell wählen

Der API-Schlüssel bestimmt, welches Gedächtnis (Ihr Konto); das Modell bestimmt, welche Engine es liest. Alle Modelle teilen sich ein Gedächtnis, Sie können also mit einem speichern und mit einem anderen abrufen. Setzen Sie einen Standard mit with_model(); verketten Sie es erneut, um einen einzelnen Aufruf zu überschreiben.

let mem = Client::new("wos-live-...").with_model("tablet-1");  // default
mem.recall("...", "alice").await?;                       // tablet-1
mem.with_model("scroll-1").recall("...", "alice").await?;  // or pick a model per call

list_models ✓ live-tested

Der Katalog - die IDs, die Sie an with_model übergeben können, und ob sie jeweils live sind. Modelle mit memory: "shared" lesen denselben Store; "isolated" führt einen eigenen. Benötigt keinen API-Schlüssel.

mem.list_models().await?;
Tatsächliche Antwort
[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"},
 {"id": "scroll-1", "name": "Scroll 1", "available": true, "memory": "shared"},
 {"id": "scroll-1.2", "name": "Scroll 1.2", "available": true, "memory": "shared"}]

ping ✓ live-tested

Verbindung und Gültigkeit des API-Schlüssels in einer Zeile prüfen.

mem.ping().await?;   // Ok(true), or Err whose .kind() is Auth / PaymentRequired

Der Katalog oben spiegelt stets die aktuell verfügbaren Modelle wider - übergeben Sie eine andere ID, erhalten Sie einen klaren Fehler. Neue Modelle erscheinen dort automatisch, sobald sie ausgeliefert werden.

Schreiben

add ✓ live-tested

Eine Erinnerung speichern. Beim Eingang eingebettet - kein LLM-Aufruf, Sie zahlen nur Embeddings.

mem.add("she prefers tea over coffee", "alice", json!({})).await?;
mem.add("I promised the summary by Friday", "alice", json!({"speaker": "me"})).await?;  // its own words - no registration needed
Tatsächliche Antwort
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

add_turn ✓ live-tested

Einen Gesprächszug (Nutzer + Assistent) zugleich ins Kurzzeit- und Langzeitgedächtnis speichern.

mem.add_turn("hi", "hello!", "alice").await?;
Tatsächliche Antwort
{"status": "ok"}

speaker ✓ live-tested

Jede Erinnerung kann tragen, wer sie gesagt hat. Registriere eine Person einmal und übergib danach ihren Namen als speaker; "me" (die eigenen Worte des Assistenten) braucht nie eine Registrierung. Auch die Suche akzeptiert speaker, um nur die Worte einer Person zu holen.

mem.add_speaker("Bob", "alice").await?;  # once per person; "me" needs no registration
mem.add("I promised to send the report on Friday", "alice", json!({"speaker": "me"})).await?;
mem.add("Bob said the deadline moved to Tuesday", "alice", json!({"speaker": "Bob"})).await?;
mem.search_with("what did Bob say about deadlines?", "alice", 10, json!({"speaker": "Bob"})).await?;
Sprecher sind explizit, wie Stores. Registriere die Person zuerst, speichere dann unter ihrem Namen: ein Tippfehler wird nie still zu einer neuen Person. Ein Store registriert zunächst bis zu 50 Personen (wir planen mehr), und "me" braucht nie Registrierung und zählt nie.

add_bulk ✓ live-tested

Einen großen Textblock nachladen. Serverseitig zerlegt und eingebettet - ideal zum Import bestehender Historie.

mem.add_bulk("Alice moved to Brooklyn in March...", "alice", "general").await?;
Tatsächliche Antwort
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}

update ✓ live-tested

Ein Fakt hat sich geändert. Die alte Erinnerung wird als ersetzt markiert (für die Historie behalten); die neue nimmt ihren Platz im Recall ein.

mem.update("576700aa-...", "she switched to coffee this year", "alice").await?;
Tatsächliche Antwort
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
 "old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}

Lesen

search ✓ live-tested

Semantische Suche, das Relevanteste zuerst. Reines Embedding - kein Keyword-Matching, jede Sprache findet also jede Erinnerung. Das SDK gibt das memories-Array direkt zurück; der rohe HTTP-Body ist unten abgebildet.

let r = mem.search("what does she drink?", "alice", 1).await?;
Tatsächliche Antwort (HTTP-Body)
{"memories": [{
   "id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624",
   "content": "she prefers tea over coffee",
   "category": "general",
   "time_bucket": "2026-06",
   "importance": 0.3,
   "similarity": 0.6316057443618774,
   "is_superseded": false,
   "superseded_by": null,
   "created_at": "2026-07-10T04:20:39.688276876Z"
 }], "search_ms": 315, "total_found": 1}
FeldBedeutung
similarityRohe Embedding-Ähnlichkeit zu Ihrer Abfrage (0–1).
is_supersededTrue, wenn dieser Fakt durch update() ersetzt wurde.
search_msServerseitige Abrufzeit.

recall ✓ live-tested

Ein Roundtrip liefert alles, was Ihr LLM braucht - fügen Sie das Ergebnis direkt in Ihren Prompt ein: ein begrenzter Kontext fester Größe, egal wie viel Sie gespeichert haben.

let ctx = mem.recall("what does she drink?", "alice").await?;
Tatsächliche Antwort (Struktur - Listen gekürzt)
{"short_term":  {"count": 2, "turns": [{"role": "user", "content": "hi", ...}]},
 "long_term":   {"count": 4, "memories": [{"content": "she prefers tea over coffee",
                                           "similarity": 0.63, ...}]},
 "context":     {"count": 4, "around_top_memory": [
                  "[match] she prefers tea over coffee",
                  "[after] Alice moved to Brooklyn in March. ..."]},
 "instruction": "Use short_term for recent context, long_term for relevant
                 past memories, context for surrounding conversation of the
                 most relevant memory."}

history ✓ live-tested

Jüngste Gesprächszüge (Kurzzeitgedächtnis), älteste zuerst.

let turns = mem.history("alice").await?;
Tatsächliche Antwort (HTTP-Body)
{"count": 2, "turns": [
   {"role": "user",      "content": "hi",     "timestamp": "2026-07-10T04:20:40.989011337Z"},
   {"role": "assistant", "content": "hello!", "timestamp": "2026-07-10T04:20:40.989013416Z"}
 ], "user_id": "alice"}

stats ✓ live-tested

Anzahl der Erinnerungen für einen Nutzer.

mem.stats("alice").await?;
Tatsächliche Antwort
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}

get ✓ live-tested

Ruft eine einzelne Erinnerung per id ab - die id, die add oder list_memories zurückgegeben hat. Nur der gespeicherte Originaltext plus Metadaten, nie der Vektor. Eine id aus einem anderen Store oder eine gelöschte/invalidierte Erinnerung ergibt 404.

let m = mem.get("alice", "576700aa-...").await?;
response
{"id": "576700aa-...", "content": "she prefers tea over coffee",
 "category": "general", "source_type": "user_said",
 "created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}

list_memories ✓ live-tested

Listet die Erinnerungen eines Stores auf - nur der gespeicherte Originaltext und seine Metadaten, nie der Vektor. Seitenweise per Cursor: den zurückgegebenen next_cursor für die nächste Seite mitgeben.

mem.list_memories("alice", 100, None).await?;
response
{"count": 2, "next_cursor": null, "memories": [
   {"id": "576700aa-...", "content": "she prefers tea over coffee",
    "category": "general", "source_type": "user_said",
    "created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}
 ]}

list_all_memories

Alle Erinnerungen ohne Cursor-Verwaltung durchlaufen oder den ganzen Store auf einmal holen.

let all = mem.list_all_memories("alice").await?;   // every page, collected

Löschen

delete ✓ live-tested

Eine einzelne Erinnerung per ID löschen.

mem.delete("alice", "576700aa-...").await?;
Tatsächliche Antwort
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}

delete_all ✓ live-tested

Alles für einen Nutzer löschen - ein Aufruf, DSGVO-bereit.

mem.delete_all("alice").await?;
Tatsächliche Antwort
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}

Fehler und Zuverlässigkeit

Jeder Fehler ist typisiert - fange den konkreten (Rate-Limit, Auth, Zahlung) oder alle mit dem Basis-WosError.

use wontopos::ErrorKind;
match mem.search("...", "alice", 10).await {
    Ok(hits) => { /* use hits */ }
    Err(e) if e.kind() == ErrorKind::NotFound => { mem.create_store("alice").await?; }
    Err(e) if e.is_rate_limited() => { /* back off */ }
    Err(e) => return Err(e),
}

rate_limit

Lies das verbleibende Kontingent nach jedem Aufruf und drossle, bevor du das Limit erreichst.

mem.search("...", "alice", 10).await?;
let rl = mem.rate_limit();   // Some(RateLimit { remaining: Some(3), .. })
curl

curl - keine Installation, dieselben Methoden.

Kein SDK zu installieren - jeder HTTP-Client funktioniert. Setzen Sie Ihren Schlüssel einmal und rufen Sie dieselben Endpunkte auf, die die SDKs kapseln. Basis-URL https://api.wontopos.com, Authentifizierung über X-API-Key, JSON rein und raus.

# set your key once (never hard-code it)
export WOS_API_KEY="wos-live-..."

Schreiben

store ✓ live-tested

Eine Erinnerung speichern. Beim Eingang eingebettet - kein LLM-Aufruf.

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"she prefers tea over coffee"}'
Tatsächliche Antwort
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

store-turn ✓ live-tested

Einen Gesprächszug (Nutzer + Assistent) zugleich ins Kurzzeit- und Langzeitgedächtnis speichern.

curl -X POST https://api.wontopos.com/api/v1/memory/store-turn \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","user_msg":"hi","assistant_msg":"hello!"}'
Tatsächliche Antwort
{"status": "ok"}

speaker ✓ live-tested

Jede Erinnerung kann tragen, wer sie gesagt hat. Registriere eine Person einmal und übergib danach ihren Namen als speaker; "me" (die eigenen Worte des Assistenten) braucht nie eine Registrierung. Auch die Suche akzeptiert speaker, um nur die Worte einer Person zu holen.

curl -X POST https://api.wontopos.com/api/v1/memory/speakers \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","speaker":"Bob"}'   # once per person

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"I promised to send the report on Friday","metadata":{"speaker":"me"}}'

curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"Bob said the deadline moved to Tuesday","metadata":{"speaker":"Bob"}}'

curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what did Bob say about deadlines?","speaker":"Bob"}'
Sprecher sind explizit, wie Stores. Registriere die Person zuerst, speichere dann unter ihrem Namen: ein Tippfehler wird nie still zu einer neuen Person. Ein Store registriert zunächst bis zu 50 Personen (wir planen mehr), und "me" braucht nie Registrierung und zählt nie.

supersede ✓ live-tested

Ein Fakt hat sich geändert - die alte Erinnerung wird als ersetzt markiert, die neue nimmt ihren Platz im Recall ein.

curl -X POST https://api.wontopos.com/api/v1/memory/supersede \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","old_memory_id":"576700aa-...","new_content":"she switched to coffee this year"}'
Tatsächliche Antwort
{"new_memory_id": "07e94433-...", "old_memory_id": "576700aa-...", "status": "superseded"}

Lesen

search ✓ live-tested

Semantische Suche, das Relevanteste zuerst. Reines Embedding - jede Sprache findet jede Erinnerung.

curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what does she drink?","max_results":1}'
Tatsächliche Antwort
{"memories": [{"id": "576700aa-...", "content": "she prefers tea over coffee",
   "similarity": 0.63, "is_superseded": false}], "search_ms": 315, "total_found": 1}

recall ✓ live-tested

Ein Roundtrip liefert Kurzzeit + Langzeit + Kontext + eine Instruktion. Fügen Sie es direkt in Ihren Prompt ein.

curl -X POST https://api.wontopos.com/api/v1/memory/recall \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what does she drink?"}'
Tatsächliche Antwort (Struktur)
{"short_term": {"count": 2, "turns": [...]},
 "long_term":  {"count": 4, "memories": [{"content": "she prefers tea over coffee", "similarity": 0.63}]},
 "context":    {"count": 4, "around_top_memory": ["[match] she prefers tea over coffee"]},
 "instruction": "Use short_term for recent context, long_term for relevant past memories..."}

Löschen

forget ✓ live-tested

Eine Erinnerung per ID löschen - oder die ID weglassen, um alles für einen Nutzer zu löschen (DSGVO).

curl -X POST https://api.wontopos.com/api/v1/memory/forget \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice"}'  # omit memory_id = delete all
Tatsächliche Antwort
{"memories_deleted": 1, "status": "deleted", "user_id": "alice"}

Jeder Endpunkt + Body-Felder →

Engramme

Engrams

Aufrufbare Recall-Werkzeuge, die Ihr Modell einsetzen kann - jedes eine eigene Abrufstrategie über dasselbe Gedächtnis. Nutzen Sie eines oder führen Sie mehrere zugleich aus.

Ab sofort verfügbar. Die allgemeinen Engramme unten sind Abruf-Pipelines ohne LLM und laufen daher auf jeder Stufe ab Tablet 1. Memoir und Archive, ein separater Modellmodus, werden weiter unten in einem eigenen Abschnitt behandelt.

Regelmäßig erscheinen weitere Engramme - diese Liste wächst.

Memoir & Archive Scroll 1.2+

Dies ist eine Auslieferungs-Form, kein aufrufbares Werkzeug. Ab Scroll 1.2 wählen Sie sie pro Aufruf - form: "memoir" oder form: "archive" - und dieser Recall, eine einfache Suche eingeschlossen, kommt mit entsprechend geschriebener Zeit zurück.

Alle Engramme Engramme

Time_awareness Scroll 1.2+

Eine Auslieferungsform - pro Aufruf gewählt. Übergeben Sie form - memoir oder archive - bei einem beliebigen Aufruf eines formfähigen Modells (ab Scroll 1.2), und die Antwort kommt entsprechend gerendert zurück: eine einfache Suche, ein Recall oder jedes Engramm. In den SDKs ist es ein form-Feld wie tz; über HTTP der Header X-WOS-Form. Ein Memoir liest sich, wie ein Mensch sich erinnert; ein Archive führt ein exaktes Protokoll - der Unterschied zeigt sich am deutlichsten darin, wie beide die Zeit schreiben.

Memoir

form: "memoir"
Erinnert wie ein Mensch · eine Erzählung

Erzählt, was geschah und wie ein Moment zum nächsten führte, mit dem weichen Zeitgefühl menschlicher Erinnerung - liest sich als Erlebnis, nicht als Liste.

Archive

form: "archive"
Geführt als Protokoll · präzise Zeit

Liefert Treffer als exakte Datensätze - präzise verstrichene Zeit und absolute Anker, so strukturiert, dass ein Modell sie direkt ablesen kann.

Es rendert Erinnerungen, die Sie bereits gespeichert haben - es erzeugt keine. Jede Erinnerung ist ein store-/add-Aufruf unter einer user_id (diese user_id ist der Store dieser Person). Zuerst speichern; danach kommt jeder Recall - die einfache Suche unten eingeschlossen - mit Zeitmarkierung zurück. Siehe Schnellstart zum Speichern.
# plain search - no engram - the memoir form on Scroll 1.2
r = mem.search("what does Alice drink?", user_id="alice", model="scroll-1.2", form="memoir", tz=9)
# every hit gets a .time field → "a couple weeks ago"  (form="archive" → "2 weeks ago (Jun 09)")
// plain search - no engram - the memoir form on Scroll 1.2
const r = await mem.withModel("scroll-1.2").search("what does Alice drink?", "alice", 10, { form: "memoir", tz: 9 });
// search_with merges extra fields into the body - form picks the render, tz the local clock
let r = mem.with_model("scroll-1.2").search_with("what does Alice drink?", "alice", 10, json!({"form": "memoir", "tz": 9})).await?;
curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: wos-live-..." -H "X-WOS-Model: scroll-1.2" -H "X-WOS-Form: memoir" -H "X-WOS-Timezone: 9" \
  -d '{"user_id":"alice","query":"what does Alice drink?"}'
# each memory comes back with a "time" field; use X-WOS-Form: archive for exact time

tz ist der UTC-Versatz des Aufrufers in Stunden - damit "heute Morgen" und die 4-Uhr-Tagesgrenze in dessen Ortszeit landen. Weglassen für UTC; über HTTP ist es der X-WOS-Timezone-Header. Grob nach Region: US-Ostküste -5, US-Zentral -6, US-Westküste -8 · UK / Lissabon 0 · Mitteleuropa +1 · Osteuropa +2 · Indien +5.5 · China / Singapur +8 · Korea / Japan +9 · Sydney +10. (Normalzeit - die Sommerzeit verschiebt manche Regionen um +1; übergeben Sie, was für Ihre Nutzer tatsächlich gilt.)

Dieselbe Suche, zwei Formen - die Erinnerungen sind identisch, nur time ändert sich:

Ergebnis · form: memoir
{ "count": 3, "memories": [
  { "content": "Alice prefers tea over coffee", "time": "a couple weeks ago" },
  { "content": "met Alice at the cafe downtown",  "time": "yesterday afternoon" },
  { "content": "Alice moved to Brooklyn",          "time": "about half a year ago" }
] }
Ergebnis · form: archive
{ "count": 3, "memories": [
  { "content": "Alice prefers tea over coffee", "time": "2 weeks ago (Jun 09)" },
  { "content": "met Alice at the cafe downtown",  "time": "yesterday at 14:00" },
  { "content": "Alice moved to Brooklyn",          "time": "6 months ago (Dec 2025)" }
] }
VerstrichenMemoirArchive
3 Min.a few minutes ago3 minutes ago
14 Min.about 15 minutes ago14 minutes ago
30 Min.half an hour ago30 minutes ago
50 Min.about an hour ago50 minutes ago
2 Std.a couple hours ago2 hours ago, at 13:10
8 Std.this morning8 hours ago, at 07:10
gestern Nachm.yesterday afternoonyesterday at 14:00
letzte Nachtlast night17 hours ago, at 22:00
2 Tagea couple days ago2 days ago (Tue 15:10)
6 Tageseveral days ago6 days ago (Fri 15:10)
9 Tageabout a week agolast week (Jun 16)
16 Tagea couple weeks ago2 weeks ago (Jun 09)
35 Tageabout a month agolast month (May 21)
60 Tagea couple months ago2 months ago (Apr 2026)
180 Tageabout half a year ago6 months ago (Dec 2025)
380 Tageabout a year agolast year (Jun 2025)
800 Tagea couple years ago2 years ago (Apr 2024)
1500 Tageabout 4 years ago4 years ago (May 2022)

Jeder Wert oben ist die tatsächliche Ausgabe des Renderers. Betrachten Sie die beiden "gestern"-Zeilen: Ein Memoir trennt den Nachmittag von der letzten Nacht - ein Tag ist ein Schlaf - während ein Archive eine einzelne Uhrzeit schreibt und keine Tag-Nacht-Grenze zieht.

Wie jeder Modus die Zeit liest

Memoir - so, wie Menschen es tatsächlich sagen. Jüngste Momente bleiben recht scharf (etwa 15 Minuten, eine halbe Stunde), dann weitet sich die Formulierung, je weiter man zurückgeht - ein paar Wochen, etwa ein halbes Jahr, ein paar Jahre - so, wie sich Erinnerung selbst mit der Entfernung lockert. Innerhalb eines Tages weicht die Uhr einem Orientierungspunkt: heute Morgen, letzte Nacht, gestern Nachmittag. Und ein Tag ist ein Schlaf, kein Kalendersprung: Die Grenze liegt bei etwa 4 Uhr Ortszeit, sodass eine späte Nacht noch als derselbe Abend gilt, nicht schon als morgen.

Archive - präzise, stets mit Anker. Jede Zeile trägt die exakte verstrichene Zeit plus eine absolute Referenz, mit der ein Modell rechnen kann, und der Anker wird enger, je näher es rückt: eine Uhrzeit für heute (vor 8 Stunden, um 07:10), Wochentag und Uhrzeit für diese Woche (vor 2 Tagen (Di 15:10)), ein Datum für diesen Monat (letzte Woche (16. Jun)), Monat und Jahr darüber hinaus (vor 6 Monaten (Dez 2025)). Nie vage, nie falsch.

Memoir und Archive rendern jeden Recall der Antwort - eine einfache Suche, ein Recall oder ein Engramm. Die Modellstufe (Tablet → Scroll → Codex) bestimmt, wie viel die Engine leistet; die Form (memoir / archive) bestimmt, wie sie die Zeit schreibt. Verfügbar ab Scroll 1.2.
Alle Engramme Engramme

deep_recall

Multi-Hop-Recall. Sucht nach Ihrer Abfrage, nimmt dann den besten Treffer und sucht erneut nach dessen Inhalt - und holt so verknüpften Kontext ein, den eine einzelne Suche übersehen würde. Am stärksten, wenn Erinnerungen aufeinander verweisen (eine Person → ihre Projekte → Details). Liefert bis zu ~12.

out = mem.engram("deep_recall", "what should I know about Alice?", user_id="alice")
const out = await mem.engram("deep_recall", "what should I know about Alice?", "alice");
let out = mem.engram("deep_recall", "what should I know about Alice?", "alice").await?;
curl -X POST https://api.wontopos.com/api/v1/engram/run \
  -H "X-API-Key: wos-live-..." -H "Content-Type: application/json" \
  -d '{"name":"deep_recall","user_id":"alice","query":"what should I know about Alice?"}'
Antwort
{ "engram": "deep_recall", "hops": 2, "count": 12,
  "memories": [ ... ],
  "usage": { "input_tokens": 5, "output_tokens": 61 } }
Abgerechnet nach Tokens - jeder Aufruf liefert usage (Eingabe + Ausgabe), gezählt mit demselben Tokenizer wie der Rest der API; keine versteckte Gebühr pro Engramm. Mehrere zugleich nötig? Rufen Sie sie parallel auf - jedes Engramm ist eine unabhängige Anfrage.
Alle Engramme Engramme

timeline

Zeitlich geordneter Recall. Liefert Erinnerungen neueste zuerst, sortiert nach dem Zeitpunkt des Ereignisses, nicht nach Relevanz. Für "Wann war X", Verlauf und Reihenfolgefragen. Liefert bis zu 15.

events = mem.engram("timeline", "project milestones", user_id="alice")
const events = await mem.engram("timeline", "project milestones", "alice");
let events = mem.engram("timeline", "project milestones", "alice").await?;
curl -X POST https://api.wontopos.com/api/v1/engram/run \
  -H "X-API-Key: wos-live-..." -H "Content-Type: application/json" \
  -d '{"name":"timeline","user_id":"alice","query":"project milestones"}'
Antwort
{ "engram": "timeline", "hops": 1, "count": 15,
  "memories": [ ... ],
  "usage": { "input_tokens": 4, "output_tokens": 88 } }
Abgerechnet nach Tokens - jeder Aufruf liefert usage (Eingabe + Ausgabe), gezählt mit demselben Tokenizer wie der Rest der API; keine versteckte Gebühr pro Engramm. Mehrere zugleich nötig? Rufen Sie sie parallel auf - jedes Engramm ist eine unabhängige Anfrage.
Alle Engramme Engramme

gather

Breites Sammeln. Sucht und erweitert dann um die besten drei Treffer herum - ein weiteres Netz als deep_recall. Damit holen Sie alles zu einer Person, einem Projekt oder einem Thema in einem Aufruf ein. Liefert bis zu ~18.

related = mem.engram("gather", "everything about Project Atlas", user_id="alice")
const related = await mem.engram("gather", "everything about Project Atlas", "alice");
let related = mem.engram("gather", "everything about Project Atlas", "alice").await?;
curl -X POST https://api.wontopos.com/api/v1/engram/run \
  -H "X-API-Key: wos-live-..." -H "Content-Type: application/json" \
  -d '{"name":"gather","user_id":"alice","query":"everything about Project Atlas"}'
Antwort
{ "engram": "gather", "hops": 4, "count": 18,
  "memories": [ ... ],
  "usage": { "input_tokens": 6, "output_tokens": 142 } }
Abgerechnet nach Tokens - jeder Aufruf liefert usage (Eingabe + Ausgabe), gezählt mit demselben Tokenizer wie der Rest der API; keine versteckte Gebühr pro Engramm. Mehrere zugleich nötig? Rufen Sie sie parallel auf - jedes Engramm ist eine unabhängige Anfrage.
HTTP-API

Jeder Endpunkt, eine Basis-URL.

Kein SDK erforderlich - jeder HTTP-Client funktioniert. Basis-URL https://api.wontopos.com, Authentifizierung über den X-API-Key-Header, JSON rein und raus. Memory-Operationen sind POST; die Verwaltung von Stores nutzt POST / GET / DELETE auf /collection. Ein Store muss zuerst existieren (siehe Stores), sonst liefern Operationen im Store 404.

EndpunktZweckBody-Felder
POST /api/v1/memory/collectionStore anlegenuser_id
GET /api/v1/memory/collectionsIhre Stores auflisten(keine)
DELETE /api/v1/memory/collectionStore + seine Erinnerungen löschenuser_id
/api/v1/memory/storeeine Erinnerung speichernuser_id · content · metadata? (speaker)
/api/v1/memory/store-turneinen Gesprächszug speichernuser_id · user_msg · assistant_msg
POST /api/v1/memory/speakersSprecher registrieren (explizit, bis 50)user_id · speaker
GET /api/v1/memory/speakersregistrierte Sprecher + Zähler auflistenuser_id
DELETE /api/v1/memory/speakersSprecher abmelden (Erinnerungen bleiben)user_id · speaker
/api/v1/memory/bulk-storeeinen Textblock nachladenuser_id · content · category?
/api/v1/memory/searchsemantische Sucheuser_id · query · max_results? · speaker?
/api/v1/memory/recallKurzzeit + Langzeit + Kontextuser_id · query
/api/v1/memory/historyjüngste Gesprächszügeuser_id
/api/v1/memory/statsAnzahl der Erinnerungenuser_id
/api/v1/memory/supersedeeinen geänderten Fakt ersetzenuser_id · old_memory_id · new_content
/api/v1/memory/forgeteine (oder alle) löschenuser_id · memory_id? (weglassen = alle löschen)
# create the store once (stores are explicit)
curl -X POST https://api.wontopos.com/api/v1/memory/collection \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice"}'

# store a memory
curl -X POST https://api.wontopos.com/api/v1/memory/store \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","content":"she prefers tea over coffee"}'

# recall - one call, ready for your prompt
curl -X POST https://api.wontopos.com/api/v1/memory/recall \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice","query":"what does alice drink?"}'
Tatsächliche Antwort - store
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}
Nutzungsstufen

Dieselben Funktionen für alle.
Stufen erhöhen nur Ihre Limits.

Jede Stufe nutzt die vollständige Engine - dieselbe Recall-Qualität, dieselben Sprachen, jede Methode. Die Stufen steigen automatisch bis Stufe 5, während Ihre kumulierten Guthabenkäufe wachsen - ohne Antrag oder Vertriebsgespräch. Enterprise (Stufe 6) ist die einzige Ausnahme.

Ausgabenlimits

Jede Stufe begrenzt, wie viel Sie pro Kalendermonat ausgeben können. Sie steigen sofort auf, sobald Ihre kumulierten Guthabenkäufe die nächste Schwelle erreichen.

NutzungsstufeGuthabenkaufMonatliches Ausgabenlimit
Tier 1$5$100
Tier 2$40$500
Tier 3$200$1,000
Tier 4$400$5,000
Tier 5$1,000$25,000
Tier 6 - EnterpriseSprechen Sie mit unsKein Limit

Rate-Limits

Rate-Limits gelten pro Konto - alle API-Schlüssel eines Kontos teilen sich ein Limit, das mit Ihrer Stufe skaliert. Bei Überschreitung kommt ein 429 mit einem retry-after-Header zurück; warten Sie gestaffelt (1s → 2s → 4s) und versuchen Sie es erneut. Jeder Endpunkt ist idempotenzfreundlich, Wiederholungen sind also sicher.

StufeAnfragen pro Minute
Tier 1150
Tier 2300
Tier 3600
Tier 41,500
Tier 53,000
Tier 6 - EnterpriseIndividuell

Enterprise (Stufe 6) erhält individuelle Rate-Limits, ein SLA, dedizierten Support und optional eine Self-Host-Lizenz - sprechen Sie mit uns.

Die Preise sind nutzungsbasiert: Tokens plus pauschal $0.0001 pro Anfrage. Tablet kostet $2 pro 1M Eingabe-Tokens, $3 pro 1M Ausgabe-Tokens. Speicherung ist kostenlos und ohne Obergrenzen. Siehe warum wir so bepreisen.
Fehler & Limits

Wenn etwas schiefgeht.

Fehler kommen als JSON-Umschlag zurück, mit einem stabilen type, einer menschenlesbaren Meldung und einer request_id, die Sie uns bei der Meldung eines Problems mitschicken können.

Tatsächliche Antwort - ungültiger Schlüssel (HTTP 401)
{"type": "error", "error": {
   "type": "authentication_error",
   "message": "Invalid or revoked API key.",
   "request_id": "063f8b83-eee2-4383-a5cf-11e4bcd29d7c"
 }}
HTTPBedeutungWas zu tun ist
401Ungültiger oder widerrufener API-SchlüsselPrüfen Sie den Schlüssel; stellen Sie in der Konsole einen neuen aus.
422Fehlerhafter Body (fehlendes Feld oder falscher Typ)Die Meldung nennt das genaue Feld - korrigieren und erneut versuchen.
429Rate-Limit erreichtExponentiell warten (1s → 2s → 4s) und erneut versuchen. Sicher: Alle Endpunkte sind idempotenzfreundlich.
5xxServerseitiges ProblemMit Backoff erneut versuchen; geben Sie die request_id an, wenn Sie uns kontaktieren.
# SDK error handling (Python)
from wontopos import Client, WosError

try:
    mem.search("...", user_id="alice")
except WosError as e:
    if e.status == 401: ...  # bad key
    elif e.status == 429: ...  # back off and retry
Schlüsselsicherheit. Ihr Schlüssel wird bei der Erstellung einmal angezeigt und bei uns nur als Hash gespeichert. Bewahren Sie ihn in einer Umgebungsvariable auf; falls er durchsickert, widerrufen Sie ihn in der Konsole - der Widerruf wirkt sofort.

Rate-Limits gelten pro Konto, geteilt über alle Ihre Schlüssel, und skalieren mit Ihrer Stufe - siehe Nutzungsstufen. Die Nutzung Ihres Kontos sehen Sie in der Konsole.

Self-Hosting

Ihre Server, Ihre Daten.

Die Engine kann in Ihrer eigenen Infrastruktur laufen - dieselbe API, dieselben SDKs. Richten Sie den Client auf Ihren Host, und sonst ändert sich nichts.

mem = Client(api_key="...", base_url="https://wos.your-host.com")
const mem = new Client({ apiKey: "...", baseUrl: "https://wos.your-host.com" });
let mem = Client::with_base_url("...", "https://wos.your-host.com");
  • Datenresidenz. Erinnerungen verlassen Ihr Netzwerk nie.
  • Dieselbe Oberfläche. Dieselben Methoden und Endpunkte funktionieren identisch.
  • Lizenzierung. Self-Host-Pakete werden pro Deployment vereinbart - kontaktieren Sie uns.
Skalierung

Jenseits des Kontextfensters.

WOS ruft aus Historien von 1.4M Tokens ab - weit größer als jedes LLM-Kontextfenster - und liefert dennoch einen kompakten Ausschnitt von ~1.470 Tokens zurück.

Das Gedächtnis Ihres Agenten ist nicht dadurch begrenzt, was in einen Prompt passt. Es behält alles und ruft nur das Wesentliche ab, egal wie groß die Historie wird.

Datenschutz

Privat, und Ihr Eigentum.

Ihre Daten bleiben in Ihrem Store. Wir trainieren nie darauf, sehen sie nicht ein und verwenden sie nicht weiter - wir organisieren sie nur, damit Sie sie abrufen können.

  • BYOK. Ihr LLM-Schlüssel wird pro Anfrage gesendet und nie gespeichert.
  • Isoliert. Erinnerungen sind pro Konto und darin pro user_id abgegrenzt.
  • DSGVO-Löschung & Self-Hosting. Ein Aufruf löscht einen Nutzer vollständig; auf Wunsch betreiben Sie die Engine in Ihrer eigenen Umgebung.