GeniffyDocs
Changelog Log In Get a key

Any framework

Geniffy works with any model and any framework, because it doesn't wrap your model. You add two calls around the model call you already make: one before it answers, and one after.

The two calls

1

Before the model answers, recall

context() returns what is known about this user that bears on their message, written out for a prompt, each line with where it came from. Put it in your system prompt or instructions.

2

After it answers, remember

Add the exchange with memories.add(). Geniffy learns from what the user said, so their next conversation starts knowing it.

Both calls go through a client bound to one of your users with space(), so what one user said never reaches another.

memory.py
from geniffy import Geniffy

geniffy = Geniffy()                      # reads GENIFFY_API_KEY


def answer(user_id: str, message: str, generate) -> str:
    """generate(system, message) is your own model call, with any provider."""
    mem = geniffy.space(f"user_{user_id}")
    context = mem.context(message)       # what is known that bears on the message
    system = f"You are a helpful assistant.\n\n<memory>\n{context}\n</memory>"
    reply = generate(system, message)
    mem.memories.add(messages=[{"role": "user", "content": message},
                               {"role": "assistant", "content": reply}])
    return reply

When nothing is known yet, context() says so in one sentence instead of coming back empty, so the model says it doesn't know rather than guessing. See When nothing is known.

With your stack

Each page has the same two calls in the shape that framework expects, tested against the framework itself.

Model providers

Python agents

TypeScript agents

Voice and no-code

Using a framework that isn't listed? Put context() wherever it builds the system prompt or instructions, and memories.add() wherever it hands you the finished reply.

Recall first, or as a tool

There are two ways to put memory in front of a model, and most apps want the first.

Recall first Recall as a tool
How it works context() runs before every reply The model calls recall when it decides to
Model calls per reply One Two or more when it looks something up
The model always sees what is known Yes Only when it asks
Best for Assistants, support and companions Agents that plan and look things up as they go

They also work together: recall first for what bears on the message, and the tool for when the model needs to look further. Every model provider and agent framework page shows both.

A recall tool

Give the model one tool, named recall, and answer each call with mem.context(query):

recall.json
{
  "name": "recall",
  "description": "Look up what is known about the user, with where it came from.",
  "parameters": {
    "type": "object",
    "properties": { "query": { "type": "string", "description": "What to look up" } },
    "required": ["query"]
  }
}

Anthropic calls the schema input_schema, OpenAI calls it parameters, and the Vercel AI SDK takes it as inputSchema. Tell the model when to use it in your instructions, for example: Use recall before answering anything that depends on what the user said before.

Saving what was said

  • Save each exchange once, after the reply. memories.add() returns as soon as the conversation is stored, and learning happens after, so saving never holds up the reply.
  • Send messages as your framework holds them. Anthropic content blocks, OpenAI parts and Vercel AI SDK parts all go in as they are. Only text is read: images, tool calls and tool results are skipped, and so are system and developer messages.
  • Who said what is kept. What your user says becomes a fact about them, and what your assistant says stays the assistant's.

See Conversations for everything memories.add() accepts.

Last updated October 5, 2026