Voice
Hindclaw
Production-grade Hindsight memory plugin for OpenClaw β per-agent config, multi-bank recall, IaC bank management
Install
openclaw plugins install hindclaw
README
<p align="center">
<img src=".github/assets/hindclaw.png" alt="HindClaw">
</p>
<p align="center">
Self-hosted Hindsight management platform β multi-tenant access control, user/group permissions, client integrations, and infrastructure tooling for AI agent memory.
</p>
<p align="center">
<a href="https://www.npmjs.com/package/hindclaw"><img src="https://img.shields.io/npm/v/hindclaw?style=flat-square&color=0f766e" alt="npm"></a>
<a href="https://pypi.org/project/hindclaw-extension/"><img src="https://img.shields.io/pypi/v/hindclaw-extension?style=flat-square&color=0f766e" alt="PyPI"></a>
<img src="https://img.shields.io/badge/license-MIT-10b981?style=flat-square" alt="License">
</p>
<p align="center">
<a href="https://hindclaw.pro">Documentation</a> ·
<a href="https://hindsight.vectorize.io">Hindsight</a> ·
<a href="https://openclaw.ai">OpenClaw</a>
</p>
---
## Why HindClaw?
Built on [Hindsight](https://hindsight.vectorize.io) β the highest-scoring agent memory system on the [LongMemEval benchmark](https://vectorize.io/#:~:text=The%20New%20Leader%20in%20Agent%20Memory).
The official Hindsight plugin gives you auto-capture and auto-recall. HindClaw adds what you need to run it in production β two orthogonal dimensions that combine per-message:
**WHO** (permissions) β resolved through 4 layers, each can override any field:
- Global config defaults β group merge β bank group override β bank user override
- Not just `recall: true/false` β LLM model, token budget, extraction depth, tag visibility, retention frequency. 11 configurable fields at every layer.
**HOW** (strategies) β resolved per topic:
- Each conversation topic routes to a named strategy with its own extraction mission, mode, and entity labels
- Strategies are orthogonal to permissions β a blocked user never reaches strategy resolution
```mermaid
graph TD
MSG["π¬ Message: user + bank + topic"] --> PERM["π Resolve permissions<br/>for THIS user on THIS bank"]
MSG --> STRAT["π― Resolve strategy<br/>for THIS topic on THIS bank"]
PERM --> R{"recall?"}
PERM --> W{"retain?"}
R -->|true| RECALL["π₯ Recall<br/>budget, tokens, tag filters<br/>from resolved permissions"]
R -->|false| NO_R["π« No recall"]
W -->|true| RETAIN["π€ Retain<br/>roles, tags, LLM model<br/>+ topic strategy"]
W -->|false| NO_W["π« No retain"]
STRAT --> RETAIN
style MSG fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style PERM fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style STRAT fill:#c2410c,color:#fff,stroke:#c2410c
style RECALL fill:#10b981,color:#fff,stroke:#10b981
style RETAIN fill:#10b981,color:#fff,stroke:#10b981
style NO_R fill:#ef4444,color:#fff,stroke:#ef4444
style NO_W fill:#f59e0b,color:#fff,stroke:#f59e0b
```
Every combination of **(user Γ bank Γ topic)** can produce different behavior β different access flags, different LLM model, different recall budget, different extraction strategy.
---
### π Per-User Access & Behavioral Overrides
The same user gets different behavior on different agents. Every parameter is configurable per group, overridable per bank and per user.
```mermaid
graph TD
MSG["π¬ Message"] --> ID["π Resolve identity"]
ID --> GROUPS["π₯ Merge group permissions"]
GROUPS --> BANK{"π¦ Bank overrides?"}
BANK -->|group override| BG["βοΈ Bank group permissions"]
BANK -->|user override| BU["π€ Bank user permissions"]
BANK -->|none| GLOBAL["π Global defaults"]
BG --> RESOLVED["β
Resolved permissions"]
BU --> RESOLVED
GLOBAL --> RESOLVED
RESOLVED --> TOPIC{"π― Topic?"}
TOPIC -->|mapped| STRATEGY["π Named strategy"]
TOPIC -->|unmapped| DEFAULT["π Bank defaults"]
style MSG fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style ID fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style GROUPS fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style BG fill:#c2410c,color:#fff,stroke:#c2410c
style BU fill:#c2410c,color:#fff,stroke:#c2410c
style GLOBAL fill:#c2410c,color:#fff,stroke:#c2410c
style RESOLVED fill:#0f766e,color:#fff,stroke:#0f766e
style STRATEGY fill:#10b981,color:#fff,stroke:#10b981
style DEFAULT fill:#f59e0b,color:#fff,stroke:#f59e0b
```
**Override chain** (most specific wins):
```
config.json5 defaults β group β bank group β bank user
```
**Configurable at every level:** `recall`, `retain`, `retainRoles`, `retainTags`, `retainEveryNTurns`, `recallBudget`, `recallMaxTokens`, `recallTagGroups`, `llmModel`, `llmProvider`, `excludeProviders`
**Same user, different agents:**
| | agent-1 (strategic) | agent-2 (financial) |
|---|---|---|
| **user-1** (executive) | recall + retain, high budget, no filters | recall + retain, high budget, no filters |
| **user-2** (dept-head) | recall only, mid budget, filtered | recall + retain, high budget (user override) |
| **user-3** (staff) | blocked (no entry β `_default`) | recall only, low budget, filtered |
| **anonymous** | blocked | blocked |
### π Cross-Agent Recall
One agent queries multiple banks in parallel. Permissions checked per-bank.
```mermaid
graph LR
Q["π agent-1 recall query"] --> B1["π¦ bank: agent-1"]
Q --> B2["π¦ bank: agent-2"]
Q --> B3["π¦ bank: agent-3"]
B1 -->|recall: true| R1["π₯ results"]
B2 -->|recall: true| R2["π₯ results"]
B3 -->|recall: false| SKIP["π« skipped"]
R1 --> MERGE["π Merge + interleave"]
R2 --> MERGE
MERGE --> INJECT["π Inject into prompt"]
style Q fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style B1 fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style B2 fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style B3 fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style R1 fill:#10b981,color:#fff,stroke:#10b981
style R2 fill:#10b981,color:#fff,stroke:#10b981
style SKIP fill:#ef4444,color:#fff,stroke:#ef4444
style MERGE fill:#0f766e,color:#fff,stroke:#0f766e
style INJECT fill:#0f766e,color:#fff,stroke:#0f766e
```
### π― Named Retain Strategies
Different conversation topics routed to different extraction strategies.
```mermaid
graph LR
MSG["π¬ Incoming message"] --> TOPIC{"π― Topic ID?"}
TOPIC -->|280304| DEEP["π¬ deep-analysis"]
TOPIC -->|280418| LIGHT["β‘ lightweight"]
TOPIC -->|other| DEFAULT["π bank default"]
DEEP --> RETAIN1["π Verbose extraction"]
LIGHT --> RETAIN2["π Concise extraction"]
DEFAULT --> RETAIN3["π Standard extraction"]
style MSG fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style DEEP fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style LIGHT fill:#f59e0b,color:#fff,stroke:#f59e0b
style DEFAULT fill:#c2410c,color:#fff,stroke:#c2410c
style RETAIN1 fill:#10b981,color:#fff,stroke:#10b981
style RETAIN2 fill:#10b981,color:#fff,stroke:#10b981
style RETAIN3 fill:#10b981,color:#fff,stroke:#10b981
```
### ποΈ Infrastructure as Code
`hindclaw plan` shows what will change. `hindclaw apply` syncs it. Like Terraform for memory banks.
```mermaid
graph LR
FILE["π Bank config files"] --> PLAN["π hindclaw plan"]
PLAN --> DIFF{"π Changes?"}
DIFF -->|none| OK["β
Up to date"]
DIFF -->|yes| SHOW["π Show diff"]
SHOW --> APPLY["β‘ hindclaw apply"]
APPLY --> CONFIRM{"β Confirm?"}
CONFIRM -->|yes| SYNC["π Sync to Hindsight"]
CONFIRM -->|no| CANCEL["β Cancelled"]
style FILE fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style PLAN fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style APPLY fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style OK fill:#10b981,color:#fff,stroke:#10b981
style SHOW fill:#f59e0b,color:#fff,stroke:#f59e0b
style SYNC fill:#10b981,color:#fff,stroke:#10b981
style CANCEL fill:#ef4444,color:#fff,stroke:#ef4444
```
### π§© Session Start Context
Mental models loaded before the first message β no cold start.
```mermaid
graph LR
START["π¬ Session starts"] --> LOAD["π¦ Load mental models"]
LOAD --> M1["π§ Project context"]
LOAD --> M2["π€ User preferences"]
M1 --> INJECT["π Inject into system prompt"]
M2 --> INJECT
INJECT --> READY["β
Agent ready with full context"]
READY --> MSG1["π¬ First user message"]
style START fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style LOAD fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style M1 fill:#c2410c,color:#fff,stroke:#c2410c
style M2 fill:#c2410c,color:#fff,stroke:#c2410c
style INJECT fill:#0f766e,color:#fff,stroke:#0f766e
style READY fill:#10b981,color:#fff,stroke:#10b981
style MSG1 fill:#10b981,color:#fff,stroke:#10b981
```
### πͺ Reflect on Recall
Instead of raw memory retrieval, the agent reasons over its memories.
```mermaid
graph LR
Q["π¬ User question"] --> MODE{"πͺ Reflect enabled?"}
MODE -->|yes| REFLECT["π§ Hindsight reflect API"]
MODE -->|no| RECALL["π₯ Hindsight recall API"]
REFLECT --> REASON["π‘ LLM reasons over memories"]
REASON --> ANSWER["β
Grounded response"]
RECALL --> RAW["π Raw memory list"]
RAW --> ANSWER
style Q fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style REFLECT fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style RECALL fill:#c2410c,color:#fff,stroke:#c2410c
style REASON fill:#0f766e,color:#fff,stroke:#0f766e
style RAW fill:#f59e0b,color:#fff,stroke:#f59e0b
style ANSWER fill:#10b981,color:#fff,stroke:#10b981
```
### π Multi-Server Support
Per-agent infrastructure routing β one gateway, multiple Hindsight servers.
```mermaid
graph LR
GW["π Gateway"] --> A1["π€ agent-1"]
GW --> A2["π€ agent-2"]
GW --> A3["π€ agent-3"]
GW --> A4["π€ agent-4"]
A1 --> HOME["π Home server"]
A2 --> HOME
A3 --> OFFICE["π’ Office server"]
A4 --> LOCAL["π» Local daemon"]
style GW fill:#0f766e,color:#fff,stroke:#0f766e
style A1 fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style A2 fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style A3 fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style A4 fill:#1d4ed8,color:#fff,stroke:#1d4ed8
style HOME fill:#8b5cf6,color:#fff,stroke:#8b5cf6
style OFFICE fill:#c2410c,color:#fff,st
... (truncated)
voice
Comments
Sign in to leave a comment