Python - todos os métodos, três grupos.
Escrever, ler, excluir. Todos os exemplos abaixo foram executados contra a API em produção em 2026-08-01; as respostas estão na íntegra.
pip install wontopos
from wontopos import Client mem = Client(api_key="wos-live-...") # or read from an env var
Escolha um modelo
A chave de API escolhe qual memória (sua conta); o modelo escolhe qual motor a lê. Todos os modelos compartilham uma mesma memória, então você pode armazenar com um e recuperar com outro. Defina um padrão no cliente; sobrescreva uma chamada específica passando 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="scroll-1") # or pick a model per call
list_models
O catálogo - os ids que você pode passar em model e se cada um está disponível. Modelos com memory: "shared" leem o mesmo store; "isolated" mantém o seu próprio. Não requer chave de API.
mem.list_models()[{"id": "tablet-1", "name": "Tablet 1", "available": true, "memory": "shared"},
{"id": "tablet-2", "name": "Tablet 2", "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
Confirme a conexão e que sua chave de API funciona: uma verificação de uma linha.
mem.ping() # True, or raises AuthenticationError / PaymentRequiredError
O catálogo acima sempre reflete os modelos disponíveis neste momento - passe qualquer outro id e você recebe um erro claro. Novos modelos aparecem nele automaticamente quando são lançados.
Escrever
add
Armazena uma memória. Sem chamada de LLM na entrada: você paga apenas a tarifa de escrita.
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
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}add_turn
Armazena um turno de conversa (usuário + assistente) na memória de curto e de longo prazo de uma só vez.
mem.add_turn("hi", "hello!", user_id="alice")
{"status": "ok"}speaker
Cada memória pode carregar quem a disse. Registre uma pessoa uma vez e depois passe o nome como speaker; "me" (as palavras do próprio assistente) nunca precisa de registro. A busca também aceita speaker, para lembrar só as palavras de uma pessoa.
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")
[{"content": "Bob said the deadline moved to Tuesday", "speaker": "Bob", ...}]add_bulk
Faça backfill de um bloco grande de texto. Dividido e indexado no servidor, ideal para importar histórico existente.
mem.add_bulk("Alice moved to Brooklyn in March. She works at a design studio downtown.", user_id="alice")
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}update
Um fato mudou. A memória antiga é marcada como substituída (mantida para histórico); a nova toma o lugar dela no recall.
mem.update("576700aa-...", "she switched to coffee this year", user_id="alice")
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
"old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}Ler
search
Busca semântica, os mais relevantes primeiro. Qualquer idioma encontra qualquer memória, seja qual for o idioma em que foi escrita. O SDK retorna o array memories diretamente; o corpo HTTP bruto aparece abaixo. Alguns modelos respondem com mais de um conjunto de resultados e o SDK os devolve mesclados, então o array pode conter MAIS do que max_results. Dimensione sua janela de prompt pelo que você recebe, não pelo número que pediu.
r = mem.search("what does she drink?", user_id="alice", limit=1)
[{
"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"
}]| Campo | Significado |
|---|---|
| similarity | Quão próxima esta memória está da sua consulta (0–1). |
| is_superseded | Verdadeiro se este fato foi substituído por update(). |
| search_ms | Tempo de recuperação no servidor. |
recall
Uma única ida e volta retorna tudo o que o seu LLM precisa - cole o resultado direto no seu prompt: um contexto limitado e de tamanho fixo, não importa quanto você tenha armazenado.
ctx = mem.recall("what does she drink?", user_id="alice")
{"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
Turnos recentes da conversa (memória de curto prazo), do mais antigo para o mais recente.
turns = mem.history("alice")
{"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
Contagens de memórias de um usuário.
mem.stats("alice")
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}get
Busca uma memória pelo id - o id que add ou list_memories retornou. Apenas o texto original armazenado e seus metadados. Um id de outro store, ou uma memória apagada ou invalidada, retorna 404.
m = mem.get("alice", memory_id="576700aa-...")
{"id": "576700aa-...", "content": "she prefers tea over coffee",
"category": "general", "created_at": "2026-07-10T04:20:39Z", "event_date": null,
"is_superseded": false, "superseded_by": null}{"memory": {"id": "8bd090de-...", "content": "the office moved to the seventh floor in June",
"category": "general", "created_at": "2026-07-31T18:20:30.531518060+00:00", "event_date": null,
"is_superseded": false, "superseded_by": null}, "user_id": "docs_livetest"}list_memories
Lista as memórias de um armazenamento - apenas o texto original que você guardou e seus metadados. Paginado por cursor: reenvie o next_cursor retornado para a próxima página.
page = mem.list_memories("alice", limit=100)
{"count": 2, "next_cursor": null, "memories": [
{"id": "576700aa-...", "content": "she prefers tea over coffee",
"category": "general", "created_at": "2026-07-10T04:20:39Z", "event_date": null,
"is_superseded": false, "superseded_by": null}
]}iter_memories · export_memories
Percorra todas as memórias sem gerenciar o cursor, ou traga o armazenamento inteiro de uma vez.
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
Excluir
delete
Exclui uma única memória pelo id.
mem.delete("alice", memory_id="576700aa-...")
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}delete_all
Apaga tudo de um usuário - uma única chamada, pronta para o GDPR.
mem.delete_all("alice")
{"memories_deleted": 4, "status": "deleted", "user_id": "alice"}Erros e confiabilidade
Cada falha é um erro tipado - capture o específico (limite de taxa, autenticação, pagamento) ou todos com o WosError base.
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
Leia a cota restante após qualquer chamada e desacelere antes de bater no limite.
mem.search("...", user_id="alice") rl = mem.rate_limit # {"limit": 150, "remaining": 3, "reset": ...}
search_self
As duas trilhas em uma única chamada num modelo de memória própria (Scroll 1.2+): o que os outros disseram e as palavras do PRÓPRIO agente - separadas, para que quem lê nunca confunda quem falou.
r = mem.search_self("what did I promise?", user_id="alice") r["memories"] # what others said / general memories r["self_memories"] # the agent's OWN words (speaker "me")
list_engrams
Pergunte ao serviço quais engramas e formas de entrega o modelo selecionado consegue executar, em vez de fixar nomes que ficam desatualizados assim que um novo é lançado.
cat = mem.list_engrams() [e["name"] for e in cat["engrams"]] # ask, never hard-code
filters
Restringe a busca a parte do repositório. Aplicado antes da ordenação, então você recebe as melhores correspondências dentro do filtro - não um top-N filtrado depois.
mem.search("what did we decide", user_id="alice", filters={ "categories": ["work"], "event_from": "2026-01-01", # when it HAPPENED })
idempotency_key
Torna seguro repetir uma escrita. Use quando a repetição é sua - um job que caiu e foi reexecutado, uma fila que reentrega.
mem.add("she prefers tea", "alice", idempotency_key=f"import:{row.id}")
import:row-42), nunca uma constante: uma chave reutilizada em duas escritas diferentes repete a primeira e a segunda se perde em silêncio. Formato: 1-128 caracteres de [A-Za-z0-9._:-].with_timeout / with_retries / with_deadline
Ajuste um único ponto de chamada sem mexer no cliente já construído: um clone com timeout maior para um backfill grande, ou sem retentativas dentro do seu próprio laço de retry.
timeout limita uma tentativa, então uma chamada que repete pode durar mais que ele: nos valores padrão uma única chamada pode segurar uma conexão por 30 s, recuar, tentar de novo e de novo. deadline limita a chamada inteira: cada tentativa é cortada no que sobrou, e nenhuma espera dorme além do orçamento. Defina quando quem chama tem um limite real, como um handler de requisição com cinco segundos.
mem.with_timeout(120).add_bulk(big_blob, "alice") # this slow call only mem.with_retries(0).add("...", "alice") # you retry, not the SDK mem.with_deadline(5).recall("...", "alice") # 5s for the whole call