Concepts

Memory and history

Where a Hubzoid agent's memory lives, from the Hub's shared knowledge to each person's own notes, each conversation's history and what scheduled work remembers.

"Memory" covers several different things in Hubzoid: the Hub's shared knowledge, each person's private notes, the history of one conversation and the state a workflow keeps between runs. Each is stored in its own place, written by different people or processes, and shared with a different group.

Why it matters

Keeping these apart is what lets a whole team share one agent safely. A rule in the Hub's knowledge reaches everyone. A note Priya asks the agent to keep about how to format answers reaches only Priya. What Lee typed in one chat never appears in someone else's.

KindWritten byStored inShared with
Authored knowledgeBuilders, in Gitknowledge/*.mdEveryone who uses the Hub
Team memoryProposed with remember, applied by someone who manages the agent. Beta, off by default.knowledge/_learned/*.mdEveryone who uses the Hub
Your notesYou, in chat or in Settings → MemoryThe operational databaseOnly you, on that agent
SourcesPeople, in Settings → SourcesCollections that Hubzoid indexes for searchThe readers each collection names. The agent cites them with search_sources.
Conversation historyThe conversation itselfPer surface, see belowThe people in that conversation
Workflow stateWorkflow code and scheduled tasksThe operational database and task state filesThat workflow, per account a run acts as

A quick example

In the web app, Priya Raman writes:

Message
Remember that I prefer answers as a table.

The agent calls save_memory and replies that it saved the note, that only Priya sees it and that Priya can change it in Settings → Memory. Every new chat Priya starts with this agent now begins with that note. Lee Okafor, using the same agent, sees no difference.

To change what the whole team's agent knows, Priya edits a file in knowledge/ instead, or, where in-app editing is on, asks the agent to remember it for the team.

How it works

Shared across the Hub

  • Authored knowledge

    knowledge/*.md

    Written by builders and reviewed in Git.

  • Team memory

    knowledge/_learned/

    Proposed with remember and applied by someone who manages the agent.

One person

  • Your notes

    One short note per person per agent, kept with save_memory or in Settings.

One conversation

  • Conversation history

    The web app keeps it in the Hubzoid database, Slack in Slack, and WhatsApp and Telegram in the Hub database. API and MCP callers keep their own.

The agent

Answers with the Hub's knowledge, the person's own notes and that conversation's history, never another conversation's.

One workflow

  • Workflow state

    hub.state

    What scheduled work has already done for the account a run acts as.

  • Shared workflow state

    hub.shared_state

    State that is not about one person, shared by every account that runs the workflow.

The workflow

Its code or task, on each run, as the run's account.

Knowledge is shared across the Hub. Notes stay with one person, history with one conversation, and workflow state with one workflow and the account it runs as.

Authored knowledge

Knowledge is the Hub's reference material: definitions, policies, thresholds and how your systems fit together. It lives in knowledge/ as Markdown, is reviewed like code, and changes when someone edits it. The system prompt lists each document's name and description, and the agent reads a document in full with read_knowledge(name) when it needs it.

read_knowledge and list_knowledge read the folder from disk on every call, so an edit is used by the next call without a restart. See the Hub.

Your notes

Each person can keep one short note per agent: how they like answers, what they call things, what they work on. It is for that person only and never part of the Hub's files.

Settings, Memory: private notes you asked the agent to remember, with a text box for the notes, a 4000 character count and a Save notes button.Settings, Memory: private notes you asked the agent to remember, with a text box for the notes, a 4000 character count and a Save notes button.
Each person reads, edits and deletes their own notes here.
How notes are saved, sized, used and stored
  • Saving. Ask in chat ("remember that I prefer tables") and the agent calls save_memory, or write the note in Settings → Memory. "Forget that" calls remove_memory.
  • Size. Up to 4,000 characters per person per agent.
  • Who can change it. Only the person, in a chat or in Settings. Scheduled runs cannot, and a page or document the agent reads cannot.
  • How it is used. Each new web app chat starts with the notes. The agent's instructions and knowledge win when they disagree, and the agent never copies notes into anything others see.
  • Where it lives. The hz_personal_memory table of the operational database, never the Hub's files or Git. Settings shows each person only their own notes.

Team memory with remember

Beta and off by default

Changing an agent's files from the browser, including remember and propose_hub_change, is off unless the deployment sets in_app_editing: true in hubzoid.yaml (or HUBZOID_IN_APP_EDITING=true for one Hub) and restarts hubzoid run. While it is off, the agent does not offer these tools, and builders change knowledge in the files. Files that come from an image are never written.

With it on, remember turns a correction made in chat into a proposed change to the Hub's knowledge:

  1. Person asks
  2. Access check
  3. Change proposed
  4. Manager applies
  5. Read by the next call
Each step of a team memory change, its limits, safety rules and undo
  1. A person with Save shared knowledge (curator), or who manages the agent, says "remember for the team: the South warehouse closes at 4pm on Fridays".
  2. The agent calls remember(topic, text). It proposes an edit to knowledge/_learned/<topic>.md: a new file for a new topic, added text for an existing one, or a correction of exact existing text.
  3. The proposal appears as a card with the diff in chat. Nothing changes yet.
  4. Someone who manages the agent applies or rejects it from the card or in Settings. A change the agent proposes never applies itself, even for a manager.
  5. Applying writes exactly the reviewed text, only if the file has not changed since. In a Hub kept in Git, each applied change is one commit, with the person who approved it as the author.

The topic becomes the file name, in lowercase letters, digits and hyphens, at most 80 characters, and the document is named learned/<topic>. A changed file may be at most 200 KB.

Some rules keep this safe:

  • The tool's description tells the model to call it only when a person explicitly asks it to remember something for the team, never on its own or because a document asked.
  • The caller must be on a surface allowed to reach restricted tools. By default Slack, WhatsApp and Telegram callers are refused. An unattended run never changes the Hub.
  • remember is not offered over MCP. A Hub tool named remember replaces the built-in one.
  • Every attempt, allowed or refused, is recorded in the access log with the person, surface and reason.

To undo an applied change, propose an undo, which needs its own review: hubzoid hub-changes undo my-hub <id>. hubzoid hub-changes list my-hub --status pending lists proposals waiting for review.

Team memory is shared

An applied change becomes part of the Hub's knowledge for everyone who uses it, on every surface. Grant Save shared knowledge only to people who should propose changes to what the whole team's agent believes.

Conversation history

The agent does not remember earlier turns by itself. Each turn hands it the conversation so far. Where that history comes from depends on the surface:

SurfaceWhere history livesWhat the agent receives
Web appThe operational database (hz_conversations and hz_messages)The active branch of the conversation up to the new message, so an edited or regenerated turn follows its own branch. Earlier replies contribute their answer text, never their reasoning or tool entries.
Your own appThe operational database, under a private id for each person of your appTheir own chats, which they can list and reopen
SlackSlack itselfThe thread, read back from Slack on every turn
WhatsApp, TelegramThe hz_inbound_history table in the Hub databaseThe most recent messages for that chat, 40 by default
OpenAI-compatible APIYour applicationWhatever messages list your application sends
MCP clientsThe client applicationNothing. Each MCP tool call stands alone.

History is separate per surface and per conversation. A question asked in Slack is not visible in the web app, and one WhatsApp chat never sees another.

Managing web app chats, WhatsApp and Telegram storage, and usage rows

In the web app, each person's conversations are their own: they can search, rename, archive and delete them, and share a read-only link that signed-in people of the deployment can open. Deleting a person's account deletes their conversations.

For WhatsApp and Telegram, Hubzoid keeps the thread itself because those platforms do not replay it. Only the visible answer is stored. INBOUND_HISTORY_MAX (default 40) sets the messages kept per chat, and INBOUND_HISTORY_TTL_DAYS, when set, deletes older messages each time the chat stores a new one.

Usage rows in hz_usage record the time, surface, person, chat id, model, tokens, estimated cost and duration of every turn. They never contain message content.

Workflow state

Scheduled work needs to remember what it has already done. That memory belongs to the workflow and to the account a run acts as, not to a conversation. See who a run acts as.

Code workflows use hub.state, a dictionary-like store in the operational database (hz_workflow_kv). Keys are scoped to the Hub, the workflow and the run's account, so two workflows never collide and the same workflow run for someone else starts empty. hub.shared_state is shared by every account that runs the workflow, so keep personal data out of it. Values are JSON, and each assignment is committed at once.

workflows/stock_alerts/main.py
for item in low_stock:
    key = f"alerted:{item['sku']}:{item['date']}"
    if hub.state.get(key):
        continue  # already handled in an earlier run
    send_alert(item)
    hub.state[key] = True
Why a state write can repeat after a crash

A write to hub.state is its own commit, not a checkpointed step. If a run crashes after a write and resumes, a counter such as hub.state["n"] += 1 can be applied twice. Use per-item markers like the one above, which let a repeated run skip work it already finished.

Markdown tasks run each round in a fresh context, with no chat history. Continuity comes from a state file the task keeps for the run's account at <hub>/.hubzoid/schedule/<task>@<person>/state.json. The task's preamble tells the agent to read it first and update it after every unit of work. Each run also writes a step-by-step log to the runs/ folder beside it. See markdown tasks.

The workflow engine separately checkpoints each completed step of a run, which is what lets an interrupted run resume without repeating finished steps. That is execution state, managed by the engine, not something your code reads.

Choose which cookies Hubzoid can use. You can change this at any time from Cookie settings in the footer. Read the Cookie Policy for details.