Memória de longo prazo para agentes de IA.
O WOS é uma API de memória. Você armazena as memórias de um usuário uma única vez e depois recupera apenas as relevantes para cada consulta, passando-as ao prompt do seu modelo.
A recuperação é puramente semântica, sem correspondência por palavras-chave nem BM25, então a qualidade do recall é idêntica em todos os idiomas. Cada consulta retorna um contexto pequeno e limitado, não importa quanto você tenha armazenado, e nenhum modelo é executado sobre as suas memórias armazenadas.
Operações principais
store- salva uma memória para um usuário.recall- obtém as memórias relevantes para uma consulta. Esta é a chamada principal.search- busca semântica bruta sobre as memórias armazenadas.supersede- atualiza ou substitui uma memória desatualizada.forget- exclui uma única memória ou um usuário inteiro (GDPR).
Três modelos, uma mesma linhagem.
Os modelos WOS recebem nomes das formas como as pessoas preservaram o conhecimento ao longo da história - Tablet, Scroll, Codex. Pedra, pergaminho, livro encadernado: cada um faz mais pelo seu agente do que o anterior.
Tablet
DisponívelUma forma enxuta, rápida e de baixo custo de inscrever e recuperar memória - a base sobre a qual todos os modelos são construídos.
Scroll
DisponívelAdiciona um modelo de linguagem para ler sua pergunta com mais atenção e trazer de volta um contexto mais completo, de modo que evidências dispersas voltem reunidas, em vez de faltar uma peça.
Codex
Em breveAbre sozinho na página certa - escolhendo a memória e as ferramentas de que cada momento precisa, e ficando mais afiado quanto mais é usado.
O relatório completo de benchmark do Tablet 1 está na página de benchmarks.
Pague $2 para nós. Economize muitas vezes esse valor no seu LLM.
O WOS entrega ao seu LLM ~1,200 tokens por consulta - uma fatia limitada e relevante - em vez de enfiar o histórico completo em cada prompt. A diferença é enorme, e cresce junto com o seu histórico.
Cada $1 gasto no WOS economiza ~$98 no LLM. Histórico maior ou modelo mais caro → ROI maior.
De onde vem a economia
- Sem o WOS, você enfia o histórico inteiro em cada prompt -
100K tokens × $2.50/1M = $0.25por consulta, às tarifas de entrada do GPT-4o (cerca de 2× isso em modelos do nível do Opus). - Com o WOS, você ingere uma única vez (
$2/1M) e cada consulta passa a ser uma pequena recuperação ($3/1M × 1,200) mais o seu LLM sobre apenas ~1,200 tokens. - Quanto menos tokens o seu LLM lê, menos você paga - e o WOS mantém esse número estável conforme a memória cresce.
Todos os idiomas, a mesma precisão.
A recuperação é puramente semântica - apenas embeddings, zero correspondência por palavras-chave ou BM25. Então a qualidade do recall é idêntica, quer seus usuários escrevam em 日本語, 中文, Español ou inglês.
A correspondência lexical, como o BM25, é ajustada ao formato de um idioma específico - morfologia, espaçamento, escrita. Em um store multilíngue, isso significa que a qualidade da recuperação varia por idioma. O WOS não usa nenhuma correspondência lexical, então todos os idiomas passam pelo mesmo caminho.
Um store, três idiomas ao mesmo tempo
Você não escolhe um idioma por store - misture-os livremente. Abaixo, a memória de um único usuário contém japonês, inglês e espanhol ao mesmo tempo, e cada pergunta encontra a memória certa independentemente do idioma. Esta é uma interação real com a API em produção:
# 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
"¿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
Sem etapa de tradução, sem detecção de idioma, sem configuração por idioma. Memórias e perguntas são posicionadas pelo significado, não pelo idioma - se o significado corresponde, o idioma não importa.
Por que banimos palavras-chave de propósito
A pontuação lexical, como o BM25, fortalece a recuperação para alguns idiomas mais do que para outros, o que atrapalha quando um store contém muitos idiomas. Por isso, nós a removemos completamente do motor e aplicamos essa regra na revisão de código: com qualquer pontuação lexical no caminho, a qualidade do recall variaria por idioma.
Nenhum modelo é executado sobre suas memórias.
O armazenamento é literal e o motor busca por embeddings - barato, rápido e determinístico. Um modelo nunca é executado sobre as suas memórias armazenadas. O Tablet não usa modelo algum; o Scroll e o Codex adicionam um ao redor do motor para resultados mais fortes, mas ele só vê a sua consulta, nunca o que você armazenou.
- Motor determinístico. O motor retorna as mesmas memórias para a mesma consulta, todas as vezes - e é por isso que a variância do nosso benchmark vem apenas do modelo leitor.
- Barato em escala. Sem custo de geração para armazenar ou recuperar, então sua conta acompanha o armazenamento - não o uso de modelo - conforme a memória cresce.
Suas palavras, intocadas
Um design comum executa um modelo de linguagem no momento da escrita para extrair e reescrever "fatos" do texto. Esse design troca três coisas: custo de geração em cada escrita, latência adicional e o armazenamento da paráfrase de um modelo em vez das palavras originais. O WOS faz a troca oposta - armazena o que foi dito, sem alterações, e deixa que o seu LLM faça a interpretação no momento da leitura, com o texto original em mãos.
90.7%, medido e reproduzível.
90.7% no LongMemEval-S, média de 5 execuções independentes (σ 0.5%, nenhuma escolhida a dedo), avaliado pelo juiz canônico GPT-4o do benchmark.
No mesmo benchmark, as pontuações variam bastante conforme o protocolo de avaliação - o juiz, o prompt e o que a camada de recuperação pode fazer. Usamos o juiz terceiro canônico GPT-4o do benchmark tal como publicado, não mudamos nada para nos ajustar ao teste e publicamos o código de pontuação e o prompt do leitor para que qualquer pessoa possa reproduzir os 90.7% exatamente.
O protocolo, em uma única tabela
| Item | O que fazemos |
|---|---|
| Conjunto de dados | LongMemEval-S (limpo), ~240K tokens de histórico por pergunta |
| Juiz | O juiz canônico GPT-4o do benchmark - um terceiro, não nós |
| Execuções | 5 execuções independentes, todas as pontuações publicadas, média reportada (σ 0.5%) |
| Leitor | Modelo leitor e prompt fixos, publicados na íntegra |
O que mantém a honestidade: um juiz terceiro, o prompt do leitor publicado sem alterações, recuperação puramente semântica e todas as execuções reportadas - não apenas a melhor. O motor de recuperação é determinístico - execute de novo e você obtém as mesmas memórias.
Escalamos benchmarks mais difíceis
Testamos no benchmark padrão mais difícil que ainda não conquistamos - e o número é a marca máxima entre todos os modelos WOS, reescrita sempre que um modelo melhor é lançado. Ao superar 94%, avançamos para um benchmark mais difícil.
Duas tarifas de token por modelo,
mais $0.0001 por requisição.
Por milhão de tokens mais uma taxa fixa de $0.0001 por requisição, pagamento conforme o uso. Sem assinatura, sem aluguel de armazenamento, sem limites de memória. Você paga quando seu agente escreve ou lê - nunca pelo que ele lembra.
| Modelo | Entrada / 1M | Saída / 1M | |
|---|---|---|---|
| Tablet 1 | $2 | $3 | Disponível |
| Scroll 1 | $4 | $8 | Disponível |
| Codex 1 | - | - | A definir |
- $0.0001 por requisição. Uma taxa fixa em cada chamada de API, além do uso de tokens.
- O armazenamento é gratuito. A ingestão paga uma única vez; manter os dados não custa nada. Sem limite de quantidade, sem limite de retenção.
- Nós armazenamos. Nunca treinamos com os dados, os usamos ou olhamos para eles. A memória do seu agente é sua - nós apenas a organizamos para que você possa recuperá-la.
- Por que o Tablet é tão barato: seu motor não executa modelo algum, então nosso custo é embeddings e disco - não GPUs. O Scroll e o Codex adicionam um modelo, e é isso que o preço mais alto deles cobre.
Três chamadas: armazenar, recuperar, responder.
Uma única API. A chamada recall() retorna contexto de curto prazo, de longo prazo e do entorno em uma única ida e volta, pronto para inserir no seu prompt.
Armazenar
add() guarda fatos e trocas: as palavras do seu usuário, as do próprio assistente (speaker "me") ou as de uma pessoa nomeada. Incorporado na entrada, sem chamada de LLM.
Recuperar
recall() retorna curto prazo + longo prazo + contexto em uma única chamada - um contexto limitado e de tamanho fixo.
Responder
Entregue esse contexto limitado ao seu LLM - qualquer provedor, sua chave.
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")
Memórias carregam um falante. O padrão são as palavras do seu usuário, speaker "me" guarda o que o próprio assistente disse, e um nome como "Bob" lembra quem disse, permitindo lembrar por pessoa.
Seu primeiro recall em 5 minutos.
Uma chave, uma linha de instalação, três chamadas - seu agente tem memória. Cada trecho de código nesta página foi realmente executado; as respostas são mostradas na íntegra.
Obtenha uma chave de API
Crie uma no console. Uma chave de 155 caracteres que começa com wos-live- é exibida uma única vez. Guarde-a em uma variável de ambiente - nunca no código.
Instale
pip install wontopos # Python npm install wontopos # TypeScript / JavaScript cargo add wontopos # Rust # curl - nothing to install, just set WOS_API_KEY
Crie um store, depois armazene & recupere
Um store é o user_id sob o qual você lê e escreve. Stores são explícitos: crie um primeiro (a chamada abaixo), depois armazene e recupere sob ele. Armazenar - embeddings gerados na entrada, sem chamada de LLM. Recuperar - curto prazo + longo prazo + contexto em uma única ida e volta.
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?"){"user_id": "alice", "status": "created"}{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}user_id ao cliente e todas as chamadas o usam - sem precisar repeti-lo; sobrescreva uma chamada específica passando user_id a ela. Stores são explícitos: armazenar em um store que não existe, ou recuperar dele, retorna 404 - crie-o primeiro. Toda conta começa com um store default, então sem nenhum user_id o caminho de configuração zero simplesmente funciona. Veja Stores para listá-los e gerenciá-los.recall() retorna quatro blocos - short_term (turnos recentes), long_term (memórias relevantes), context (o que cercava a melhor correspondência) e uma instruction dizendo ao LLM como usá-los. Insira tudo isso no seu prompt.
Stores - criar, listar, excluir.
Um store é o user_id sob o qual você lê e escreve - um espaço de memória isolado por usuário final, agente ou tópico. Stores são explícitos: crie um antes de armazenar nele ou recuperar dele, ou a chamada retorna 404. Toda conta começa com um store default, então você pode começar sem uma chamada de criação.
mem.create_store("alice") # create (idempotent)
mem.list_stores() # [{"user_id","created_at"}, ...]
mem.delete_store("alice") # delete the store + all its memories{ "user_id": "alice", "status": "created" } // "exists" if it already did{ "collections": [
{ "user_id": "default", "created_at": "2026-06-26T02:23:14Z" },
{ "user_id": "alice", "created_at": "2026-06-26T02:24:01Z" }
], "count": 2 }{ "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." } }"alice", "user_42") para manter a memória de cada pessoa separada, ou um único store default para um agente pessoal. Você também pode criar e navegar pelos stores no console (Memory ids → Issue) sem escrever código. Excluir um store é permanente - remove todas as memórias sob ele.Recalls repetidos, por um décimo do preço.
Ative por solicitação e o WOS armazena em cache o resultado da busca sob o texto da consulta, com as mesmas regras de prefixo do prompt caching dos LLMs. Enquanto o cache está quente, uma consulta repetida ou estendida reutiliza o resultado anterior, e a parte em cache é cobrada a 10% da tarifa normal por token.
Uma conversa, três turnos
É isto que realmente acontece quando um agente continua conversando com sua memória. Cada turno envia a conversa acumulada como consulta, com cache_control ligado.
A consulta inteira é buscada e armazenada em cache: entrada a 2x (TTL de 5 minutos).
Só a frase do Bob é transformada em embeddings e buscada. A parte antiga custa 0,1x, a frase nova 2x, e o cache agora termina nela.
Nenhuma chamada ao motor. Tudo a 0,1x: o desconto de 90%.
As tarifas
| Operação | Cobrança de tokens | O que significa |
|---|---|---|
| Escrita de cache - TTL 5 minutos | 2× | A primeira solicitação. Seu resultado é mantido por 5 minutos, e cada leitura desliza a janela para frente. |
| Escrita de cache - TTL 1 hora | 3× | A primeira solicitação, mantida por uma hora inteira. |
| Leitura de cache - acerto ou acerto de prefixo | 0.1× | Toda solicitação após a escrita: a parte em cache custa um décimo da tarifa normal por token. |
Quanto isso economiza
Um exemplo concreto: seu agente envia uma conversa de 3.000 tokens como consulta e a repete ou continua 10 vezes em cinco minutos. Sem cache, são 30.000 tokens de entrada a preço cheio. Com um cache de 5 minutos, são 6.000 pela primeira escrita (2x) mais cerca de 2.700 pelas nove leituras em cache: 8.700 tokens cobrados, 71% menos. Quanto mais longa a conversa, maior a economia.
A regra do prefixo
A correspondência é feita no início da consulta. Se o início permanece idêntico e apenas texto novo é acrescentado ao final, a parte em cache é reutilizada e apenas a parte nova é buscada. Se algo muda antes do fim do texto em cache, nada pode ser reutilizado.
cached [ A B C D E F G ] ○ [ A B C D E F G ] E ✗ [ B C D E F G ] E
○ acerto - o início não mudou, E é a única parte nova
✗ erro - o início mudou, então a consulta inteira é buscada e armazenada em cache novamente
Três regras para lembrar
- Estender rearmazena até a nova cauda. Depois de [A B C D E F G] + E, o cache agora termina em E: a cauda é cobrada uma vez na tarifa de escrita, e o próximo turno pode casar todo o A..E como prefixo de novo.
- Um único prefixo contíguo por solicitação. Uma consulta não pode ser dividida em dois segmentos de cache; apenas o seu início pode casar.
- Escritas invalidam na hora. Qualquer store, store-turn, bulk-store, forget, supersede ou exclusão do store descarta o cache dele, então uma resposta em cache nunca pode ficar obsoleta.
Como ativar
hits = mem.search(
"...the conversation so far...", user_id="alice",
cache_control={"ttl": "5m"}, # or "1h"
){ "memories": [ ... ],
"cache": { "status": "hit", // "write" | "hit" | "extend"
"ttl": "5m",
"cache_read_input_tokens": 412,
"cache_creation_input_tokens": 0 } }Você não precisa de um SDK para nada disso. O caching é um campo em uma chamada HTTP, então funciona a partir de qualquer linguagem de programação. A aba curl é a receita universal, e os SDKs de Python, TypeScript e Rust são apenas invólucros de conveniência sobre exatamente a mesma chamada.
Memória que sabe quem disse.
As pessoas lembram por pessoa: o que o Bob prometeu, o que você disse que faria. Marque cada memória com um falante e seu agente faz o mesmo, em todos os modelos Tablet e Scroll.
Um time, três memórias
Um armazenamento mantém muitas vozes separadas. Registre uma pessoa uma vez, salve cada fala com seu falante e depois pergunte por pessoa.
O armazenamento agora conhece o Bob. O limite de 50 é contado aqui, no registro; chamadas de salvamento nunca retornam erro de limite.
A memória agora é do Bob: toda busca que a devolve indica isso.
A fala do próprio assistente também vira memória, e "me" nunca conta para o limite.
Só as palavras do Bob voltam. As palavras de uma pessoa nunca voltam como as de outra.
Três regras para lembrar
- "me" é o próprio assistente. Nunca registrado, nunca contado. Reservado e minúsculo:
speaker: "Me"ou"ME"retorna400 invalid_request_errorem vez de ser convertido em silêncio. - O limite é contado no registro: 50 por armazenamento para começar. Registrar além disso retorna
400 invalid_request_errorcomspeaker_limit: 50no corpo do erro. Salvar com um nome não registrado também retorna400e nada é salvo. Filtrar a busca por um nome não registrado retorna404 not_found_error. Ramifique pelo status e pelos campos, não pelo texto da mensagem; planejamos aumentar o limite. - Rótulos vivem em toda leitura. Resultados de busca, o contexto de longo prazo do recall e resultados de engram carregam seu falante — o modelo sempre sabe de quem são as palavras. Passe speaker numa busca para obter só as de uma pessoa. Um supersede mantém o falante; forget o remove.
- Nomes são Unicode: qualquer idioma funciona. さくら, Иван e 하늘 são falantes válidos, e a atribuição se comporta igual em todos os idiomas. A correspondência é exata após trim e normalização Unicode, então
Bobebobsão duas pessoas. Nomes vão até 80 caracteres.
# 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" } }
Duas notas de escopo. speaker acompanha add / store: add_turn lembra a troca inteira, e rótulos por pessoa e o filtro vêm de memórias com speaker explícito. E passagens de sessão (expand) são compostos de várias memórias, então não carregam rótulo; um filtro speaker sempre devolve memórias atômicas e rotuladas. E conteúdo idêntico é deduplicado para a primeira memória: esse store retorna status "duplicate" com uma nota explícita, e nenhum falante é anexado.
Testamos do jeito difícil: memórias sem nomes no texto, lembradas por pessoa. A atribuição vem do registro de falantes, não de casamento de palavras, então funciona igual em qualquer idioma.
Como usar
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{ "memories": [
{ "content": "Bob said the deadline moved to Tuesday",
"speaker": "Bob", ... } ] }{ "user_id": "alice",
"speakers": [ { "speaker": "Bob", "memories": 2, "created_at": "2026-07-10T04:20:39Z" } ],
"count": 1, "limit": 50 }A lista mostra quem o armazenamento conhece, com contagens por pessoa contra o limite. Remover apaga só o registro: as memórias ficam, apenas o rótulo do nome vai embora.
MCP - memória para ferramentas de IA
O núcleo do WOS é a API e os SDKs. O servidor MCP é um complemento sobre eles: a mesma memória, plugada em ferramentas que você não construiu - Claude Code, Claude Desktop, Cursor.
Uma linha de instalação dá ao agente nove ferramentas de memória que ele usa sozinho. E como a memória vive na sua conta, o que uma ferramenta escreve, todas as outras lembram - inclusive agentes que você constrói com o SDK.
O que dá para fazer com isso
- Um Claude Code que lembra do seu projeto. Decisões, correções, preferências - lembrados na próxima sessão sem reexplicar nada.
- Comece no ChatGPT, continue no Claude. Mesmo store, mesma memória - a conversa atravessa ferramentas em vez de recomeçar.
- Seu próprio agente continua no circuito. O que o Claude Code aprende, um agente do SDK lembra - e o que seu agente guarda, o Claude Code lembra de volta.
Funciona no Claude Code, Claude Desktop, Cursor, Windsurf e qualquer host MCP. O ChatGPT alcança a mesma memória via Actions mais a spec OpenAPI.
Instalação
claude mcp add wontopos --env WONTOPOS_API_KEY=wos-live-... -- npx -y wontopos-mcpO agente recebe nove ferramentas - recall · remember · search · update · forget · list_memories · engram · stats · create_store - cada uma descrita para que ele saiba sozinho quando usá-las.
Spec OpenAPI
O mapa completo e legível por máquina da API - cada endpoint, requisição, resposta e erro.
OpenAPI é o formato padrão da indústria para descrever uma API HTTP em um arquivo legível por máquinas.
https://api.wontopos.com/openapi.jsonO que dá para fazer com isso
Postman: File → Import → cole a URL e os 16 endpoints viram uma coleção clicável. ChatGPT: crie um GPT, adicione uma Action, cole a mesma URL. Codegen: openapi-generator -i .../openapi.json -g go gera um cliente em uma linguagem que não publicamos.
Importe no Postman, gere um cliente em uma linguagem que não publicamos, conecte ChatGPT Actions ou rode checks de contrato no CI. Um teste a fixa às rotas reais: não há como desviar.
llms.txt
Toda a API em uma página de texto que uma IA consegue ler.
llms.txt é uma convenção da web: uma página de texto puro na raiz do site que conta a uma IA tudo o que ela precisa sobre um produto.
https://wontopos.com/llms.txtColoque na sua IDE ou agente de código e ele sabe como construir sobre o WOS - auth, endpoints, padrões, erros. Atualizado a cada release.
Os mesmos fatos da spec OpenAPI, público diferente: a spec é estrutura precisa para ferramentas; este arquivo é prosa que uma IA (ou uma pessoa) lê de uma vez. Ambos atualizam a cada release.
Sua memória dentro de cada ferramenta de IA
Um único comando dá ao Claude Code, Claude Desktop, Cursor ou qualquer host MCP uma memória de longo prazo baseada na sua conta WOS. Sem código de integração: o agente recebe nove ferramentas de memória e decide quando usá-las.
Instalação
Claude Code, uma linha (crie antes uma chave no console):
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-projectAdd to Cursor → · Add to VS Code →
Env opcional: WONTOPOS_USER_ID define o store padrão, WONTOPOS_MODEL o motor, WONTOPOS_BASE_URL uma implantação self-hosted. WONTOPOS_READ_ONLY=1 muda para somente leitura (só recall/busca/listagem).
Antes de compartilhar um store
- Use uma chave dedicada. Chaves carregam seu workspace: uma chave só para MCP delimita o que as ferramentas conectadas podem tocar - e você pode rotacioná-la no console sem mexer nas chaves do app.
- Modo somente leitura.
WONTOPOS_READ_ONLY=1não registra nenhuma ferramenta de escrita: o agente pode lembrar, buscar, listar memórias, executar engramas e ler estatísticas, mas não guardar, atualizar, esquecer ou apagar. Ideal para agentes que devem consultar a memória, não possuí-la. - Mantenha a confirmação de ferramentas ligada. Hosts MCP perguntam antes de rodar ferramentas por padrão - deixe ligada principalmente para
forget, pois exclusões valem para todas as ferramentas do store. - Tudo o que for guardado pode ser lembrado por qualquer ferramenta com a chave. Nunca guarde segredos - chaves de API, senhas - como memórias.
- Memórias lembradas são dados, não instruções. As descrições das ferramentas dizem isso explicitamente ao agente. Ainda assim, não guarde texto de terceiros não confiável em um store que um agente autônomo obedece.
- Exclusões também são compartilhadas. Um forget ou delete_all de uma ferramenta apaga para todas.
- "me" é o agente que escreve no store. Se vários agentes compartilham um store, as vozes "me" se misturam. Dê a cada agente seu próprio store (
WONTOPOS_USER_ID) para identidades separadas. - Uma conta paga. Todas as ferramentas conectadas consomem o mesmo saldo e limite de taxa.
Depois, é só conversar
O agente chama a ferramenta remember. Fica guardado de forma durável: o fim da sessão não muda nada.
Uma sessão nova não tem histórico. O agente chama recall e responde de memória: às sextas.
Coisas para dizer
- "Este repo usa pnpm, lembre disso" →
rememberguarda; a próxima sessão já sabe. - "Qual formato de erro combinamos semana passada?" →
recalltraz a decisão de volta ao contexto. - "Na verdade, o prazo passou para sexta" → o agente vê que contradiz o que lembrou e chama
updatepara corrigir essa memória no lugar. - "Isso está errado, esqueça" → o agente acha o id e chama
forget- seu host pede confirmação antes. - "O que você lembra sobre mim?" →
list_memoriespercorre tudo o que está guardado, para o agente responder ou organizar.
Nada de especial para formular: são frases comuns, não comandos. O agente lê a descrição de cada ferramenta e escolhe sozinho.
As nove ferramentas
recall- Contexto em uma chamada: turnos recentes mais memórias relevantes. A descrição instrui o agente a chamá-la primeiro sempre que o contexto passado importar.remember- Guarda um fato ou decisão durável.speaker: "me"marca as palavras do próprio agente; um nome registrado, quem disse.search- Busca semântica, com filtro opcional por pessoa (speaker).forget- Apaga uma memória pelo id.speakers- Registra, lista ou remove as pessoas que um store lembra.create_store- Stores são explícitos: um por usuário final, projeto ou agente.
SDK ou MCP?
- O SDK vai dentro de um app que você escreve. Seu código decide exatamente quando guardar e o que lembrar - determinístico, tipado, versionado. Construindo um produto? SDK.
- O MCP se pluga em uma ferramenta de IA que você não escreveu. O agente decide quando usar a memória, guiado pelas descrições - zero código. Para Claude Code, Claude Desktop, Cursor ou dar memória a um assistente pronto.
Por baixo, a mesma API e os mesmos stores - um app feito no SDK e uma sessão do Claude Code via MCP compartilham uma memória. Escolha por superfície, não um ou outro.
Uma memória através de todas as ferramentas
A memória pertence à conta, não à ferramenta. O mesmo store escrito do ChatGPT (Actions mais a spec OpenAPI) é lembrado no Claude Code e nos seus próprios agentes, e vice-versa: uma conversa iniciada em uma ferramenta continua em outra.
E como é um único store, você pode sair do Claude Code e continuar a conversa onde constrói: um agente do SDK com a mesma chave e store lembra tudo o que o Claude Code acabou de aprender - e o que seu agente guarda, o Claude Code lembra na próxima sessão.
npx wontopos-mcp): sua chave fica no seu ambiente e nunca passa por um servidor de terceiros. Envolve o SDK TypeScript, então retries automáticos, recusa de redirecionamentos e mascaramento da chave valem como estão.Claude Code
O caminho principal: um comando no terminal e toda sessão começa com memória.
- Crie uma chave de API no console. A chave carrega seu workspace: uma chave = um espaço de memória.
- Registre o servidor.
--scope usero disponibiliza em todos os projetos; sem ele, só o projeto atual o vê. - Confira: rode
/mcpdentro do Claude Code -wontoposdeve aparecer com nove ferramentas. - Torne automático: uma linha no seu
CLAUDE.md- "quando o contexto passado importar, chame wontopos recall primeiro" - e toda sessão começa com memória sem pedir.
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-projectClaude Desktop
Adicione o bloco abaixo ao claude_desktop_config.json (Configurações → Developer → Edit Config), reinicie o app e as nove ferramentas aparecem. Nota: o claude.ai na web e no celular precisa de um servidor MCP remoto, que o WOS ainda não oferece - o app de desktop é o caminho suportado.
# claude_desktop_config.json
{ "mcpServers": {
"wontopos": {
"command": "npx",
"args": ["-y", "wontopos-mcp"],
"env": { "WONTOPOS_API_KEY": "wos-live-...",
"WONTOPOS_USER_ID": "my-project" }
} } }Cursor
Adicione o bloco abaixo ao ~/.cursor/mcp.json - ou aperte o botão de um clique - e reinicie o Cursor. O agente pega as nove ferramentas.
# ~/.cursor/mcp.json
{ "mcpServers": {
"wontopos": {
"command": "npx",
"args": ["-y", "wontopos-mcp"],
"env": { "WONTOPOS_API_KEY": "wos-live-...",
"WONTOPOS_USER_ID": "my-project" }
} } }VS Code
O VS Code (modo agente do Copilot) lê servidores MCP de .vscode/mcp.json do projeto - adicione o bloco abaixo ou aperte o botão de um clique.
# .vscode/mcp.json
{ "servers": {
"wontopos": {
"command": "npx",
"args": ["-y", "wontopos-mcp"],
"env": { "WONTOPOS_API_KEY": "wos-live-...",
"WONTOPOS_USER_ID": "my-project" }
} } }Windsurf
O Windsurf (Cascade) lê ~/.codeium/windsurf/mcp_config.json: adicione o bloco abaixo e recarregue - as mesmas nove ferramentas aparecem.
# ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": {
"wontopos": {
"command": "npx",
"args": ["-y", "wontopos-mcp"],
"env": { "WONTOPOS_API_KEY": "wos-live-...",
"WONTOPOS_USER_ID": "my-project" }
} } }ChatGPT
Os conectores MCP do ChatGPT só aceitam servidores remotos, então o caminho suportado hoje é um GPT personalizado com uma Action: crie um GPT, adicione uma Action, cole a URL da spec OpenAPI abaixo e defina sua chave como header de auth. Esse GPT chamará a mesma memória das suas outras ferramentas.
# GPT → Configure → Actions → Import from URL
https://api.wontopos.com/openapi.json
# Authentication: API Key · Header name: X-API-KeyMesmo store, mesma memória: o que o ChatGPT guarda pela Action, o Claude Code lembra pelo MCP - e vice-versa.
Gemini CLI
O Gemini CLI lê servidores MCP de ~/.gemini/settings.json: adicione o bloco abaixo, reinicie a CLI e as mesmas nove ferramentas aparecem lá também.
# ~/.gemini/settings.json
{ "mcpServers": {
"wontopos": {
"command": "npx",
"args": ["-y", "wontopos-mcp"],
"env": { "WONTOPOS_API_KEY": "wos-live-...",
"WONTOPOS_USER_ID": "my-project" }
} } }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-07-10; 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 ✓ live-tested
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": "scroll-1", "name": "Scroll 1", "available": true, "memory": "shared"},
{"id": "scroll-1.2", "name": "Scroll 1.2", "available": true, "memory": "shared"}]ping ✓ live-tested
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 ✓ live-tested
Armazena uma memória. Embeddings gerados na entrada - sem chamada de LLM, você paga apenas 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
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}add_turn ✓ live-tested
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 ✓ live-tested
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")
{"memories": [{"content": "Bob said the deadline moved to Tuesday", "speaker": "Bob", ...}]}add_bulk ✓ live-tested
Faz backfill de um grande bloco de texto. Fragmentado e convertido em embeddings no servidor - ideal para importar um 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 ✓ live-tested
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 ✓ live-tested
Busca semântica, os mais relevantes primeiro. Puramente embeddings - sem correspondência por palavras-chave, então qualquer idioma encontra qualquer memória. O SDK retorna o array de memórias diretamente; o corpo HTTP bruto é mostrado abaixo.
r = mem.search("what does she drink?", user_id="alice", limit=1)
{"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}| Campo | Significado |
|---|---|
| similarity | Similaridade bruta de embedding com a sua consulta (0–1). |
| is_superseded | Verdadeiro se este fato foi substituído por update(). |
| search_ms | Tempo de recuperação no servidor. |
recall ✓ live-tested
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 ✓ live-tested
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 ✓ live-tested
Contagens de memórias de um usuário.
mem.stats("alice")
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}get ✓ live-tested
Busca uma memória pelo id - o id que add ou list_memories retornou. Apenas o texto original armazenado e seus metadados, nunca o vetor. 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", "source_type": "user_said",
"created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}list_memories ✓ live-tested
Lista as memórias de um armazenamento - apenas o texto original que você guardou e seus metadados, nunca o vetor. 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", "source_type": "user_said",
"created_at": "2026-07-10T04:20:39Z", "event_date": null, "is_superseded": false}
]}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 ✓ live-tested
Exclui uma única memória pelo id.
mem.delete("alice", memory_id="576700aa-...")
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}delete_all ✓ live-tested
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": ...}
TypeScript - todos os métodos, três grupos.
Escrever, ler, excluir. Todos os exemplos abaixo foram executados contra a API em produção em 2026-07-10; as respostas estão na íntegra.
npm install wontopos
import { Client } from "wontopos"; const mem = new Client({ apiKey: "wos-live-..." });
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 construtor; sobrescreva uma chamada específica com 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
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.
await mem.listModels();
[{"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
Confirme a conexão e que sua chave de API funciona: uma verificação de uma linha.
await mem.ping(); // true, or throws 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 ✓ live-tested
Armazena uma memória. Embeddings gerados na entrada - sem chamada de LLM, você paga apenas 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
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}addTurn ✓ live-tested
Armazena um turno de conversa (usuário + assistente) na memória de curto e de longo prazo de uma só vez.
await mem.addTurn("hi", "hello!", "alice");
{"status": "ok"}speaker ✓ live-tested
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.
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" });
addBulk ✓ live-tested
Faz backfill de um grande bloco de texto. Fragmentado e convertido em embeddings no servidor - ideal para importar um histórico existente.
await mem.addBulk("Alice moved to Brooklyn in March. She works at a design studio downtown.", "alice");
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}update ✓ live-tested
Um fato mudou. A memória antiga é marcada como substituída (mantida para histórico); a nova toma o lugar dela no recall.
await mem.update("576700aa-...", "she switched to coffee this year", "alice");
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
"old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}Ler
search ✓ live-tested
Busca semântica, os mais relevantes primeiro. Puramente embeddings - sem correspondência por palavras-chave, então qualquer idioma encontra qualquer memória. O SDK retorna o array de memórias diretamente; o corpo HTTP bruto é mostrado abaixo.
const r = await mem.search("what does she drink?", "alice", 1);
{"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}| Campo | Significado |
|---|---|
| similarity | Similaridade bruta de embedding com a sua consulta (0–1). |
| is_superseded | Verdadeiro se este fato foi substituído por update(). |
| search_ms | Tempo de recuperação no servidor. |
recall ✓ live-tested
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.
const ctx = await mem.recall("what does she drink?", "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 ✓ live-tested
Turnos recentes da conversa (memória de curto prazo), do mais antigo para o mais recente.
const turns = await 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 ✓ live-tested
Contagens de memórias de um usuário.
await mem.stats("alice");
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}get ✓ live-tested
Busca uma memória pelo id - o id que add ou list_memories retornou. Apenas o texto original armazenado e seus metadados, nunca o vetor. Um id de outro store, ou uma memória apagada ou invalidada, retorna 404.
const m = await mem.get("alice", "576700aa-...");
{"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
Lista as memórias de um armazenamento - apenas o texto original que você guardou e seus metadados, nunca o vetor. Paginado por cursor: reenvie o next_cursor retornado para a próxima página.
const page = await mem.listMemories("alice", { limit: 100 });
{"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
Percorra todas as memórias sem gerenciar o cursor, ou traga o armazenamento inteiro de uma vez.
for await (const m of mem.iterMemories("alice")) console.log(m.id, m.content); const everything = await mem.exportMemories("alice");
Excluir
delete ✓ live-tested
Exclui uma única memória pelo id.
await mem.delete("alice", "576700aa-...");
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}deleteAll ✓ live-tested
Apaga tudo de um usuário - uma única chamada, pronta para o GDPR.
await mem.deleteAll("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.
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
Leia a cota restante após qualquer chamada e desacelere antes de bater no limite.
await mem.search("...", "alice"); const rl = mem.rateLimit; // { limit: 150, remaining: 3, reset: ... }
Rust - todos os métodos, três grupos.
Escrever, ler, excluir. Todos os exemplos abaixo foram executados contra a API em produção em 2026-07-10; as respostas estão na íntegra.
cargo add wontopos
use wontopos::Client; let mem = Client::new("wos-live-...");
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 com with_model(); encadeie-o novamente para sobrescrever uma chamada específica.
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
O catálogo - os ids que você pode passar em with_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().await?;
[{"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
Confirme a conexão e que sua chave de API funciona: uma verificação de uma linha.
mem.ping().await?; // Ok(true), or Err whose .kind() is Auth / PaymentRequired
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 ✓ live-tested
Armazena uma memória. Embeddings gerados na entrada - sem chamada de LLM, você paga apenas 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
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}add_turn ✓ live-tested
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!", "alice").await?;
{"status": "ok"}speaker ✓ live-tested
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", "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?;
add_bulk ✓ live-tested
Faz backfill de um grande bloco de texto. Fragmentado e convertido em embeddings no servidor - ideal para importar um histórico existente.
mem.add_bulk("Alice moved to Brooklyn in March...", "alice", "general").await?;
{"elapsed_secs": 0.154154944, "status": "ok", "stored": 1, "total_chunks": 1}update ✓ live-tested
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", "alice").await?;
{"new_memory_id": "07e94433-b7cc-4e49-8d8f-f37fc1a392b7",
"old_memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "superseded"}Ler
search ✓ live-tested
Busca semântica, os mais relevantes primeiro. Puramente embeddings - sem correspondência por palavras-chave, então qualquer idioma encontra qualquer memória. O SDK retorna o array de memórias diretamente; o corpo HTTP bruto é mostrado abaixo.
let r = mem.search("what does she drink?", "alice", 1).await?;
{"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}| Campo | Significado |
|---|---|
| similarity | Similaridade bruta de embedding com a sua consulta (0–1). |
| is_superseded | Verdadeiro se este fato foi substituído por update(). |
| search_ms | Tempo de recuperação no servidor. |
recall ✓ live-tested
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.
let ctx = mem.recall("what does she drink?", "alice").await?;
{"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
Turnos recentes da conversa (memória de curto prazo), do mais antigo para o mais recente.
let turns = mem.history("alice").await?;
{"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
Contagens de memórias de um usuário.
mem.stats("alice").await?;
{"short_term_turns": 2, "total_memories": 4, "user_id": "alice"}get ✓ live-tested
Busca uma memória pelo id - o id que add ou list_memories retornou. Apenas o texto original armazenado e seus metadados, nunca o vetor. Um id de outro store, ou uma memória apagada ou invalidada, retorna 404.
let m = mem.get("alice", "576700aa-...").await?;
{"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
Lista as memórias de um armazenamento - apenas o texto original que você guardou e seus metadados, nunca o vetor. Paginado por cursor: reenvie o next_cursor retornado para a próxima página.
mem.list_memories("alice", 100, None).await?;
{"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
Percorra todas as memórias sem gerenciar o cursor, ou traga o armazenamento inteiro de uma vez.
let all = mem.list_all_memories("alice").await?; // every page, collected
Excluir
delete ✓ live-tested
Exclui uma única memória pelo id.
mem.delete("alice", "576700aa-...").await?;
{"memory_id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "deleted"}delete_all ✓ live-tested
Apaga tudo de um usuário - uma única chamada, pronta para o GDPR.
mem.delete_all("alice").await?;
{"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.
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
Leia a cota restante após qualquer chamada e desacelere antes de bater no limite.
mem.search("...", "alice", 10).await?; let rl = mem.rate_limit(); // Some(RateLimit { remaining: Some(3), .. })
curl - sem instalação, os mesmos métodos.
Nenhum SDK para instalar - qualquer cliente HTTP funciona. Defina sua chave uma vez e chame os mesmos endpoints que os SDKs encapsulam. URL base https://api.wontopos.com, autenticação via X-API-Key, JSON na entrada e na saída.
# set your key once (never hard-code it) export WOS_API_KEY="wos-live-..."
Escrever
store ✓ live-tested
Armazena uma memória. Embeddings gerados na entrada - sem chamada de 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"}'
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}store-turn ✓ live-tested
Armazena um turno de conversa (usuário + assistente) na memória de curto e de longo prazo de uma só vez.
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!"}'
{"status": "ok"}speaker ✓ live-tested
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.
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"}'
supersede ✓ live-tested
Um fato mudou - a memória antiga é marcada como substituída, a nova toma o lugar dela no 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"}'
{"new_memory_id": "07e94433-...", "old_memory_id": "576700aa-...", "status": "superseded"}Ler
search ✓ live-tested
Busca semântica, os mais relevantes primeiro. Puramente embeddings - qualquer idioma encontra qualquer memória.
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}'
{"memories": [{"id": "576700aa-...", "content": "she prefers tea over coffee",
"similarity": 0.63, "is_superseded": false}], "search_ms": 315, "total_found": 1}recall ✓ live-tested
Uma única ida e volta retorna curto prazo + longo prazo + contexto + uma instrução. Cole direto no seu 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?"}'
{"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..."}Excluir
forget ✓ live-tested
Exclui uma memória pelo id, ou omita-o para excluir tudo de um usuário (GDPR).
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
{"memories_deleted": 1, "status": "deleted", "user_id": "alice"}Engrams
Ferramentas de recall invocáveis pelo seu modelo - cada uma é uma estratégia de recuperação diferente sobre a mesma memória. Use uma, ou execute várias ao mesmo tempo.
Novos engrams são lançados regularmente - esta lista cresce.
Memoir & Archive Scroll 1.2+
Esta é uma forma de entrega, não uma ferramenta invocável. No Scroll 1.2 e superiores, escolha por chamada - form: "memoir" ou form: "archive" - e esse recall, incluindo uma busca simples, volta com o tempo escrito dessa forma.
Time_awareness Scroll 1.2+
Uma forma de entrega - escolhida por chamada. Passe form - memoir ou archive - em qualquer chamada de um modelo compatível (Scroll 1.2 e superiores), e a resposta volta renderizada dessa forma: uma busca simples, um recall ou qualquer engram. Nos SDKs é um campo form, como tz; via HTTP é o cabeçalho X-WOS-Form. Um Memoir se lê do jeito que uma pessoa lembra; um Archive mantém um registro exato - a diferença aparece principalmente em como cada um escreve o tempo.
Memoir
form: "memoir"Conta o que aconteceu e como um momento levou ao seguinte, com a noção suave de tempo que uma pessoa recorda - lido como experiência, não como uma lista.
Archive
form: "archive"Retorna as correspondências como registros exatos - tempo decorrido preciso e âncoras absolutas, estruturados para um modelo ler diretamente.
store / add sob um user_id (esse user_id é o store daquela pessoa). Armazene primeiro; depois qualquer recall - incluindo a busca simples abaixo - volta com marcação de tempo. Veja o Início rápido para armazenar.# 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)")tz é o deslocamento UTC de quem chama, em horas - assim, "esta manhã" e o limite de dia às 4h caem no horário local deles. Omita para UTC; via HTTP, é o cabeçalho X-WOS-Timezone. Aproximadamente, por região: Leste dos EUA -5, Centro dos EUA -6, Oeste dos EUA -8 · Reino Unido / Lisboa 0 · Europa Central +1 · Europa Oriental +2 · Índia +5.5 · China / Cingapura +8 · Coreia / Japão +9 · Sydney +10. (Horário padrão - o horário de verão desloca algumas regiões em +1; passe o que os seus usuários estiverem realmente usando.)
A mesma busca, duas formas - as memórias são idênticas, apenas o time muda:
{ "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" }
] }{ "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)" }
] }| Decorrido | Memoir | Archive |
|---|---|---|
| 3 min | a few minutes ago | 3 minutes ago |
| 14 min | about 15 minutes ago | 14 minutes ago |
| 30 min | half an hour ago | 30 minutes ago |
| 50 min | about an hour ago | 50 minutes ago |
| 2 h | a couple hours ago | 2 hours ago, at 13:10 |
| 8 h | this morning | 8 hours ago, at 07:10 |
| ontem à tarde | yesterday afternoon | yesterday at 14:00 |
| ontem à noite | last night | 17 hours ago, at 22:00 |
| 2 dias | a couple days ago | 2 days ago (Tue 15:10) |
| 6 dias | several days ago | 6 days ago (Fri 15:10) |
| 9 dias | about a week ago | last week (Jun 16) |
| 16 dias | a couple weeks ago | 2 weeks ago (Jun 09) |
| 35 dias | about a month ago | last month (May 21) |
| 60 dias | a couple months ago | 2 months ago (Apr 2026) |
| 180 dias | about half a year ago | 6 months ago (Dec 2025) |
| 380 dias | about a year ago | last year (Jun 2025) |
| 800 dias | a couple years ago | 2 years ago (Apr 2024) |
| 1500 dias | about 4 years ago | 4 years ago (May 2022) |
Todos os valores acima são a saída real do renderizador. Observe as duas linhas de "ontem": um Memoir separa a tarde da noite anterior - um dia é um sono - enquanto um Archive escreve um único horário de relógio e não traça linha entre dia e noite.
Como cada modo lê o tempo
Memoir - do jeito que as pessoas realmente falam. Momentos recentes permanecem razoavelmente nítidos (uns 15 minutos, meia hora), e depois a formulação vai se alargando quanto mais para trás se vai - algumas semanas, cerca de meio ano, uns dois anos - do mesmo jeito que a própria memória se afrouxa com a distância. Dentro de um dia, ele troca o relógio por um marco: esta manhã, ontem à noite, ontem à tarde. E um dia é um sono, não um tique de calendário: o limite fica por volta das 4h no horário local, então uma madrugada ainda é lida como a mesma noite, não como o dia seguinte.
Archive - preciso, sempre com uma âncora. Cada linha traz o tempo decorrido exato mais uma referência absoluta a partir da qual um modelo pode calcular, e a âncora fica mais precisa conforme se aproxima do presente: um horário de relógio para hoje (8 horas atrás, às 07:10), um dia da semana e horário nesta semana (2 dias atrás (ter 15:10)), uma data neste mês (semana passada (16 jun)), um mês e ano além disso (6 meses atrás (dez 2025)). Nunca vago, nunca errado.
deep_recall
Recall multi-hop. Busca a sua consulta, depois pega a melhor correspondência e busca de novo sobre o conteúdo dela - trazendo contexto vinculado que uma busca única deixaria passar. Ideal quando as memórias referenciam umas às outras (uma pessoa → seus projetos → detalhes). Retorna até ~12.
out = mem.engram("deep_recall", "what should I know about Alice?", user_id="alice"){ "engram": "deep_recall", "hops": 2, "count": 12,
"memories": [ ... ],
"usage": { "input_tokens": 5, "output_tokens": 61 } }usage (entrada + saída), contado pelo mesmo tokenizador do restante da API; sem taxa oculta por engram. Precisa de vários de uma vez? Chame-os simultaneamente - cada engram é uma requisição independente.timeline
Recall em ordem temporal. Retorna memórias ordenadas do mais recente para o mais antigo por quando o evento aconteceu, não por relevância. Para perguntas de "quando foi X", histórico e sequência. Retorna até 15.
events = mem.engram("timeline", "project milestones", user_id="alice"){ "engram": "timeline", "hops": 1, "count": 15,
"memories": [ ... ],
"usage": { "input_tokens": 4, "output_tokens": 88 } }usage (entrada + saída), contado pelo mesmo tokenizador do restante da API; sem taxa oculta por engram. Precisa de vários de uma vez? Chame-os simultaneamente - cada engram é uma requisição independente.gather
Coleta ampla. Busca e depois expande ao redor das três melhores correspondências - uma rede mais ampla que o deep_recall. Use-o para trazer tudo relacionado a uma pessoa, projeto ou tópico em uma única chamada. Retorna até ~18.
related = mem.engram("gather", "everything about Project Atlas", user_id="alice"){ "engram": "gather", "hops": 4, "count": 18,
"memories": [ ... ],
"usage": { "input_tokens": 6, "output_tokens": 142 } }usage (entrada + saída), contado pelo mesmo tokenizador do restante da API; sem taxa oculta por engram. Precisa de vários de uma vez? Chame-os simultaneamente - cada engram é uma requisição independente.Todos os endpoints, uma única URL base.
Nenhum SDK necessário - qualquer cliente HTTP funciona. URL base https://api.wontopos.com, autenticação via o cabeçalho X-API-Key, JSON na entrada e na saída. As operações de memória são POST; gerenciar stores usa POST / GET / DELETE em /collection. Um store precisa existir primeiro (veja Stores), ou as operações dentro do store retornam 404.
| Endpoint | Finalidade | Campos do corpo |
|---|---|---|
| POST /api/v1/memory/collection | criar um store | user_id |
| GET /api/v1/memory/collections | listar seus stores | (nenhum) |
| DELETE /api/v1/memory/collection | excluir um store + suas memórias | user_id |
| /api/v1/memory/store | armazenar uma memória | user_id · content · metadata? (speaker) |
| /api/v1/memory/store-turn | armazenar um turno de conversa | user_id · user_msg · assistant_msg |
| POST /api/v1/memory/speakers | registrar um falante (explícito, até 50) | user_id · speaker |
| GET /api/v1/memory/speakers | listar falantes registrados + contagens | user_id |
| DELETE /api/v1/memory/speakers | remover um falante (memórias ficam) | user_id · speaker |
| /api/v1/memory/bulk-store | backfill de um bloco de texto | user_id · content · category? |
| /api/v1/memory/search | busca semântica | user_id · query · max_results? · speaker? |
| /api/v1/memory/recall | curto + longo + contexto | user_id · query |
| /api/v1/memory/history | turnos recentes | user_id |
| /api/v1/memory/stats | contagens de memórias | user_id |
| /api/v1/memory/supersede | substituir um fato que mudou | user_id · old_memory_id · new_content |
| /api/v1/memory/forget | excluir uma (ou todas) | user_id · memory_id? (omitir = excluir tudo) |
# 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?"}'
{"id": "576700aa-f0e0-4c26-99a0-10e2d5b0d624", "status": "stored (1 chunks)"}Os mesmos recursos para todos.
Os níveis só aumentam seus limites.
Todo nível executa o motor completo - mesma qualidade de recall, mesmos idiomas, todos os métodos. Os níveis avançam automaticamente até o Nível 5 conforme suas compras acumuladas de créditos crescem, sem solicitação nem contato com vendas. Enterprise (Nível 6) é a única exceção.
Limites de gasto
Cada nível limita quanto você pode gastar por mês-calendário. Você avança imediatamente quando suas compras acumuladas de créditos atingem o próximo patamar.
| Nível de uso | Compra de créditos | Limite mensal de gasto |
|---|---|---|
| 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 - Enterprise | Fale conosco | Sem limite |
Limites de requisições
Os limites de requisições são por conta - todas as chaves de API de uma conta compartilham um mesmo limite, que escala com o seu nível. Excedê-lo retorna um 429 com um cabeçalho retry-after; recue (1s → 2s → 4s) e tente novamente. Todos os endpoints são compatíveis com idempotência, então repetir requisições é seguro.
| Nível | Requisições por minuto |
|---|---|
| Tier 1 | 150 |
| Tier 2 | 300 |
| Tier 3 | 600 |
| Tier 4 | 1,500 |
| Tier 5 | 3,000 |
| Tier 6 - Enterprise | Personalizado |
O Enterprise (Nível 6) recebe limites de requisições personalizados, um SLA, suporte dedicado e uma licença opcional de self-host - fale conosco.
Quando algo dá errado.
Os erros retornam como um envelope JSON com um type estável, uma mensagem legível e um request_id que você pode nos enviar ao relatar um problema.
{"type": "error", "error": {
"type": "authentication_error",
"message": "Invalid or revoked API key.",
"request_id": "063f8b83-eee2-4383-a5cf-11e4bcd29d7c"
}}| HTTP | Significado | O que fazer |
|---|---|---|
| 401 | Chave de API inválida ou revogada | Verifique a chave; emita uma nova no console. |
| 422 | Corpo malformado (campo ausente ou de tipo errado) | A mensagem indica o campo exato - corrija e tente novamente. |
| 429 | Limite de requisições excedido | Recue exponencialmente (1s → 2s → 4s) e tente novamente. Seguro: todos os endpoints são compatíveis com idempotência. |
| 5xx | Problema no servidor | Tente novamente com recuo; inclua o request_id se entrar em contato conosco. |
# 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
Os limites de requisições são por conta, compartilhados entre todas as suas chaves, e escalam com o seu nível - veja Níveis de uso. O uso da sua conta é exibido no console.
Seus servidores, seus dados.
O motor pode rodar dentro da sua própria infraestrutura - mesma API, mesmos SDKs. Aponte o cliente para o seu host e nada mais muda.
mem = Client(api_key="...", base_url="https://wos.your-host.com")- Residência de dados. As memórias nunca saem da sua rede.
- Mesma superfície. Os mesmos métodos e endpoints funcionam de forma idêntica.
- Licenciamento. Os pacotes de self-host são negociados por implantação - entre em contato.
Além da janela de contexto.
O WOS recupera de históricos de 1.4M tokens - muito maiores que qualquer janela de contexto de LLM - e ainda assim devolve uma fatia enxuta de ~1,470 tokens.
A memória do seu agente não é limitada pelo que cabe em um prompt. Ela guarda tudo e recupera apenas o que importa, não importa o quanto o histórico cresça.
Privado, e seu.
Seus dados permanecem no seu store. Nunca treinamos com eles, os visualizamos ou os reutilizamos - apenas os organizamos para que você possa recuperá-los.
- BYOK. Sua chave de LLM é enviada a cada requisição e nunca armazenada.
- Isolado. As memórias têm escopo por conta e, depois, por
user_id. - Exclusão GDPR & self-host. Uma única chamada apaga um usuário; execute o motor no seu próprio ambiente, se preferir.