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

@sonzai-labs/openclaw-context

v1.6.0

Published

OpenClaw ContextEngine plugin for the Sonzai Mind Layer — gives OpenClaw agents hierarchical memory, personality evolution, mood tracking, and fact extraction

Readme

@sonzai-labs/openclaw-context

OpenClaw ContextEngine plugin for the Sonzai Mind Layer. Gives OpenClaw agents hierarchical memory, personality evolution, mood tracking, relationship modeling, and automatic fact extraction — powered by the Sonzai API.

Quick Start

One-shot install (recommended)

npx --yes @sonzai-labs/openclaw-context install

This probes backend health, runs openclaw plugins install, launches the interactive config wizard, and prints the restart instruction. One command end-to-end.

Interactive Setup

openclaw plugins install @sonzai-labs/openclaw-context
npx @sonzai-labs/openclaw-context setup

The setup wizard will:

  1. Ask for your Sonzai API key (or detect SONZAI_API_KEY from env)
  2. Ask if you have an existing agent ID, or create one for you
  3. Ask whether memory recall should be sync (default) or async
  4. Write your API key and plugin config to openclaw.json

That's it — restart OpenClaw and your agent has persistent memory. No environment variables needed.

Backend health check

Before installing, verify the backend is reachable:

curl -sf https://api.sonz.ai/health && echo "OK"
# or
npx @sonzai-labs/openclaw-context health

Manual Setup

# 1. Install
openclaw plugins install @sonzai-labs/openclaw-context

Add to your openclaw.json:

{
  "plugins": {
    "slots": {
      "contextEngine": "sonzai"
    },
    "entries": {
      "sonzai": {
        "enabled": true,
        "apiKey": "sk-your-api-key",
        "agentId": "your-agent-uuid"  // optional — auto-provisioned if omitted
      }
    }
  }
}

openclaw.json acts as your config file — no environment variables needed.

Zero-touch trial (no key needed)

Running the installer on a machine with no openclaw.json gets you a 14-day trial automatically — no sign-up, no browser, no key copying. The plugin calls the platform's /onboarding/trial endpoint, writes the issued key into openclaw.json, and you're done.

To keep memory past the trial window, claim it into a real account:

npx @sonzai-labs/openclaw-context claim

This prints a one-time link. Open it, sign in (or sign up) with Clerk, and your trial agent + memory become permanent. The agent_id does not change, so nothing in your config has to be touched.

Why a trial cap exists

To keep the trial pool from being drained by automation, issuance is capped at 100 trial keys/day globally. When the cap is reached, the installer falls back to the manual paste prompt — paste an existing key, or try again the next day.

B2B Integration (Programmatic Setup)

For platforms deploying OpenClaw at scale, use the programmatic setup API in your provisioning scripts:

import { setup } from "@sonzai-labs/openclaw-context";

// One-liner: validates key, provisions agent, writes openclaw.json
const result = await setup({
  apiKey: "sk-project-scoped-key",
  agentName: "customer-support-bot",   // stable name → deterministic agent ID
  configPath: "/path/to/openclaw.json",
});

console.log(result.agentId);   // "a1b2c3d4-..."
console.log(result.written);   // true — config file updated

B2B Provisioning Script Example

import { setup } from "@sonzai-labs/openclaw-context";

// Called once per tenant during onboarding
async function provisionOpenClawForTenant(tenantName: string) {
  const result = await setup({
    apiKey: process.env.SONZAI_PROJECT_KEY!,
    agentName: `${tenantName}-assistant`,  // unique per tenant
    configPath: `/etc/openclaw/${tenantName}/openclaw.json`,
  });

  // Store the agent ID in your DB for reference
  await db.tenants.update(tenantName, { sonzaiAgentId: result.agentId });
}

Kubernetes / Docker Deployments

The agent ID is deterministic: SHA1(tenantID + agentName). As long as your config has the same API key + agent name (or explicit agent ID), pods can restart, scale, or be replaced without creating duplicate agents.

For containerized environments, you can either bake the API key into openclaw.json or use env vars as overrides (useful for secrets management):

# Example: K8s deployment — env var overrides openclaw.json
env:
  - name: SONZAI_API_KEY
    valueFrom:
      secretKeyRef:
        name: sonzai-secrets
        key: api-key
  - name: SONZAI_AGENT_ID
    value: "a1b2c3d4-e5f6-..."  # from provisioning step

Config-Only (No Env Vars)

Everything can live in openclaw.json — no env vars required:

const result = await setup({
  apiKey: "sk-...",
  agentName: "my-bot",
  writeConfig: true,
  configPath: "./openclaw.json",
});
// API key and agent ID are both written to openclaw.json.

How It Works

The plugin replaces OpenClaw's default Markdown-file memory with Sonzai's Mind Layer:

| OpenClaw Hook | What Happens | |---------------|-------------| | bootstrap | Starts a Sonzai session; provisions agent if needed | | ingest | No-op (processing deferred to afterTurn) | | assemble | Single getContext call fetches memory, mood, personality, relationships, goals, interests, habits, and recent_turns (server-side parallelized); injects as systemPromptAddition | | compact | Triggers Sonzai's consolidation pipeline (replaces OpenClaw's summarization) | | afterTurn | Sends conversation to Sonzai for fact extraction | | dispose | Ends all active sessions cleanly |

Context Injection

Before each LLM call, the plugin injects a <sonzai-context> block into the system prompt containing:

  • Agent personality profile and Big5 traits
  • Current mood state
  • Relationship data with the current user
  • Semantically relevant memories (searched by last user message)
  • Active goals
  • User interests
  • Behavioral habits

If any API call fails, it's silently skipped — the plugin never blocks OpenClaw.

Mid-session memory retrieval

assemble() runs before every LLM turn and calls getContext with the current user message as the query — so memory search is per-turn, not a session-start snapshot.

Two classes of memory are surfaced:

  • Consolidated facts (loaded_facts) — extracted from prior sessions and promoted by the consolidation pipeline. Always available.
  • Recent turns (recent_turns) — raw messages from the current session, pushed on every process() call, TTL 2h. Closes the latency gap for facts the user just stated this turn but hasn't been consolidated into a canonical fact yet.

The Sonzai backend writes recent turns on each afterTurnprocess() and surfaces them on the next assemblegetContext call. So a fact stated this turn is retrievable next turn even before the consolidation pipeline has run.

User Identity

The plugin automatically extracts user identity from OpenClaw session keys:

| Session Type | Example Key | Resolved userId | |-------------|------------|-----------------| | CLI (1:1) | agent:abc:mainKey | "owner" (default) | | Telegram DM | agent:abc:telegram:direct:123 | "123" | | WhatsApp DM | agent:abc:whatsapp:direct:+1555... | "+1555..." | | Discord group | agent:abc:discord:group:guild789 | "guild789" |

Agent ID Stability

The Sonzai backend derives agent IDs deterministically:

agentId = SHA1(namespace, tenantID + "/" + lowercase(agentName))

Same API key + same name = same agent UUID, always. Safe across:

  • Pod restarts and replacements
  • Container recreation
  • Multiple replicas (they all resolve to the same agent)
  • openclaw plugins install re-runs

To get separate agents under one API key, use different agentName values.

Full Configuration Reference

All settings go in openclaw.json under plugins.entries.sonzai. Environment variables are supported as overrides.

| Setting | Env Var Override | Default | Description | |---------|-----------------|---------|-------------| | apiKey | SONZAI_API_KEY | required | Sonzai API key | | agentId | SONZAI_AGENT_ID | auto-provision | Pre-provisioned agent UUID | | baseUrl | SONZAI_BASE_URL | https://api.sonz.ai | API base URL | | agentName | SONZAI_AGENT_NAME | openclaw-agent | Name for auto-provisioned agents | | defaultUserId | — | owner | Default userId for CLI (1:1) sessions | | contextTokenBudget | — | 2000 | Max tokens for context injection | | memoryMode | SONZAI_MEMORY_MODE | sync | Memory recall timing. sync blocks context build until recall returns (per-turn completeness); async races a deadline (lower first-token latency, slow hits spill to next turn). | | disable.mood | — | false | Skip mood context | | disable.personality | — | false | Skip personality context | | disable.relationships | — | false | Skip relationship context | | disable.memory | — | false | Skip memory search | | disable.goals | — | false | Skip goals context | | disable.interests | — | false | Skip interests context | | disable.habits | — | false | Skip habits context | | disable.knowledge | — | false | Skip knowledge-base context | | extractionProvider | SONZAI_EXTRACTION_PROVIDER | gemini | LLM provider used for fact extraction. Optional. Override to route extraction through openai, anthropic, etc. | | extractionModel | SONZAI_EXTRACTION_MODEL | gemini-3.1-flash-lite | LLM model used for fact extraction. Optional — this is the default floor. Override with a heavier model like gemini-3.1-pro-preview to trade latency/cost for extraction quality. | | projectId | SONZAI_PROJECT_ID | auto-discover | Sonzai project UUID. Only consulted when byok keys are set. If omitted, the plugin uses the tenant's Default project. | | byok.openai | SONZAI_BYOK_OPENAI_KEYOPENAI_API_KEY | — | Customer-provided OpenAI key. See Bring Your Own Key. | | byok.gemini | SONZAI_BYOK_GEMINI_KEYGEMINI_API_KEYGOOGLE_API_KEY | — | Customer-provided Gemini key. | | byok.xai | SONZAI_BYOK_XAI_KEYXAI_API_KEY | — | Customer-provided xAI key. | | byok.openrouter | SONZAI_BYOK_OPENROUTER_KEYOPENROUTER_API_KEY | — | Customer-provided OpenRouter key. |

Bring Your Own Key (BYOK)

If you set any provider keys under byok, openclaw registers them with the Sonzai platform on startup. Sonzai then uses your key for upstream LLM calls and bills you only its 25% service fee instead of the full 125% platform markup.

Supported providers: openai, gemini, xai, openrouter. Pick whichever provider you've also configured as extractionProvider — that's the one Sonzai will route fact extraction through.

# Namespaced (recommended — won't get hijacked by unrelated tools)
export SONZAI_BYOK_OPENAI_KEY=sk-proj-...
# or standard provider env vars also work as a fallback:
export OPENAI_API_KEY=sk-proj-...

# Optional — only needed if your API key is scoped to a non-Default project
export SONZAI_PROJECT_ID=00000000-0000-0000-0000-000000000000

Registration runs fire-and-forget on every plugin load. Failures (bad key, network error, missing project access) are logged but do not block plugin startup. The platform PUT is idempotent, so re-runs are cheap — just update the env var and restart to rotate.

Switching memory mode

The plugin enforces the configured memoryMode on every bootstrap, so changing plugins.entries.sonzai.memoryMode in openclaw.json (or setting SONZAI_MEMORY_MODE=async) takes effect on the next session start — no manual agent update needed:

{
  "plugins": {
    "entries": {
      "sonzai": {
        "apiKey": "sk-...",
        "memoryMode": "async"  // default is "sync"
      }
    }
  }
}

REST API reference

The plugin calls these endpoints on your behalf via the @sonzai-labs/agents SDK. Always up-to-date — run just sync-spec to re-pull the production spec and regenerate the table.

Generated from spec/openapi.json (API version 1.0.0, synced 2026-04-23) — re-run just sync-spec to refresh.

| Method | Path | What the plugin uses it for | |--------|------|------------------------------| | GET | /agents/{agentId} | Fetch agent metadata | | GET | /agents/{agentId}/context | Enriched context for assemble() — per turn | | POST | /agents | Provision / look up agent (idempotent) | | POST | /agents/{agentId}/memory/consolidate | Consolidation pipeline trigger from compact() | | POST | /agents/{agentId}/process | Fact extraction from afterTurn() | | POST | /agents/{agentId}/sessions/end | Session close — dispose() | | POST | /agents/{agentId}/sessions/start | Session open — bootstrap() | | PUT | /agents/{agentId}/capabilities | Enforce memoryMode on every bootstrap |

Programmatic Engine Usage

The engine can also be used directly outside OpenClaw:

import { Sonzai } from "@sonzai-labs/agents";
import { SonzaiContextEngine, resolveConfig } from "@sonzai-labs/openclaw-context";

const client = new Sonzai({ apiKey: "sk-..." });
const config = resolveConfig({ apiKey: "sk-...", agentId: "agent-123" });
const engine = new SonzaiContextEngine(client, config);

await engine.bootstrap({ sessionId: "my-session" });
const { systemPromptAddition } = await engine.assemble({
  sessionId: "my-session",
  messages: [{ role: "user", content: "Hello!" }],
  tokenBudget: 4000,
});

License

MIT