npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onesilo/buzz

v0.2.7

Published

Prototype: gives Buzz (buzz.xyz) long-term memory powered by One Silo. A Buzz agent that ingests channel conversation into shared silos and answers with recalled context.

Downloads

1,337

Readme

Buzz × One Silo — long-term memory for your Buzz workspace

A Buzz agent that remembers, powered by One Silo.

Buzz is an open-source workspace where humans and AI agents work together — every message is a cryptographically signed event, and agents join channels the same way coworkers do. But like every chat tool, conversation scrolls away: decisions get re-litigated, facts get re-asked, context evaporates.

This project adds a memory agent to your workspace: a Buzz member with its own keypair that quietly distills your channels into durable, searchable memory — and answers with that memory when asked, across channels and across time.

#eng     <alice>  after the debate yesterday: we decided to ship the payments
                  migration on Friday, behind the flag
#eng     <bob>    I'll rotate the staging API keys before the migration runs
#eng     <alice>  !remember rollback plan: re-enable the legacy processor via
                  LaunchDarkly flag payments-v1

         ... the next day, in a different channel ...

#support <bob>    @silo what did we decide about the payments migration?
#support <silo>   Here's what I remember about "the payments migration":
                  1. [Decision] we decided to ship the payments migration on
                     Friday, behind the flag
                     — alice, 2026-07-25, event de579e4d
                  2. [Noted] rollback plan: re-enable the legacy processor via
                     LaunchDarkly flag payments-v1
                     — alice, 2026-07-25, event e5f1f682
                  3. [Action item] I'll rotate the staging API keys before the
                     migration runs
                     — bob, 2026-07-25, event e02bad11

Every recalled memory cites its provenance — author, date, and the signed Buzz event it was distilled from — because in Buzz, everything is verifiable.

What the agent does

  • Listens quietly, in context. In channels it's been added to, it buffers conversation into rolling turn windows and captures whole episodes — speaker-attributed transcripts — so "yeah let's do that" is remembered with the turns that give it meaning. Decision-like turns flush their window immediately; the rest flush when the episode goes quiet. It never speaks unless spoken to.
  • Remembers on demand. !remember <text> stores something verbatim.
  • Answers from memory. @silo <question> or !recall <query> returns a grounded answer composed from the silo's memory. A decision made in #eng is recallable from #support.
  • Stays accountable. !memories lists what it knows; !forget <id> deletes. When new information would replace existing memory, the agent surfaces it instead of silently overwriting — rewriting memory is the owner's call, not the agent's.

| Command | What it does | | --- | --- | | @silo <question> | Answer from memory (grounded, provenance-cited) | | !recall <query> | Same as a mention, explicit form | | !remember <text> | Store verbatim, max salience | | !memories | What's stored (recent for the channel, or a silo overview) | | !forget <id> | Delete a memory by id |

Quick start

Deploying for a team? The deployment runbook below is the operational end-to-end: install → pair → node deployment shapes → hosted-relay membership → supervision → troubleshooting.

brew tap onesilo/tap
brew trust --formula onesilo/tap/onesilo-buzz
brew install onesilo-buzz
onesilo-buzz run

The trust step is not optional on current Homebrew: it refuses to load formulae from third-party taps until you trust them, so without it install stops at "Refusing to load formula … from untrusted tap". Trusting the single formula is narrower than brew trust onesilo/tap, which also covers anything the tap ships in future.

The formula builds from source, so Homebrew requires current Xcode Command Line Tools. If the install stops on an outdated Xcode, check which toolchain is selected before installing anything — a current Xcode is often already present but not selected:

xcode-select -p
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

If it still reports outdated Command Line Tools: sudo rm -rf /Library/Developer/CommandLineTools && sudo xcode-select --install.

run walks the whole setup: it asks where your workspace's memory should live, installs a onesilo-node if your answer needs one, starts the agent, and prints the npub to add to your channels.

Where should this workspace's memory live?

  1. Hybrid — private capture, cloud enrichment (default)
     A local model distills conversation on this machine; only the
     resulting statements reach your silo, where they are enriched.
     Raw conversation never leaves. @mentions still get a composed answer.
     Trade-off: needs a onesilo-node, and distillation is only as good as
     the local model.

  2. Cloud — best recall
     Conversation transcripts are sent to your silo, distilled there with
     full turn context, and enriched (entities, topics, relationships).
     @mentions get a composed, grounded answer.
     Trade-off: raw conversation leaves this machine.

  3. Local — nothing leaves this machine
     Distilled and stored entirely on your onesilo-node. Nothing is sent
     to One Silo at all.
     Trade-off: no enrichment, and @mentions return a ranked list of
     memories with citations rather than a composed answer.

Choose 1-3 [1]: 1
[onesilo-buzz] Installing onesilo-node with Homebrew (builds from source; this can take a few minutes)…
[onesilo-buzz] Initializing the node with default settings (first run downloads Ollama and a local model — this can take a while)…
   ... the node's non-interactive setup runs ...
[onesilo-buzz] Starting the node…
[onesilo-buzz] Node is up — distillation will run on this machine.

  ─────────────────────────────────────────────────────────────────
  The agent is running. One step left: let it into your workspace.
  ─────────────────────────────────────────────────────────────────

  Agent      @silo
  npub       npub1w7v9x2m...
  pubkey     7ae615cadb...
  relay      wss://onesilo.communities.buzz.xyz

See Memory modes for the full trade-offs. The choice is asked rather than assumed, and if you pick a mode that keeps conversation on this machine and the node can't be installed, run stops rather than quietly syncing to the cloud instead — silently doing the opposite of what you chose would be worse than not starting.

A node started this way lives exactly as long as onesilo-buzz — it is a child process, not a background service. Nothing is installed into launchd or systemd, and nothing keeps holding a tunnel open after you quit. If you want a node that runs on its own schedule, run onesilo-node yourself (or use Silo Desktop); onesilo-buzz run detects one that is already answering and leaves it alone.

Flags: --yes takes the recommended answer to every prompt (which is hybrid, so it still installs a node), --no-node forces cloud. Setting MEMORY_MODE, SILO_MODE or DISTILL_MODE skips the question entirely.

The tap (onesilo/homebrew-tap) is live, and its formula installs the published npm package, so brew install onesilo-buzz is the recommended path. To run from a checkout instead: npm install && npm run cli -- run.

1. Try the demo — no account, no infrastructure

git clone https://github.com/onesilo/onesilo-buzz.git
cd onesilo-buzz
npm install
npm run demo    # scripted two-day conversation through the full agent loop
npm test        # the test suite, including an end-to-end in-process relay

The demo runs entirely offline against a local memory store.

2. Get a silo

The agent's real memory is a silo — a private, managed memory store powered by One Silo, with semantic recall, entity/topic enrichment, and an owner dashboard. Your memory stays portable: silos export to the open .silo file format, specified at onesilo/silo-spec.

Sign up at dashboard.onesilo.com — free to start. That's the only dashboard step: the agent registers itself when you pair it (next step), and a dedicated silo is provisioned for it automatically.

3. Pair the agent with your One Silo account

cp .env.example .env    # set BUZZ_RELAY_URL; the defaults cover the rest
npm run connect

connect prints an authorization URL. Open it, approve, done — this is standard OAuth, the same flow ChatGPT, Claude, and Cursor use to connect to One Silo. The agent then appears in your dashboard under Connections as Buzz Agent (@yourhandle), where you manage it like any connected app: revoke access, set rate limits, require approvals, scope which silos it can touch. Pairing is one-time; refresh tokens keep the agent running headlessly.

If connect reports that no refresh token came back, the agent will stop working when its current access token expires — re-run npm run connect against a build that requests offline_access. Agents paired before that scope was requested need to re-pair once; a missing refresh token cannot be backfilled.

4. Run it in your workspace

npm start          # or: onesilo-buzz run

Add the agent to your Buzz channels like any other member. onesilo-buzz run prints its npub (for pasting into a client) and its hex pubkey (for relay admin tooling) once it is live, along with the buzz-admin add-member command a member-restricted relay needs — that one is easy to miss, because a restricted relay does not reject the agent visibly, it just never delivers anything to it. npm start logs only the first 12 characters of the pubkey — enough to recognise the agent in the log, not enough to admit it — so use onesilo-buzz run (or onesilo-buzz connect) when you need the real values. Pin the identity with AGENT_SECRET_KEY in .env.

How it works

┌────────────┐   WebSocket    ┌───────────────────┐    MCP over HTTPS    ┌──────────────────┐
│ Buzz relay │ ─────────────▶ │   memory agent    │ ───────────────────▶ │ One Silo         │
│  (signed   │ ◀───────────── │  ingest → distill │ ◀─────────────────── │  semantic recall │
│   events)  │  signed replies│  recall → reply   │   grounded answers   │  + enrichment    │
└────────────┘                └───────────────────┘                      └──────────────────┘

The agent speaks two open protocols and nothing else:

  • To Buzz: Nostr. Channel messages are signed events (kind 9 with an h channel tag); the agent verifies every signature it reads and signs everything it publishes with its own keypair. NIP-42 relay auth is supported.
  • To One Silo: MCP + OAuth. The agent is a standard Model Context Protocol client of the One Silo platform — the same connection surface as every other MCP client. Capture goes through One Silo's ingestion pipeline (which enriches memories with entities, topics, and relationships), recall uses One Silo's semantic search, and questions are answered by the silo itself, grounded in its own memory. Memory-replacing writes are surfaced for owner confirmation, never auto-applied by the agent.

Conversation-aware capture. The agent is a segmenter, not a distiller: it decides where a conversational episode begins and ends, and One Silo's server-side pipeline does the semantic work with full turn context. An episode flushes when a decision-like turn appears (immediately, so it's recallable fast), when the window fills (CAPTURE_WINDOW_TURNS), or when the channel goes quiet (CAPTURE_IDLE_FLUSH_SECONDS); the last CAPTURE_OVERLAP_TURNS turns carry into the next segment so episodes that span a flush keep their thread. Failed captures are retained and retried on the next flush. Note the privacy posture this implies: raw conversation transcripts from the agent's channels are sent to your silo (not just distilled one-liners) — only add the agent to channels whose content belongs in that memory. If you'd rather raw conversation never leave your machine at all, run a onesilo-node and turn on private distillation (next section).

Pairing with a onesilo-node

Run an open-source onesilo-node on the same machine and the agent composes with it out of the box — two independent switches control where things run:

| SILO_MODE | DISTILL_MODE | Memory lives | Distillation runs | Cloud credential | | --- | --- | --- | --- | --- | | mcp (default) | cloud (default) | your cloud silo | One Silo | agent's own OAuth | | mcp | node | your cloud silo | your node | agent's own OAuth | | relay | node | your cloud silo, via the node | your node | the node's sign-in only | | node | node | your node (SQLite, hybrid recall) | your node | none |

  • SILO_MODE=relay — One Silo through a gateway node's MCP relay (/v1/cloud/mcp). The node holds the only cloud credential; the agent authenticates to the node with the node key and never pairs (npm run connect not needed). One connection in the dashboard: the node.
  • SILO_MODE=node — memory served entirely by the node's memory API: SQLite with FTS5 keyword search, fused with vector recall when the node's compute is on. With DISTILL_MODE=node this is the fully on-machine stack: capture, distillation, storage, and recall never leave hardware you own.

Both find the node automatically: LAN APIs at 127.0.0.1:8765, node key from ~/.onesilo-node/node.key or the admin API (NODE_LAN_URL / NODE_KEY override).

Private distillation with onesilo-node. For workspaces that don't want raw transcripts leaving their hardware, pair the agent with a node on the same machine:

# once, on the same machine (downloads a local model if needed):
onesilo-node setup && onesilo-node

# then run the agent with:
DISTILL_MODE=node npm start

With DISTILL_MODE=node, each conversation segment is distilled by the node's local model (via the node's admin API) into standalone memory statements — decisions, facts, action items, preferences — and only those statements sync to your silo. It works out of the box: the agent finds the node at 127.0.0.1:8766 and reads the admin token onesilo-node setup wrote to ~/.onesilo-node/admin.token. If the node is down, captures buffer in the turn window and retry until it's back — the agent never falls back to shipping raw transcripts; privacy degradation is not an automatic decision.

| Path | What it is | | --- | --- | | src/buzz/ | Nostr protocol surface: event parsing, agent identity, relay transport, and an in-process fake relay for demo/tests | | src/silo/ | The MemoryStore contract with two backends: One Silo via MCP (mcp-store.ts, mcp-client.ts, oauth.ts) and a local JSON store for offline use; node-distill.ts wraps either with onesilo-node private distillation | | src/node/ | Client for a local onesilo-node's admin API (/v1/compute/generate) | | src/memory/ | Distillation heuristics and reply formatting | | src/agent.ts | The agent loop: routes events to ingest / commands / recall | | src/connect.ts | One-time OAuth pairing CLI | | demo/ | Scripted end-to-end walkthrough |

Memory buckets & shared memory

Memory lives in silos, and one agent isn't limited to one:

  • Multiple buckets per agent. Map channels to different silos with SILO_CHANNEL_MAP (e.g. eng=<silo-id>,support=<silo-id>); unmapped channels use the default bucket (SILO_ID, normally the agent's own auto-provisioned silo). Capture and recall route per channel, so #exec can keep a separate memory from #eng while both are served by the same agent. Recall is bucket-wide: channels sharing a bucket share memory.
  • Shared memory across agents. Silos are addressable by id, and a connection can be granted access to any number of them from the dashboard (Connections → your Buzz agent → Silos). Point two agents — different workspaces, different machines, different keypairs — at the same silo id and they read and write one shared memory, each still individually visible, rate-limitable, and revocable in the dashboard.
  • Scope-aware startup. On boot the agent calls get_scope, logs the silos and shapes its connection can reach, and warns about any configured bucket the connection hasn't been granted — so a misconfigured map fails loudly at startup, not silently at capture time.

Memory modes

Where a workspace's conversation is distilled and stored is the decision with the most consequence in this setup, so onesilo-buzz run asks it directly on first run and saves the answer to .env — delete that line to be asked again. Setting MEMORY_MODE (or SILO_MODE/DISTILL_MODE) skips the question entirely.

| | What leaves your machine | Enrichment | @mention answer | Needs a node | |---|---|---|---|---| | hybrid (recommended) | distilled statements only | yes | composed, grounded | yes | | cloud | full transcripts | yes | composed, grounded | no | | local | nothing | no | ranked list with citations | yes |

cloud sends transcripts to your silo, which distills them with full turn context — so "yeah let's do that" is captured next to the turn it refers to — then runs the enrichment pass (entities, topics, relationships). Best recall, least local.

hybrid puts a local model in front: a onesilo-node distills conversation on your machine, and only the resulting statements sync. You keep enrichment and composed answers; raw conversation never leaves. The trade is that distillation is only as good as the local model, and it has less context to work with than the cloud pipeline.

local keeps everything on the node — nothing reaches One Silo at all. The cost is real and worth understanding before choosing it: the node's memory API is SQLite + FTS5 (fused with vector recall when its compute capability is on), with no enrichment pipeline behind it. It also implements neither silo_ask nor silo_get_context, so an @mention degrades from a composed answer to a ranked list of memories with citations, and !memories becomes a keyword search.

SILO_MODE and DISTILL_MODE still work and still take precedence — they were the interface first. MEMORY_MODE just names the three combinations worth having. Node storage implies node distillation, so SILO_MODE=node alone is the same as MEMORY_MODE=local.

Configuration

Everything is environment-driven — see .env.example.

| Variable | Default | Purpose | | --- | --- | --- | | MEMORY_MODE | (asked on first run, then saved) | cloud, hybrid, or local — see Memory modes | | BUZZ_RELAY_URL | (asked on first run) | Your Buzz workspace relay; ws://localhost:7777 for local dev | | BUZZ_CHANNEL_IDS | (auto-discovered) | Comma-separated channels to listen in; set it to pin the agent to a subset | | AGENT_HANDLE | OneSilo | The agent's @handle | | AGENT_PICTURE_URL | One Silo mark | Avatar published in the agent's profile; set empty for none | | AGENT_SECRET_KEY | (generated) | Pin the agent's Nostr identity | | SILO_MODE | (from MEMORY_MODE) | mcp (One Silo direct), relay (One Silo via a gateway node), node (node-local memory), local (JSON file) | | SILO_SERVER_URL | https://connect.onesilo.com | Silo control plane (OAuth + MCP) | | SILO_ID | default | Default memory bucket (default = the agent's own silo) | | SILO_CHANNEL_MAP | (empty) | Per-channel buckets: channel=silo_id,… | | SILO_TOKEN_PATH | .silo/oauth.json | Where OAuth tokens persist | | CAPTURE_WINDOW_TURNS | 12 | Turns buffered before a segment flushes | | CAPTURE_OVERLAP_TURNS | 2 | Turns carried into the next segment as context | | CAPTURE_IDLE_FLUSH_SECONDS | 600 | Quiet time that closes an episode | | DISTILL_MODE | (from MEMORY_MODE; node storage implies node) | cloud (silo distills raw segments) or node (a local onesilo-node distills; only statements leave the machine) | | NODE_URL | http://127.0.0.1:8766 | onesilo-node admin API (distillation, status) | | NODE_ADMIN_TOKEN | (from ~/.onesilo-node/admin.token) | Explicit node admin token override | | NODE_LAN_URL | http://127.0.0.1:8765 | onesilo-node LAN API (memory, /v1/cloud relay) | | NODE_KEY | (from ~/.onesilo-node/node.key or admin API) | Explicit node key override | | NODE_ALLOW_REMOTE | (unset) | Set 1 to allow a non-loopback node URL (requires https) | | AGENT_SECRET_KEY_PATH | .silo/agent.key | Where a freshly generated agent key is written (0600) |

Deployment runbook

Operational, end-to-end steps for standing up the agent: install → pair with One Silo → choose a deployment shape (with or without a onesilo-node) → connect to your relay — self-hosted or hosted → admit the agent → verify → keep it running.

0. The shape of what you're deploying

  • The agent is an ordinary Buzz member: it holds its own Nostr keypair, connects to your workspace relay over WebSocket, and is added to channels the way a person is. There is nothing to install on the relay itself.
  • Memory lives in One Silo (or fully on-machine — your choice in step 3).
  • Optionally, a onesilo-node on the same machine distills transcripts locally so raw conversation never leaves it.

Three memberships must line up, and each failure looks different:

| Missing | Symptom | |---|---| | One Silo pairing | agent exits: Not paired with One Silo yet | | Relay membership | agent runs but never sees anything (silent hang) | | Channel membership | agent sees nothing from that channel |


1. Install the agent

Requires Node.js ≥ 22 (Homebrew brings its own).

Homebrew (macOS / Linux):

brew tap onesilo/tap
brew trust --formula onesilo/tap/onesilo-buzz   # required: brew refuses untrusted taps
brew install onesilo-buzz

npm:

npm install -g @onesilo/buzz

Verify: onesilo-buzz --version.

Pick a working directory and stay in it. The agent writes its state relative to the current directory — .silo/agent.key (its identity) and .silo/oauth.json (One Silo credential) — and loads .env from it too. Running it from a different directory later means a new identity that your workspace has never admitted. A dedicated directory such as ~/buzz-agent is the easy way to make every run the same run:

mkdir -p ~/buzz-agent && cd ~/buzz-agent

2. Pair with One Silo (one-time)

Skip this only for the zero-infrastructure demo (SILO_MODE=local) or the gateway-relay shape (D below) — every other shape needs it.

cd ~/buzz-agent
onesilo-buzz connect

This runs a browser OAuth flow against connect.onesilo.com and stores a credential at .silo/oauth.json (0600) — typically refreshable, though the control plane can mint one without a refresh token (the pairing flow warns when it does). The agent appears in your One Silo dashboard as a revocable connection named after its handle ("Buzz Agent (@silo)").

Port clash: the OAuth callback listens on 8765 by default — the same port as a local onesilo-node's LAN API. If a node is already running on this machine, pair with SILO_OAUTH_CALLBACK_PORT=8770 onesilo-buzz connect (any free port).

3. Choose a deployment shape (optional node)

The node question is a privacy decision: where do raw transcripts get distilled into memories?

| Shape | SILO_MODE | DISTILL_MODE | Raw transcripts | Needs | |---|---|---|---|---| | A. Cloud only | mcp | cloud | sent to your silo, distilled server-side | One Silo pairing | | B. Local distillation (recommended) | mcp | node | never leave the machine; only distilled statements sync | pairing + a local node | | C. Fully on-machine | node | node | never leave; memory also stays in the node's local store | a local node only | | D. Gateway relay | relay | either | per DISTILL_MODE | a gateway-mode node; the node holds the only cloud credential, the agent never pairs itself |

The guided path does this for you. onesilo-buzz run probes for a node at http://127.0.0.1:8766; if none is there it offers to install one (Homebrew: onesilo/tap/onesilo-node — run brew trust --formula onesilo/tap/onesilo-node first), hands off to onesilo-node setup, and picks DISTILL_MODE=node only once the node actually answers. To skip the question entirely:

  • onesilo-buzz run --no-node → shape A, or
  • set DISTILL_MODE explicitly in the environment — an explicit setting is never second-guessed.

Deliberate non-behavior to know about: if you chose node distillation and the node goes away, captures buffer and retry — the agent never falls back to shipping raw transcripts to the cloud. A stopped node therefore looks like "memory stopped updating", not an error in the channel. Check node health first (step 7).

Remote node (advanced): the node's admin token and node key are local secrets, so NODE_URL/NODE_LAN_URL must be loopback by default. To use a node on another machine you must set NODE_ALLOW_REMOTE=1 and use https:// URLs (e.g. the node's managed-tunnel hostname), and provide NODE_ADMIN_TOKEN/NODE_KEY explicitly since ~/.onesilo-node/* files aren't on this machine. Plaintext remote URLs are refused at startup.

4. Point the agent at your relay

Configuration is environment variables. The CLI loads .env from the working directory on startup; variables already exported in the shell win over the file (same precedence as node --env-file). Minimum:

# self-hosted Buzz relay
BUZZ_RELAY_URL=wss://relay.your-workspace.example

# agent identity
AGENT_HANDLE=silo          # what people will @mention

Hosted relay (a Buzz community someone else operates, e.g. a Block-hosted community): nothing about the agent changes — hosted communities authenticate members by pubkey, so a self-hosted agent process connects from your machine like any other member. You need two things from the community:

  1. the relay's wss:// URL → set it as BUZZ_RELAY_URL;
  2. a member slot: after step 5 prints the agent's key, the community owner adds it as a member (see step 6).

Optional scoping: BUZZ_CHANNEL_IDS=eng,support restricts listening to specific channels; empty means every channel the agent has been added to. Per-channel memory buckets go in SILO_CHANNEL_MAP (see .env.example).

5. First run

cd ~/buzz-agent
onesilo-buzz run          # add --yes to accept every recommended answer

On first boot the agent generates its keypair and stores the secret at .silo/agent.key (0600, not printed in normal operation — the secret is shown only if that write fails on an interactive terminal, so it never lands in piped logs). Once connected it prints an invite block:

  Agent      @silo
  npub       npub1…            ← paste into Buzz clients
  pubkey     3f9a…             ← the form relay admin tooling takes
  relay      wss://…

That identity is stable across restarts as long as the working directory (or an explicit AGENT_SECRET_KEY) is preserved. Back up .silo/agent.key — losing it means a new identity and re-admission.

6. Admit the agent (the human step)

Nothing here is automatic, by design — a human lets an agent in.

  1. Relay membership (member-restricted relays only, which includes hosted communities):
    • self-hosted: buzz-admin add-member <pubkey> on the relay host;
    • hosted: send the pubkey/npub from the invite block to whoever owns the community and have them add it as a member.
  2. Channel membership: in the Buzz client, add the agent to each channel it should remember — paste the npub exactly as you'd add a person.

A restricted relay drops events from non-members silently: the agent connects, subscribes, and receives nothing. If the agent is "running but nothing happens", this is the first thing to check — it is membership, not a crash.

7. Verify

In a channel the agent was added to:

@silo what do you remember?

A reply proves relay + channel membership and the memory path end to end. Then check the pieces that fail quietly:

  • !remember <fact> in a channel → should be acknowledged and recalled later;
  • node shapes (B/C/D): confirm the node is healthy — curl -s -H "Authorization: Bearer $(cat ~/.onesilo-node/admin.token)" http://127.0.0.1:8766/v1/status | jq
  • shape A/B: the memories appear in your silo in the One Silo dashboard.

Reading the log while you wait. The agent narrates each turn, so a slow reply tells you where it is slow rather than looking like a hang:

3bcc67b3 thinking about a mention in #general from @shawn: "what do you remember?"
searching memory for: "what do you remember?"
memory search returned 3 result(s) in 240ms
replied in general: I remember 3 things…
3bcc67b3 done in 291ms

The two lines worth knowing:

  • distilling N turn(s) … on the local model… followed by local model (llama3.2) replied in 48.3s — a local model doing its job. If the second line takes tens of seconds every time, the model is too big for the machine; pull a smaller one.
  • … is waiting on 1 earlier message(s) — turns are handled strictly in order, so a slow distillation stalls everything behind it. Persistent waits mean capture is the bottleneck, not the relay.

8. Keep it running

The agent is a single long-lived process; the node (if any) is a second one. For an always-on deployment run each under a supervisor:

systemd (Linux): ~/.config/systemd/user/onesilo-buzz.service

[Unit]
Description=One Silo Buzz agent
After=network-online.target

[Service]
WorkingDirectory=%h/buzz-agent
EnvironmentFile=%h/buzz-agent/.env
ExecStart=/usr/bin/env onesilo-buzz run --yes
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
systemctl --user enable --now onesilo-buzz
loginctl enable-linger $USER      # keep it alive after logout

macOS: brew services start onesilo-node covers the node; run the agent under launchd the same way (a launchd plist with WorkingDirectory set to the agent directory), or in a tmux session for low-ceremony setups.

WorkingDirectory is the load-bearing line — it is what keeps the identity, credential, and .env from step 1 in play. EnvironmentFile= is optional belt-and-braces — the CLI also loads .env from the working directory itself, and systemd-provided variables win over the file.

9. Troubleshooting

| Symptom | Cause | Fix | |---|---|---| | Not paired with One Silo yet | no .silo/oauth.json in the working directory | onesilo-buzz connect from the same directory | | Runs, but no replies, no captures | not a relay member (silent drop) or not in the channel | step 6; hosted: confirm the owner added the pubkey | | Replies in one channel, deaf in another | channel membership, or BUZZ_CHANNEL_IDS excludes it | add to channel / widen the variable | | onesilo-buzz connect fails to open callback | port 8765 taken (usually the node's LAN API) | SILO_OAUTH_CALLBACK_PORT=8770 onesilo-buzz connect | | Memory stopped updating (node shapes) | node down — captures buffer, never fall back to cloud | start the node; buffered captures flush on recovery | | Replies take tens of seconds | local model is slow — check local model (...) replied in Ns in the log | pull a smaller model on the node, or accept the latency | | not in any channel yet in the log | the agent isn't a member of any channel, so there is nothing to subscribe to | add it to a channel; it picks that up within 30s | | Startup refuses NODE_URL | non-loopback node URL without the explicit opt-in | keep the node local, or NODE_ALLOW_REMOTE=1 + https:// | | New/unknown identity after a move | ran from a different directory → fresh .silo/agent.key | run from the original directory or set AGENT_SECRET_KEY | | brew install refuses the formula | tap not trusted | brew trust --formula onesilo/tap/onesilo-buzz (and …/onesilo-node) |

Privacy & control

  • The agent only sees channels it has been added to.
  • Memory lives in your silo, under your account. The dashboard shows the agent as a connection you can inspect, limit, or revoke at any time.
  • Memory-replacing writes are never auto-confirmed by the agent.
  • Recall is auditable: every memory traces back to a signed Buzz event.

Security

  • Node credentials stay local. The node admin token and node key are attached only to loopback URLs; a misconfigured NODE_URL/NODE_LAN_URL pointing off-machine is refused unless you set NODE_ALLOW_REMOTE=1, and even then plaintext http:// to a remote host is rejected — credentials never leave the machine in the clear.
  • Generated identity keys never hit logs. A freshly minted agent key is written to a 0600 file (AGENT_SECRET_KEY_PATH), not printed to stdout, and loaded back automatically on the next start (env > file > generate), so the identity is stable without exposing the key.
  • OAuth discovery is pinned. Discovered authorization/token/ registration endpoints must be same-origin as the issuer and https, so a hostile discovery document can't redirect the auth code, PKCE verifier, or refresh token to another host.
  • Raw transcripts never leave with DISTILL_MODE=node. Distillation runs on the local node; only distilled statements sync, and if the node is down captures buffer rather than fall back to shipping raw text.
  • Outbound TLS uses default certificate verification (never disabled).

Roadmap

  • Backfill & consolidation — replay channel history on join; supersede stale memories ("ship Friday" → "slipped to Monday") instead of keeping both.
  • Memory for other agents — expose recall to the other AI agents in your workspace, so every agent acts with shared context — not just humans asking !recall.
  • Browserless agent pairing — a proposed OAuth extension (urn:onesilo:oauth:grant-type:agent-key) where the agent authenticates with its own Nostr key and the owner approves the pending connection from the dashboard: no browser step, and the connection is cryptographically bound to the same identity the agent uses in Buzz.
  • Structured provenance — Buzz channel/author/event provenance currently rides as an inline trailer in captured content; a structured metadata passthrough is the cleaner long-term contract.
  • Protocol pinning — Buzz's event-kind mapping lives in one file (src/buzz/events.ts) and currently assumes NIP-29-style kind-9 channel messages; it will be pinned against Buzz's published protocol docs.

Status

A working prototype, developed in the open. Issues and PRs welcome.

Buzz is a product of Block, Inc. This project is an independent integration and is not affiliated with or endorsed by Block.

License

Apache-2.0 — the same license as Buzz itself. See also onesilo/silo-spec, the open specification for the exportable .silo format.