fleet-memory/hindsight-integrations/openclaw/README.md
Nicolò Boschi e22ae05f47
refactor(openclaw)!: read config from plugin config instead of process.env (#974)
* refactor(openclaw)!: read config from plugin config instead of process.env

The plugin loaded credentials and runtime settings from environment
variables (HINDSIGHT_API_LLM_*, HINDSIGHT_EMBED_API_*, HINDSIGHT_BANK_ID)
plus auto-detection of OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY
/ GROQ_API_KEY. That tripped OpenClaw's install-scanner env-harvesting
rule and bypassed the framework's first-class SecretRef resolution.
Switch to reading from the plugin config exclusively, with secrets
configured via 'openclaw config set ... --ref-source env|file|exec'.

Combined with the daemon lifecycle extraction in #949, this closes the
remaining install-scanner findings the 0.5.x plugin was hitting. The
plugin source now contains neither process.env nor child_process; the
former moved to plugin config (resolved by OpenClaw before the plugin
loads), and the latter lives in @vectorize-io/hindsight-all under
node_modules where the scanner's directory walker skips it. The plugin
can be installed without --dangerously-force-unsafe-install.

BREAKING CHANGE: drops the llmApiKeyEnv plugin config field along with
the HINDSIGHT_API_LLM_*, HINDSIGHT_EMBED_API_*, and HINDSIGHT_BANK_ID
environment variables. Users must now configure llmProvider and
llmApiKey explicitly via 'openclaw config set'. Migration guide is in
hindsight-docs/docs-integrations/openclaw.md and the integration
changelog.

* chore(openclaw): pin published versions of hindsight-all and hindsight-client

Phase 2 (#949) introduced @vectorize-io/hindsight-all and
@vectorize-io/hindsight-client as plugin dependencies using 'file:'
workspace paths. Those paths resolve inside the monorepo but break when
the published tarball is installed outside it — 'openclaw plugins
install @vectorize-io/hindsight-openclaw' failed with 'Cannot find
module @vectorize-io/hindsight-all' because npm could not resolve the
file: path from the extracted extension directory.

Replace both with semver ranges targeting the published versions:

  @vectorize-io/hindsight-all   ^0.1.0
  @vectorize-io/hindsight-client ^0.5.0

Verified end-to-end: 'openclaw plugins install <local-tarball>' now
succeeds without --dangerously-force-unsafe-install and without the
workspace-symlink hack. npm pulls both dependencies from the registry
into the extracted extension's node_modules, the plugin loads cleanly,
and 'openclaw plugins doctor' reports no issues.
2026-04-10 18:27:28 +02:00

12 KiB

Hindsight Memory Plugin for OpenClaw

Biomimetic long-term memory for OpenClaw using Hindsight. Automatically captures conversations and intelligently recalls relevant context.

Quick Start

# 1. Install the plugin
openclaw plugins install @vectorize-io/hindsight-openclaw

# 2. Configure the LLM provider used for memory extraction.

# Option A — OpenAI (or any OpenAI-compatible provider)
openclaw config set plugins.entries.hindsight-openclaw.config.llmProvider openai
openclaw config set plugins.entries.hindsight-openclaw.config.llmApiKey \
    --ref-source env --ref-provider default --ref-id OPENAI_API_KEY

# Option B — Claude Code (no API key needed)
openclaw config set plugins.entries.hindsight-openclaw.config.llmProvider claude-code

# Option C — OpenAI Codex (no API key needed)
openclaw config set plugins.entries.hindsight-openclaw.config.llmProvider openai-codex

# 3. Start OpenClaw
openclaw gateway

That's it! The plugin will automatically start capturing and recalling memories.

llmApiKey is marked sensitive — openclaw config set ... --ref-source env writes a SecretRef that resolves the value from your OPENAI_API_KEY environment variable at runtime, so the key is never stored in plaintext on disk. --ref-source file and --ref-source exec are also supported for mounted-secret and Vault-style setups.

Migrating from 0.5.x

0.6.0 removes all process-environment reads from the plugin. Configuration that previously came from shell env vars must now go through OpenClaw's plugin config (with SecretRef for credentials). Concrete mappings:

Old (0.5.x) New (0.6.0)
OPENAI_API_KEY=… (auto-detected) openclaw config set plugins.entries.hindsight-openclaw.config.llmProvider openai
openclaw config set plugins.entries.hindsight-openclaw.config.llmApiKey --ref-source env --ref-id OPENAI_API_KEY
HINDSIGHT_API_LLM_PROVIDER=… openclaw config set plugins.entries.hindsight-openclaw.config.llmProvider …
HINDSIGHT_API_LLM_MODEL=… openclaw config set plugins.entries.hindsight-openclaw.config.llmModel …
HINDSIGHT_API_LLM_API_KEY=… openclaw config set plugins.entries.hindsight-openclaw.config.llmApiKey --ref-source env --ref-id …
HINDSIGHT_API_LLM_BASE_URL=… openclaw config set plugins.entries.hindsight-openclaw.config.llmBaseUrl …
HINDSIGHT_EMBED_API_URL=… openclaw config set plugins.entries.hindsight-openclaw.config.hindsightApiUrl …
HINDSIGHT_EMBED_API_TOKEN=… openclaw config set plugins.entries.hindsight-openclaw.config.hindsightApiToken --ref-source env --ref-id …
HINDSIGHT_BANK_ID=… openclaw config set plugins.entries.hindsight-openclaw.config.bankId …
llmApiKeyEnv: "MY_KEY" (plugin config) llmApiKey configured as a SecretRef with --ref-id MY_KEY

If your shell already exports OPENAI_API_KEY, the SecretRef config above resolves to the same value at startup — no need to change your shell setup, just point the plugin at the variable explicitly. Run openclaw config validate after migrating to confirm the new shape parses cleanly.

Features

  • Auto-capture and auto-recall of memories each turn, injected into system prompt space so recalled memories stay out of the visible chat transcript
  • Memory isolation — configurable per agent, channel, user, or provider via dynamicBankGranularity
  • Historical backfill CLI — import prior OpenClaw session history into Hindsight using the active plugin bank-routing config by default
  • Retention controls — choose which message roles to retain, toggle auto-retain on/off, and stamp retained documents with consistent tags/source metadata

Configuration

Optional settings in ~/.openclaw/openclaw.json under plugins.entries.hindsight-openclaw.config:

Option Default Description
apiPort 9077 Port for the local Hindsight daemon
daemonIdleTimeout 0 Seconds before daemon shuts down from inactivity (0 = never)
embedPort 0 Port for hindsight-embed server (0 = auto-assign)
embedVersion "latest" hindsight-embed version
embedPackagePath Local path to hindsight-embed package for development
bankMission Agent identity/purpose stored on the memory bank. Helps the engine understand context for better fact extraction. Set once per bank — not a recall prompt.
llmProvider LLM provider for memory extraction (openai, anthropic, gemini, groq, ollama, openai-codex, claude-code). Required unless hindsightApiUrl is set.
llmModel provider default LLM model used with llmProvider
llmApiKey API key for the LLM provider. Sensitive — set via openclaw config set ... --ref-source env --ref-id OPENAI_API_KEY to reference an env var (or --ref-source file/exec for mounted-secret/Vault sources).
llmBaseUrl Optional base URL override for OpenAI-compatible providers (e.g. https://openrouter.ai/api/v1)
dynamicBankId true Enable per-context memory banks
bankId Static bank ID used when dynamicBankId is false.
bankIdPrefix Prefix for bank IDs (e.g. "prod")
retainTags [] Tags applied to every retained document, useful for cross-agent/source labeling (e.g. source_system:openclaw, agent:agentname)
retainSource "openclaw" source value written into retained document metadata
dynamicBankGranularity ["agent", "channel", "user"] Fields used to derive bank ID. Options: agent, channel, user, provider
excludeProviders ["heartbeat"] Message providers to skip for recall/retain (e.g. heartbeat, slack, telegram, discord)
autoRecall true Auto-inject memories before each turn. Set to false when the agent has its own recall tool.
autoRetain true Auto-retain conversations after each turn
retainRoles ["user", "assistant"] Which message roles to retain. Options: user, assistant, system, tool
retainEveryNTurns 1 Retain every Nth turn. 1 = every turn (default). Values > 1 enable chunked retention with a sliding window.
retainOverlapTurns 0 Extra prior turns included when chunked retention fires. Window = retainEveryNTurns + retainOverlapTurns. Only applies when retainEveryNTurns > 1.
recallBudget "mid" Recall effort: low, mid, or high. Higher budgets use more retrieval strategies.
recallMaxTokens 1024 Max tokens for recall response. Controls how much memory context is injected per turn.
recallTypes ["world", "experience"] Memory types to recall. Options: world, experience, observation. Excludes verbose observation entries by default.
recallRoles ["user", "assistant"] Roles included when building prior context for recall query composition. Options: user, assistant, system, tool.
recallTopK Max number of memories to inject per turn. Applied after API response as a hard cap.
recallContextTurns 1 Number of user turns to include when composing recall query context. 1 keeps latest-message-only behavior.
recallMaxQueryChars 800 Maximum character length for the composed recall query before calling recall.
recallPromptPreamble built-in string Prompt text placed above recalled memories in the injected <hindsight_memories> system-context block.
hindsightApiUrl External Hindsight API URL (skips local daemon)
hindsightApiToken Auth token for external API. Sensitive — set via openclaw config set ... --ref-source env --ref-id HINDSIGHT_API_TOKEN.
ignoreSessionPatterns [] Session key glob patterns to skip entirely — no recall, no retain (e.g. ["agent:*:cron:**"])
statelessSessionPatterns [] Session key glob patterns for read-only sessions — retain is always skipped; recall is skipped when skipStatelessSessions is true (e.g. ["agent:*:subagent:**", "agent:*:heartbeat:**"])
skipStatelessSessions true When true, sessions matching statelessSessionPatterns also skip recall. Set to false to allow recall but still skip retain.

Session pattern filtering

ignoreSessionPatterns and statelessSessionPatterns accept glob patterns matched against the session key (format: agent:<agentId>:<type>:<uuid>).

Glob syntax:

  • * — matches any characters except : (single segment)
  • ** — matches anything including : (multiple segments)
Pattern Matches
agent:*:cron:** All cron sessions for any agent
agent:*:subagent:** All subagent sessions for any agent
agent:main:** All sessions under the main agent

Difference between the two options:

ignoreSessionPatterns statelessSessionPatterns
Retain Skipped Always skipped
Recall Skipped Skipped only when skipStatelessSessions: true

Example config — exclude cron jobs from memory entirely, allow subagents to read but not write memories:

{
  "ignoreSessionPatterns": ["agent:*:cron:**"],
  "statelessSessionPatterns": ["agent:*:subagent:**"],
  "skipStatelessSessions": false
}

Retention details

Retained documents use stable session-scoped IDs like openclaw:agent:agentname:discord:channel:123:turn:000001 (or ...:window:000002 for chunked retention), and include richer metadata such as session_key, agent_id, provider, channel_id, thread_id, sender_id, turn_index, and retention_scope.

Documentation

For full documentation, configuration options, troubleshooting, and development guide, see:

OpenClaw Integration Documentation

Development

To test local changes to the Hindsight package before publishing:

  1. Add embedPackagePath to your plugin config in ~/.openclaw/openclaw.json:
{
  "plugins": {
    "entries": {
      "hindsight-openclaw": {
        "enabled": true,
        "config": {
          "embedPackagePath": "/path/to/hindsight-wt3/hindsight-embed"
        }
      }
    }
  }
}
  1. The plugin will use uv run --directory <path> hindsight-embed instead of uvx hindsight-embed@latest

  2. To use a specific profile for testing:

# Check daemon status
uvx hindsight-embed@latest -p openclaw daemon status

# View logs
tail -f ~/.hindsight/profiles/openclaw.log

# List profiles
uvx hindsight-embed@latest profile list

Backfilling Existing OpenClaw History

The package includes a config-aware backfill CLI for importing historical OpenClaw sessions into Hindsight.

By default it mirrors the active plugin settings for:

  • dynamicBankId
  • dynamicBankGranularity
  • bankIdPrefix
  • local daemon vs external hindsightApiUrl

Dry-run example:

npx --package @vectorize-io/hindsight-openclaw hindsight-openclaw-backfill \
  --openclaw-root ~/.openclaw \
  --dry-run

Direct invocation from a built checkout:

node dist/backfill.js --openclaw-root ~/.openclaw --dry-run

Migration-oriented overrides are explicit:

node dist/backfill.js \
  --openclaw-root ~/.openclaw \
  --bank-strategy agent \
  --agent proj-run \
  --resume \
  --max-pending-operations 10

Useful options:

  • --agent <id> limit import to selected agents
  • --exclude-archive ignore sessions-archive-from-migration_backup
  • --bank-strategy mirror-config|agent|fixed
  • --resume skip only entries already finalized as completed
  • --checkpoint <path> store progress outside the default location
  • --wait-until-drained block until the touched bank queues have finished and checkpoint state can be finalized

License

MIT