Pourquoi WOS

Une mémoire à long terme pour les agents IA.

WOS est une API de mémoire. Vous stockez une fois les souvenirs d'un utilisateur, puis ne rappelez que ceux qui sont pertinents pour chaque requête et les transmettez au prompt de votre modèle.

La récupération est purement sémantique, sans correspondance par mots-clés ni BM25 : la qualité du rappel est donc identique d'une langue à l'autre. Chaque requête renvoie un contexte réduit et borné, quel que soit le volume stocké, et aucun modèle n'est jamais exécuté sur vos souvenirs stockés.

Opérations de base

  • store - enregistre un souvenir pour un utilisateur.
  • recall - récupère les souvenirs pertinents pour une requête. C'est l'appel principal.
  • search - recherche sémantique brute sur les souvenirs stockés.
  • supersede - met à jour ou remplace un souvenir devenu obsolète.
  • forget - supprime un souvenir unique ou un utilisateur entier (RGPD).
Choisissez une section à gauche pour le détail de chaque sujet.
Modèle

Trois modèles, une même lignée.

Les modèles WOS portent le nom des supports par lesquels l'humanité a conservé le savoir au fil de l'histoire - Tablet, Scroll, Codex. La pierre, le rouleau, le livre relié : chacun apporte davantage à votre agent que le précédent.

Tablet

Disponible
Gravé dans la pierre · store & recall

Un moyen sobre, rapide et économique d'inscrire et de rappeler la mémoire - la fondation sur laquelle chaque modèle s'appuie.

Scroll

Disponible
Déroulé · rappel assisté par LLM

Ajoute un modèle de langage qui lit votre question de plus près et ramène un contexte plus complet, pour que les indices dispersés reviennent ensemble au lieu qu'il en manque un.

Codex

À venir
Relié & indexé · routage autonome

S'ouvre de lui-même à la bonne page - il choisit la mémoire et les outils dont chaque instant a besoin, et s'affine à mesure qu'on l'utilise.

Le rapport de benchmark complet de Tablet 1 se trouve sur la page benchmark.

Coût

Payez-nous $2. Économisez plusieurs fois ce montant sur votre LLM.

WOS fournit à votre LLM ~1,200 tokens par requête - une tranche bornée et pertinente - au lieu d'entasser l'historique complet dans chaque prompt. L'écart est énorme, et il grandit avec votre historique.

Coût LLM pour 1,000 requêtes Basé sur Tablet 1
Historique utilisateur100K
Requêtes / mois1,000
Votre LLM
45× moins cher - vous économisez $244/mois
Sans WOS$250.00
Avec WOS$5.50

Chaque $1 dépensé sur WOS fait économiser ~$98 sur le LLM. Un historique plus grand ou un modèle plus cher → un ROI plus grand.

D'où viennent les économies

  • Sans WOS, vous entassez l'historique entier dans chaque prompt - 100K tokens × $2.50/1M = $0.25 par requête, au tarif d'entrée de GPT-4o (environ 2× plus sur les modèles de classe Opus).
  • Avec WOS, vous ingérez une fois ($2/1M), puis chaque requête n'est qu'une petite récupération ($3/1M × 1,200) plus votre LLM sur seulement ~1,200 tokens.
  • Moins votre LLM lit de tokens, moins vous payez - et WOS garde ce nombre constant à mesure que la mémoire grandit.
Réduction de contexte = historique ÷ tokens fournis, pas le coût (le calculateur ci-dessus facture chaque récupération).  25K → 21× · 100K → 83× · 200K → 167×.
Multilingue

Toutes les langues, la même précision.

La récupération est purement sémantique - embeddings uniquement, zéro correspondance par mots-clés ou BM25. La qualité du rappel est donc identique que vos utilisateurs écrivent en 日本語, en 中文, en Español ou en anglais.

La correspondance lexicale comme BM25 est calibrée sur la forme d'une langue donnée - morphologie, espacement, écriture. Dans un store multilingue, la qualité de récupération varie alors selon la langue. WOS n'utilise aucune correspondance lexicale : toutes les langues empruntent le même chemin.

Un seul store, trois langues à la fois

Vous ne choisissez pas une langue par store - mélangez-les librement. Ci-dessous, la mémoire d'un même utilisateur contient à la fois du japonais, de l'anglais et de l'espagnol, et chaque question retrouve le bon souvenir quelle que soit la langue. Il s'agit d'un échange réel avec l'API en production :

# 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
Résultats réels - chaque question bascule vers une langue différente
"¿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

Aucune étape de traduction, aucune détection de langue, aucune configuration par langue. Souvenirs et questions sont placés selon le sens, pas selon la langue - si le sens correspond, la langue n'a pas d'importance.

Trois langues ici, c'est simplement ce qui tient sur une page - il n'existe aucune liste de langues prises en charge à laquelle figurer. Le même test en conditions réelles passe aussi avec des souvenirs en 中文, en Русский et en العربية, tous vérifiés contre l'API de production.

Pourquoi nous avons banni les mots-clés à dessein

Un scoring lexical tel que BM25 renforce la récupération pour certaines langues plus que pour d'autres, ce qui pose problème quand un même store contient de nombreuses langues. Nous l'avons donc entièrement retiré du moteur et faisons respecter cette règle en revue de code : avec le moindre scoring lexical dans le chemin, la qualité du rappel varierait selon la langue.

LongMemEval est uniquement en anglais et ne mesure donc pas le rappel multilingue. La démonstration ci-dessus montre comment le vérifier directement contre l'API en production.
Architecture

Aucun modèle ne s'exécute sur vos souvenirs.

Le stockage est verbatim et le moteur cherche par embeddings - économique, rapide et déterministe. Un modèle n'est jamais exécuté sur vos souvenirs stockés. Tablet n'utilise aucun modèle ; Scroll et Codex en ajoutent un autour du moteur pour de meilleurs résultats, mais il ne voit jamais que votre requête, jamais ce que vous avez stocké.

  • Moteur déterministe. Le moteur renvoie les mêmes souvenirs pour la même requête, à chaque fois - c'est pourquoi la variance de notre benchmark provient uniquement du modèle lecteur.
  • Économique à grande échelle. Aucun coût de génération pour stocker ou récupérer : votre facture suit le stockage - pas l'usage de modèle - à mesure que la mémoire grandit.

Vos mots, intacts

Une conception courante exécute un modèle de langage à l'écriture pour extraire et réécrire des « faits » à partir du texte. Cette conception sacrifie trois choses : un coût de génération à chaque écriture, une latence supplémentaire, et le stockage d'une paraphrase du modèle plutôt que des mots d'origine. WOS fait le choix inverse - il stocke ce qui a été dit, sans modification, et laisse votre LLM interpréter à la lecture, le texte original en main.

Ce que WOS n'est pas : ni une base vectorielle à opérer vous-même, ni un framework RAG à assembler. Aucun modèle n'est jamais exécuté sur vos données stockées - ce chemin est purement embeddings. Scroll et Codex utilisent bien un modèle de langage pour de meilleurs résultats, mais il ne voit jamais que votre requête, jamais vos souvenirs stockés - et il ne s'entraîne jamais sur vos données ni ne les collecte.
Preuve

90.7%, mesuré et reproductible.

90.7% sur LongMemEval-S, en moyenne sur 5 runs indépendants (σ 0.5%, aucun trié sur le volet), noté par le juge canonique GPT-4o du benchmark.

Sur le même benchmark, les scores varient fortement selon le protocole de notation - le juge, le prompt, et ce que la couche de récupération est autorisée à faire. Nous utilisons le juge tiers canonique GPT-4o du benchmark tel que publié, ne modifions rien pour coller au test, et publions le code de notation et le prompt du lecteur pour que chacun puisse reproduire exactement les 90.7%.

Le protocole, en un tableau

ÉlémentCe que nous faisons
Jeu de donnéesLongMemEval-S (nettoyé), ~240K tokens d'historique par question
JugeLe juge canonique GPT-4o du benchmark - un tiers, pas nous
Runs5 runs indépendants, chaque score publié, moyenne rapportée (σ 0.5%)
LecteurModèle lecteur et prompt fixes, publiés verbatim

Ce qui garantit l'honnêteté : un juge tiers, le prompt du lecteur publié tel quel, une récupération purement sémantique, et chaque run rapporté - pas seulement le meilleur. Le moteur de récupération est déterministe - relancez-le et vous obtenez les mêmes souvenirs.

Nous gravissons des benchmarks plus difficiles

Nous testons sur le benchmark standard le plus difficile que nous n'avons pas encore conquis - et le chiffre affiché est le record parmi tous les modèles WOS, réécrit chaque fois qu'un meilleur modèle sort. Passé 94%, nous passons à un benchmark plus difficile.

LongMemEval-SEn cours
Tablet 185.2%
Scroll 190.7%
Juge GPT-4o · meilleur score parmi tous les modèles WOS94% pour passer au suivant
Voir le rapport complet
Tarifs

Deux tarifs de tokens par modèle,
plus $0.0001 par requête.

Par million de tokens plus $0.0001 fixe par requête, à l'usage. Pas d'abonnement, pas de loyer de stockage, pas de plafond de mémoire. Vous payez quand votre agent écrit ou lit - jamais pour ce qu'il retient.

ModèleEntrée / 1MSortie / 1M
Tablet 1$2$3Disponible
Scroll 1$4$8Disponible
Codex 1--À définir
  • $0.0001 par requête. Des frais fixes sur chaque appel API, en plus de l'usage en tokens.
  • Le stockage est gratuit. L'ingestion se paie une fois ; la conservation ne coûte rien. Aucune limite de nombre, aucune limite de rétention.
  • Nous le stockons. Nous ne nous entraînons jamais dessus, ne l'utilisons jamais et ne le regardons jamais. La mémoire de votre agent vous appartient - nous ne faisons que l'organiser pour que vous puissiez la retrouver.
  • Pourquoi Tablet est si peu cher : son moteur n'exécute aucun modèle, notre coût se limite donc aux embeddings et au disque - pas aux GPU. Scroll et Codex ajoutent un modèle, et c'est ce que couvre leur prix plus élevé.
D'autres modèles de facturation font payer chaque mois le volume stocké ou plafonnent le nombre de souvenirs selon le plan. WOS ne facture rien pour les données stockées, quel que soit leur volume ou leur âge.

Limites de débit par palier d'utilisation →

Pour les développeurs

Trois appels : store, recall, answer.

Une seule API. L'appel recall() renvoie le court terme, le long terme et le contexte environnant en un seul aller-retour, prêt à être inséré dans votre prompt.

1

Store

add() les faits et les tours de conversation de votre utilisateur. Encodé en embeddings à l'entrée - aucun LLM.

2

Recall

recall() renvoie court terme + long terme + contexte en un seul appel - un contexte borné, de taille fixe.

3

Answer

Fournissez ce contexte borné à votre LLM - n'importe quel fournisseur, votre clé.

from wontopos import Client
mem = Client(api_key="wos-...")
mem.add("she prefers tea over coffee", user_id="alice")
# one call: short + long + context
ctx = mem.recall("what does alice drink?", user_id="alice")
Démarrage rapide

Votre premier recall en 5 minutes.

Une clé, une ligne d'installation, trois appels - votre agent a de la mémoire. Chaque extrait de cette page a réellement été exécuté ; les réponses sont montrées verbatim.

1

Obtenir une clé API

Créez-en une dans la console. Une clé de 155 caractères commençant par wos-live- est affichée une seule fois. Gardez-la dans une variable d'environnement - jamais dans le code.

2

Installation

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

Créez un store, puis store & recall

Un store est le user_id sous lequel vous lisez et écrivez. Les stores sont explicites : créez-en un d'abord (l'appel ci-dessous), puis stockez et rappelez sous celui-ci. Store - encodé en embeddings à l'entrée, aucun appel LLM. Recall - court terme + long terme + contexte en un seul aller-retour.

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?"}'
Réponse réelle - create_store()
{"user_id": "alice", "status": "created"}
Réponse réelle - add()
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}
Définissez le store une seule fois. Passez user_id au client et chaque appel l'utilise - inutile de le répéter ; surchargez un appel isolé en lui passant user_id. Les stores sont explicites : stocker dans un store inexistant ou rappeler depuis celui-ci renvoie 404 - créez-le d'abord. Chaque compte démarre avec un store default : sans aucun user_id, le chemin zéro configuration fonctionne donc tel quel. Voir Stores pour les lister et les gérer.

recall() renvoie quatre blocs - short_term (tours récents), long_term (souvenirs pertinents), context (ce qui entourait la meilleure correspondance) et une instruction indiquant au LLM comment les utiliser. Insérez l'ensemble tel quel dans votre prompt.

Fonctionne dans toutes les langues. Stockez en anglais, interrogez en coréen, en japonais ou en chinois - le même souvenir revient. Recherche par embeddings, pas de correspondance par mots-clés.

Chaque méthode, par langage →

Stores

Stores - créer, lister, supprimer.

Un store est le user_id sous lequel vous lisez et écrivez - un espace mémoire isolé par utilisateur final, agent ou sujet. Les stores sont explicites : créez-en un avant d'y stocker ou d'y rappeler, sinon l'appel renvoie 404. Chaque compte démarre avec un store default, vous pouvez donc commencer sans appel de création.

Comment l'isolation s'emboîte. Un compte possède des workspaces ; chaque workspace isole sa propre mémoire, ses clés API et son usage (la facturation est partagée au niveau du compte). Un store vit à l'intérieur d'un workspace : les clés d'un même workspace partagent ses stores, et deux workspaces différents ne voient jamais la mémoire l'un de l'autre. 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"}'
Réponse réelle - create
{ "user_id": "alice", "status": "created" }   // "exists" if it already did
Réponse réelle - 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 sur un store inexistant
{ "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." } }
Utilisez un store par utilisateur final ("alice", "user_42") pour garder la mémoire de chaque personne séparée, ou un unique store default pour un agent personnel. Vous pouvez aussi créer et parcourir les stores dans la console (Memory ids → Issue) sans écrire de code. La suppression d'un store est définitive - elle efface tous les souvenirs qu'il contient.
SDK Python

Python - chaque méthode, en trois groupes.

Écrire, lire, supprimer. Chaque exemple ci-dessous a été exécuté contre l'API en production le 2026-06-10 ; les réponses sont verbatim.

pip install wontopos
from wontopos import Client

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

Choisir un modèle

La clé API détermine quelle mémoire (votre compte) ; le modèle détermine quel moteur la lit. Tous les modèles partagent une même mémoire : vous pouvez donc stocker avec l'un et rappeler avec un autre. Définissez un défaut sur le client ; surchargez un appel isolé en passant model=.

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

list_models ✓ live-tested

Le catalogue - les ids que vous pouvez passer à model et la disponibilité de chacun. Les modèles memory: "shared" lisent le même store ; "isolated" garde le sien. Aucune clé API requise.

mem.list_models()
Réponse réelle
[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"}]

Le catalogue ci-dessus reflète toujours les modèles disponibles à l'instant même - passez tout autre id et vous obtenez une erreur claire. Les nouveaux modèles y apparaissent automatiquement dès leur sortie.

Écrire

add ✓ live-tested

Stocke un souvenir. Encodé en embeddings à l'entrée - aucun appel LLM, vous ne payez que les embeddings.

mem.add("she prefers tea over coffee", user_id="alice")
Réponse réelle
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

add_turn ✓ live-tested

Stocke un tour de conversation (utilisateur + assistant) à la fois en mémoire court terme et long terme.

mem.add_turn("alice", "hi", "hello!")
Réponse réelle
{"status": "ok"}

add_bulk ✓ live-tested

Importe un gros bloc de texte. Découpé et encodé côté serveur - idéal pour importer un historique existant.

mem.add_bulk("Alice moved to Brooklyn in March. She works at a design studio downtown.", user_id="alice")
Réponse réelle
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}

update ✓ live-tested

Un fait a changé. L'ancien souvenir est marqué superseded (conservé pour l'historique) ; le nouveau prend sa place dans le recall.

mem.update("alice", old_memory_id="576700aa-...", new_content="she switched to coffee this year")
Réponse réelle
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
 "old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}

Lire

search ✓ live-tested

Recherche sémantique, du plus pertinent au moins pertinent. Pur embedding - aucune correspondance par mots-clés, n'importe quelle langue trouve donc n'importe quel souvenir. Le SDK renvoie directement le tableau memories ; le corps HTTP brut est montré ci-dessous.

r = mem.search("what does she drink?", user_id="alice", limit=1)
Réponse réelle (corps HTTP)
{"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-06-10T04:20:39.688276876Z"
 }], "search_ms": 315, "total_found": 1}
ChampSignification
similaritySimilarité d'embedding brute avec votre requête (0–1).
is_supersededVrai si ce fait a été remplacé par update().
search_msTemps de récupération côté serveur.

recall ✓ live-tested

Un seul aller-retour renvoie tout ce dont votre LLM a besoin - collez le résultat directement dans votre prompt : un contexte borné, de taille fixe, quel que soit le volume stocké.

ctx = mem.recall("what does she drink?", user_id="alice")
Réponse réelle (forme - listes raccourcies)
{"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

Tours de conversation récents (mémoire court terme), du plus ancien au plus récent.

turns = mem.history("alice")
Réponse réelle (corps HTTP)
{"count": 2, "turns": [
   {"role": "user",      "content": "hi",     "timestamp": "2026-06-10T04:20:40.989011337Z"},
   {"role": "assistant", "content": "hello!", "timestamp": "2026-06-10T04:20:40.989013416Z"}
 ], "user_id": "alice"}

stats ✓ live-tested

Compteurs de souvenirs pour un utilisateur.

mem.stats("alice")
Réponse réelle
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}

Supprimer

delete ✓ live-tested

Supprime un souvenir unique par id.

mem.delete("alice", memory_id="576700aa-...")
Réponse réelle
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}

delete_all ✓ live-tested

Efface tout pour un utilisateur - un seul appel, conforme RGPD.

mem.delete_all("alice")
Réponse réelle
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}
SDK TypeScript

TypeScript - chaque méthode, en trois groupes.

Écrire, lire, supprimer. Chaque exemple ci-dessous a été exécuté contre l'API en production le 2026-06-10 ; les réponses sont verbatim.

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

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

Choisir un modèle

La clé API détermine quelle mémoire (votre compte) ; le modèle détermine quel moteur la lit. Tous les modèles partagent une même mémoire : vous pouvez donc stocker avec l'un et rappeler avec un autre. Définissez un défaut dans le constructeur ; surchargez un appel isolé avec withModel().

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

listModels ✓ live-tested

Le catalogue - les ids que vous pouvez passer à model et la disponibilité de chacun. Les modèles memory: "shared" lisent le même store ; "isolated" garde le sien. Aucune clé API requise.

await mem.listModels();
Réponse réelle
[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"}]

Le catalogue ci-dessus reflète toujours les modèles disponibles à l'instant même - passez tout autre id et vous obtenez une erreur claire. Les nouveaux modèles y apparaissent automatiquement dès leur sortie.

Écrire

add ✓ live-tested

Stocke un souvenir. Encodé en embeddings à l'entrée - aucun appel LLM, vous ne payez que les embeddings.

await mem.add("she prefers tea over coffee", "alice");
Réponse réelle
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

addTurn ✓ live-tested

Stocke un tour de conversation (utilisateur + assistant) à la fois en mémoire court terme et long terme.

await mem.addTurn("alice", "hi", "hello!");
Réponse réelle
{"status": "ok"}

addBulk ✓ live-tested

Importe un gros bloc de texte. Découpé et encodé côté serveur - idéal pour importer un historique existant.

await mem.addBulk("Alice moved to Brooklyn in March. She works at a design studio downtown.", "alice");
Réponse réelle
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}

update ✓ live-tested

Un fait a changé. L'ancien souvenir est marqué superseded (conservé pour l'historique) ; le nouveau prend sa place dans le recall.

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

Lire

search ✓ live-tested

Recherche sémantique, du plus pertinent au moins pertinent. Pur embedding - aucune correspondance par mots-clés, n'importe quelle langue trouve donc n'importe quel souvenir. Le SDK renvoie directement le tableau memories ; le corps HTTP brut est montré ci-dessous.

const r = await mem.search("what does she drink?", "alice", 1);
Réponse réelle (corps HTTP)
{"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-06-10T04:20:39.688276876Z"
 }], "search_ms": 315, "total_found": 1}
ChampSignification
similaritySimilarité d'embedding brute avec votre requête (0–1).
is_supersededVrai si ce fait a été remplacé par update().
search_msTemps de récupération côté serveur.

recall ✓ live-tested

Un seul aller-retour renvoie tout ce dont votre LLM a besoin - collez le résultat directement dans votre prompt : un contexte borné, de taille fixe, quel que soit le volume stocké.

const ctx = await mem.recall("what does she drink?", "alice");
Réponse réelle (forme - listes raccourcies)
{"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

Tours de conversation récents (mémoire court terme), du plus ancien au plus récent.

const turns = await mem.history("alice");
Réponse réelle (corps HTTP)
{"count": 2, "turns": [
   {"role": "user",      "content": "hi",     "timestamp": "2026-06-10T04:20:40.989011337Z"},
   {"role": "assistant", "content": "hello!", "timestamp": "2026-06-10T04:20:40.989013416Z"}
 ], "user_id": "alice"}

stats ✓ live-tested

Compteurs de souvenirs pour un utilisateur.

await mem.stats("alice");
Réponse réelle
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}

Supprimer

delete ✓ live-tested

Supprime un souvenir unique par id.

await mem.delete("alice", "576700aa-...");
Réponse réelle
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}

deleteAll ✓ live-tested

Efface tout pour un utilisateur - un seul appel, conforme RGPD.

await mem.deleteAll("alice");
Réponse réelle
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}
SDK Rust

Rust - chaque méthode, en trois groupes.

Écrire, lire, supprimer. Chaque exemple ci-dessous a été exécuté contre l'API en production le 2026-06-10 ; les réponses sont verbatim.

cargo add wontopos
use wontopos::Client;

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

Choisir un modèle

La clé API détermine quelle mémoire (votre compte) ; le modèle détermine quel moteur la lit. Tous les modèles partagent une même mémoire : vous pouvez donc stocker avec l'un et rappeler avec un autre. Définissez un défaut avec with_model() ; chaînez-le à nouveau pour surcharger un appel isolé.

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

list_models ✓ live-tested

Le catalogue - les ids que vous pouvez passer à with_model et la disponibilité de chacun. Les modèles memory: "shared" lisent le même store ; "isolated" garde le sien. Aucune clé API requise.

mem.list_models().await?;
Réponse réelle
[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"}]

Le catalogue ci-dessus reflète toujours les modèles disponibles à l'instant même - passez tout autre id et vous obtenez une erreur claire. Les nouveaux modèles y apparaissent automatiquement dès leur sortie.

Écrire

add ✓ live-tested

Stocke un souvenir. Encodé en embeddings à l'entrée - aucun appel LLM, vous ne payez que les embeddings.

mem.add("she prefers tea over coffee", "alice", json!({})).await?;
Réponse réelle
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

add_turn ✓ live-tested

Stocke un tour de conversation (utilisateur + assistant) à la fois en mémoire court terme et long terme.

mem.add_turn("alice", "hi", "hello!").await?;
Réponse réelle
{"status": "ok"}

add_bulk ✓ live-tested

Importe un gros bloc de texte. Découpé et encodé côté serveur - idéal pour importer un historique existant.

mem.add_bulk("Alice moved to Brooklyn in March...", "alice", "general").await?;
Réponse réelle
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}

update ✓ live-tested

Un fait a changé. L'ancien souvenir est marqué superseded (conservé pour l'historique) ; le nouveau prend sa place dans le recall.

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

Lire

search ✓ live-tested

Recherche sémantique, du plus pertinent au moins pertinent. Pur embedding - aucune correspondance par mots-clés, n'importe quelle langue trouve donc n'importe quel souvenir. Le SDK renvoie directement le tableau memories ; le corps HTTP brut est montré ci-dessous.

let r = mem.search("what does she drink?", "alice", 1).await?;
Réponse réelle (corps HTTP)
{"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-06-10T04:20:39.688276876Z"
 }], "search_ms": 315, "total_found": 1}
ChampSignification
similaritySimilarité d'embedding brute avec votre requête (0–1).
is_supersededVrai si ce fait a été remplacé par update().
search_msTemps de récupération côté serveur.

recall ✓ live-tested

Un seul aller-retour renvoie tout ce dont votre LLM a besoin - collez le résultat directement dans votre prompt : un contexte borné, de taille fixe, quel que soit le volume stocké.

let ctx = mem.recall("what does she drink?", "alice").await?;
Réponse réelle (forme - listes raccourcies)
{"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

Tours de conversation récents (mémoire court terme), du plus ancien au plus récent.

let turns = mem.history("alice").await?;
Réponse réelle (corps HTTP)
{"count": 2, "turns": [
   {"role": "user",      "content": "hi",     "timestamp": "2026-06-10T04:20:40.989011337Z"},
   {"role": "assistant", "content": "hello!", "timestamp": "2026-06-10T04:20:40.989013416Z"}
 ], "user_id": "alice"}

stats ✓ live-tested

Compteurs de souvenirs pour un utilisateur.

mem.stats("alice").await?;
Réponse réelle
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}

Supprimer

delete ✓ live-tested

Supprime un souvenir unique par id.

mem.delete("alice", "576700aa-...").await?;
Réponse réelle
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}

delete_all ✓ live-tested

Efface tout pour un utilisateur - un seul appel, conforme RGPD.

mem.delete_all("alice").await?;
Réponse réelle
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}
curl

curl - aucune installation, mêmes méthodes.

Aucun SDK à installer - n'importe quel client HTTP convient. Définissez votre clé une fois et appelez les mêmes endpoints que les SDK encapsulent. URL de base https://api.wontopos.com, authentification via X-API-Key, JSON en entrée comme en sortie.

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

Écrire

store ✓ live-tested

Stocke un souvenir. Encodé en embeddings à l'entrée - aucun appel LLM.

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"}'
Réponse réelle
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}

store-turn ✓ live-tested

Stocke un tour de conversation (utilisateur + assistant) à la fois en mémoire court terme et long terme.

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!"}'
Réponse réelle
{"status": "ok"}

supersede ✓ live-tested

Un fait a changé - l'ancien souvenir est marqué superseded, le nouveau prend sa place dans le recall.

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"}'
Réponse réelle
{"new_memory_id": "07e94433-...", "old_memory_id": "576700aa-...", "status": "superseded"}

Lire

search ✓ live-tested

Recherche sémantique, du plus pertinent au moins pertinent. Pur embedding - n'importe quelle langue trouve n'importe quel souvenir.

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}'
Réponse réelle
{"memories": [{"id": "576700aa-...", "content": "she prefers tea over coffee",
   "similarity": 0.63, "is_superseded": false}], "search_ms": 315, "total_found": 1}

recall ✓ live-tested

Un seul aller-retour renvoie court terme + long terme + contexte + une instruction. Collez-le directement dans votre 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 she drink?"}'
Réponse réelle (forme)
{"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..."}

Supprimer

forget ✓ live-tested

Supprime un souvenir par id, ou omettez l'id pour tout supprimer pour un utilisateur (RGPD).

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
Réponse réelle
{"memories_deleted": 1, "status": "deleted", "user_id": "alice"}

Chaque endpoint + champs du corps →

Engrammes

Engrams

Des outils de rappel invocables que votre modèle peut appeler - chacun étant une stratégie de récupération différente sur la même mémoire. Utilisez-en un, ou lancez-en plusieurs à la fois.

Bientôt disponible. Les engrammes généraux ci-dessous sont des pipelines de récupération sans LLM : ils fonctionnent donc sur tous les paliers à partir de Tablet 1. L'API sert aujourd'hui store et recall, ces appels ne sont donc pas encore actifs. Memoir et Archive, un mode de modèle distinct, sont traités dans leur propre section ci-dessous.

De nouveaux engrammes sortent régulièrement - cette liste s'allonge.

Memoir & Archive Bientôt disponible

Celui-ci est un mode de modèle, pas un outil invocable. Choisissez-le au niveau du modèle et chaque rappel, simple recherche comprise, revient avec le temps écrit de cette façon. Bientôt disponible.

Tous les engrammes Engrammes

Time_awareness Bientôt disponible

Un mode de modèle, pas une option par appel. Choisissez le modèle - Time_awareness-memoir ou Time_awareness-archive - et chaque rappel revient rendu de cette façon : une simple recherche, un recall ou n'importe quel engramme, sans paramètre supplémentaire. Un Memoir se lit comme une personne se souvient ; une Archive tient un registre exact - la différence se voit surtout dans la façon dont chacun écrit le temps. Le préfixe Time_awareness- laisse la place à d'autres capacités plus tard.

Memoir

Time_awareness-memoir
Souvenu comme une personne · un récit

Raconte ce qui s'est passé et comment un moment a mené au suivant, avec le sens diffus du temps propre au souvenir humain - à lire comme une expérience, pas comme une liste.

Archive

Time_awareness-archive
Tenu comme un registre · temps précis

Renvoie les correspondances comme des enregistrements exacts - temps écoulé précis et ancres absolues, structurés pour qu'un modèle les lise directement.

Il met en forme des souvenirs déjà stockés - il n'en crée pas. Chaque souvenir est un appel store / add sous un user_id (ce user_id est le store de cette personne). Stockez d'abord ; ensuite tout rappel - y compris la simple recherche ci-dessous - revient horodaté. Voir Démarrage rapide pour stocker.
# plain search - no engram - on a memoir model
r = mem.search("what does Alice drink?", user_id="alice", model="Time_awareness-memoir", tz=9)
# every hit gets a .time field → "a couple weeks ago"  (archive model → "2 weeks ago (Jun 09)")
// plain search - no engram - on a memoir model
const r = await mem.withModel("Time_awareness-memoir").search("what does Alice drink?", "alice", 10, { tz: 9 });
// model picks the mode; tz over HTTP via the X-WOS-Timezone header
let r = mem.with_model("Time_awareness-memoir").search("what does Alice drink?", "alice", 10).await?;
curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: wos-live-..." -H "X-WOS-Model: Time_awareness-memoir" -H "X-WOS-Timezone: 9" \
  -d '{"user_id":"alice","query":"what does Alice drink?"}'
# each memory comes back with a "time" field; use Time_awareness-archive for exact time

tz est le décalage UTC de l'appelant, en heures - ainsi « ce matin » et la limite de journée à 4 h du matin tombent dans son heure locale. Omettez-le pour UTC ; en HTTP, c'est l'en-tête X-WOS-Timezone. En gros, par région : côte Est des États-Unis -5, Centre -6, côte Ouest -8 · Royaume-Uni / Lisbonne 0 · Europe centrale +1 · Europe de l'Est +2 · Inde +5.5 · Chine / Singapour +8 · Corée / Japon +9 · Sydney +10. (Heure standard - l'heure d'été décale certaines régions de +1 ; passez ce que vos utilisateurs utilisent réellement.)

Même recherche, deux modèles - les souvenirs sont identiques, seul time change :

Résultat · Time_awareness-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" }
] }
Résultat · Time_awareness-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)" }
] }
ÉcouléMemoirArchive
3 mina few minutes ago3 minutes ago
14 minabout 15 minutes ago14 minutes ago
30 minhalf an hour ago30 minutes ago
50 minabout an hour ago50 minutes ago
2 ha couple hours ago2 hours ago, at 13:10
8 hthis morning8 hours ago, at 07:10
hier ap.-midiyesterday afternoonyesterday at 14:00
la nuit dernièrelast night17 hours ago, at 22:00
2 joursa couple days ago2 days ago (Tue 15:10)
6 joursseveral days ago6 days ago (Fri 15:10)
9 joursabout a week agolast week (Jun 16)
16 joursa couple weeks ago2 weeks ago (Jun 09)
35 joursabout a month agolast month (May 21)
60 joursa couple months ago2 months ago (Apr 2026)
180 joursabout half a year ago6 months ago (Dec 2025)
380 joursabout a year agolast year (Jun 2025)
800 joursa couple years ago2 years ago (Apr 2024)
1500 joursabout 4 years ago4 years ago (May 2022)

Chaque valeur ci-dessus est la sortie réelle du moteur de rendu. Regardez les deux lignes « hier » : un Memoir sépare l'après-midi de la nuit dernière - une journée est un sommeil - tandis qu'une Archive écrit une seule heure d'horloge et ne trace aucune frontière entre jour et nuit.

Comment chaque mode lit le temps

Memoir - comme les gens le disent vraiment. Les moments récents restent assez nets (environ 15 minutes, une demi-heure), puis la formulation s'élargit à mesure qu'on remonte - quelques semaines, environ six mois, quelques années - comme la mémoire elle-même se relâche avec la distance. À l'intérieur d'une journée, l'horloge cède la place à un repère : ce matin, la nuit dernière, hier après-midi. Et une journée est un sommeil, pas un tic de calendrier : la frontière se situe vers 4 h du matin, heure locale, si bien qu'une fin de soirée tardive se lit encore comme le même soir, pas déjà comme le lendemain.

Archive - précis, toujours avec une ancre. Chaque ligne porte le temps écoulé exact plus une référence absolue à partir de laquelle un modèle peut calculer, et l'ancre se resserre à mesure qu'on se rapproche : une heure d'horloge pour aujourd'hui (il y a 8 heures, à 07:10), un jour de semaine et une heure cette semaine (il y a 2 jours (mar. 15:10)), une date ce mois-ci (la semaine dernière (16 juin)), un mois et une année au-delà (il y a 6 mois (déc. 2025)). Jamais vague, jamais faux.

Memoir et Archive sont un mode de modèle appliqué à chaque rappel - une simple recherche, un recall ou un engramme - pas une option par appel. Le palier de modèle (Tablet → Scroll → Codex) détermine ce que fait le moteur ; le mode (memoir / archive) détermine comment il écrit le temps. Bientôt disponible.
Tous les engrammes Engrammes

deep_recall

Rappel multi-sauts. Cherche votre requête, puis prend la meilleure correspondance et relance une recherche sur son contenu - ramenant du contexte lié qu'une recherche unique manquerait. Idéal quand les souvenirs se référencent entre eux (une personne → ses projets → les détails). Renvoie jusqu'à ~12 résultats.

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?"}'
Réponse
{ "engram": "deep_recall", "hops": 2, "count": 12,
  "memories": [ ... ],
  "usage": { "input_tokens": 5, "output_tokens": 61 } }
Facturé en tokens - chaque appel renvoie usage (entrée + sortie), compté par le même tokenizer que le reste de l'API ; aucun frais caché par engramme. Besoin de plusieurs à la fois ? Appelez-les en parallèle - chaque engramme est une requête indépendante.
Tous les engrammes Engrammes

timeline

Rappel chronologique. Renvoie les souvenirs triés du plus récent au plus ancien selon la date de l'événement, pas selon la pertinence. Pour les questions « quand X a-t-il eu lieu », l'historique et les séquences. Renvoie jusqu'à 15 résultats.

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"}'
Réponse
{ "engram": "timeline", "hops": 1, "count": 15,
  "memories": [ ... ],
  "usage": { "input_tokens": 4, "output_tokens": 88 } }
Facturé en tokens - chaque appel renvoie usage (entrée + sortie), compté par le même tokenizer que le reste de l'API ; aucun frais caché par engramme. Besoin de plusieurs à la fois ? Appelez-les en parallèle - chaque engramme est une requête indépendante.
Tous les engrammes Engrammes

gather

Collecte large. Cherche, puis s'étend autour des trois meilleures correspondances - un filet plus large que deep_recall. Utilisez-le pour ramener tout ce qui touche à une personne, un projet ou un sujet en un seul appel. Renvoie jusqu'à ~18 résultats.

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"}'
Réponse
{ "engram": "gather", "hops": 4, "count": 18,
  "memories": [ ... ],
  "usage": { "input_tokens": 6, "output_tokens": 142 } }
Facturé en tokens - chaque appel renvoie usage (entrée + sortie), compté par le même tokenizer que le reste de l'API ; aucun frais caché par engramme. Besoin de plusieurs à la fois ? Appelez-les en parallèle - chaque engramme est une requête indépendante.
API HTTP

Chaque endpoint, une seule URL de base.

Aucun SDK requis - n'importe quel client HTTP convient. URL de base https://api.wontopos.com, authentification via l'en-tête X-API-Key, JSON en entrée comme en sortie. Les opérations mémoire sont en POST ; la gestion des stores utilise POST / GET / DELETE sur /collection. Un store doit exister au préalable (voir Stores), sinon les opérations dans le store renvoient 404.

EndpointRôleChamps du corps
POST /api/v1/memory/collectioncréer un storeuser_id
GET /api/v1/memory/collectionslister vos stores(aucun)
DELETE /api/v1/memory/collectionsupprimer un store + ses souvenirsuser_id
/api/v1/memory/storestocker un souveniruser_id · content · metadata?
/api/v1/memory/store-turnstocker un tour de conversationuser_id · user_msg · assistant_msg
/api/v1/memory/bulk-storeimporter un bloc de texteuser_id · content · category?
/api/v1/memory/searchrecherche sémantiqueuser_id · query · max_results?
/api/v1/memory/recallcourt + long + contexteuser_id · query
/api/v1/memory/historytours récentsuser_id
/api/v1/memory/statscompteurs de souvenirsuser_id
/api/v1/memory/supersederemplacer un fait modifiéuser_id · old_memory_id · new_content
/api/v1/memory/forgeten supprimer un (ou tous)user_id · memory_id? (omis = tout supprimer)
# 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?"}'
Réponse réelle - store
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}
Paliers d'utilisation

Les mêmes fonctionnalités pour tous.
Les paliers ne font que relever vos limites.

Chaque palier exécute le moteur complet - même qualité de rappel, mêmes langues, chaque méthode. Les paliers progressent automatiquement jusqu'au Tier 5 à mesure que vos achats de crédits cumulés augmentent, sans dossier à déposer ni rendez-vous commercial. Enterprise (Tier 6) est la seule exception.

Limites de dépense

Chaque palier plafonne ce que vous pouvez dépenser par mois calendaire. Vous passez immédiatement au palier suivant dès que vos achats de crédits cumulés atteignent le seuil correspondant.

Palier d'utilisationAchat de créditsLimite de dépense mensuelle
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 - EnterpriseContactez-nousSans limite

Limites de débit

Les limites de débit sont par compte - toutes les clés API d'un compte partagent une même limite, qui augmente avec votre palier. La dépasser renvoie un 429 avec un en-tête retry-after ; patientez (1s → 2s → 4s) puis réessayez. Chaque endpoint est compatible avec l'idempotence, les nouvelles tentatives sont donc sans risque.

PalierRequêtes par minute
Tier 1150
Tier 2300
Tier 3600
Tier 41,500
Tier 53,000
Tier 6 - EnterpriseSur mesure

Enterprise (Tier 6) bénéficie de limites de débit sur mesure, d'un SLA, d'un support dédié et d'une licence d'auto-hébergement en option - contactez-nous.

La tarification est à l'usage : les tokens plus $0.0001 fixe par requête. Tablet est à $2 par 1M de tokens d'entrée, $3 par 1M en sortie. Le stockage est gratuit et sans plafond. Voir pourquoi nous tarifons ainsi.
Erreurs & limites

Quand quelque chose tourne mal.

Les erreurs reviennent sous forme d'enveloppe JSON avec un type stable, un message lisible et un request_id que vous pouvez nous transmettre pour signaler un problème.

Réponse réelle - clé invalide (HTTP 401)
{"type": "error", "error": {
   "type": "authentication_error",
   "message": "Invalid or revoked API key.",
   "request_id": "063f8b83-eee2-4383-a5cf-11e4bcd29d7c"
 }}
HTTPSignificationQue faire
401Clé API invalide ou révoquéeVérifiez la clé ; émettez-en une nouvelle dans la console.
422Corps malformé (champ manquant ou de mauvais type)Le message nomme le champ exact - corrigez et réessayez.
429Limite de débit atteintePatientez de façon exponentielle (1s → 2s → 4s) puis réessayez. Sans risque : tous les endpoints sont compatibles avec l'idempotence.
5xxProblème côté serveurRéessayez avec backoff ; joignez le request_id si vous nous contactez.
# 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
Sécurité des clés. Votre clé n'est affichée qu'une fois à la création et n'est stockée que sous forme de hash de notre côté. Gardez-la dans une variable d'environnement ; en cas de fuite, révoquez-la dans la console - la révocation est immédiate.

Les limites de débit sont par compte, partagées entre toutes vos clés, et augmentent avec votre palier - voir Paliers d'utilisation. L'usage de votre compte est visible dans la console.

Auto-hébergement

Vos serveurs, vos données.

Le moteur peut tourner dans votre propre infrastructure - même API, mêmes SDK. Pointez le client vers votre hôte et rien d'autre ne change.

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");
  • Résidence des données. Les souvenirs ne quittent jamais votre réseau.
  • Même surface. Les mêmes méthodes et endpoints fonctionnent à l'identique.
  • Licence. Les offres d'auto-hébergement sont définies par déploiement - contactez-nous.
Échelle

Au-delà de la fenêtre de contexte.

WOS rappelle depuis des historiques de 1.4M tokens - bien au-delà de toute fenêtre de contexte de LLM - et rend toujours une tranche serrée d'environ ~1,470 tokens.

La mémoire de votre agent n'est pas plafonnée par ce qui tient dans un prompt. Elle conserve tout et ne récupère que ce qui compte, quelle que soit la taille de l'historique.

Confidentialité

Privé, et à vous.

Vos données restent dans votre store. Nous ne nous entraînons jamais dessus, ne les consultons pas et ne les réutilisons pas - nous ne faisons que les organiser pour que vous puissiez les retrouver.

  • BYOK. Votre clé LLM est envoyée à chaque requête et jamais stockée.
  • Isolé. Les souvenirs sont cloisonnés par compte, puis par user_id.
  • Suppression RGPD & auto-hébergement. Un seul appel efface un utilisateur ; exécutez le moteur dans votre propre environnement si vous préférez.