doc: add langgraph and nemoclaw (#633)

This commit is contained in:
Nicolò Boschi 2026-03-20 16:18:05 +01:00 committed by GitHub
parent 72b61214f6
commit ce691549ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
58 changed files with 1652 additions and 169 deletions

View file

@ -6,6 +6,8 @@ sidebar_position: 4
The `@vectorize-io/hindsight-ai-sdk` package integrates [Hindsight](https://hindsight.vectorize.io) memory with the [Vercel AI SDK](https://ai-sdk.dev). It provides five ready-to-use tools for retaining, recalling, and reflecting on long-term memories.
[View Changelog →](/changelog/integrations/ai-sdk)
import CodeSnippet from '@site/src/components/CodeSnippet';
import aiSdkTs from '!!raw-loader!@site/examples/integrations/ai-sdk.ts';

View file

@ -6,6 +6,8 @@ sidebar_position: 5
We built `@vectorize-io/hindsight-chat` to give [Vercel Chat SDK](https://github.com/vercel/chat) bots persistent, per-user memory with a single handler wrapper. The integration works across Slack, Discord, Teams, Google Chat, GitHub, and Linear — no custom plumbing required.
[View Changelog →](/changelog/integrations/chat)
## Installation
```bash

View file

@ -6,6 +6,8 @@ sidebar_position: 5
Persistent memory for AI agent crews via [CrewAI](https://github.com/crewAIInc/crewAI). Give your crews long-term memory with fact extraction, entity tracking, and temporal awareness.
[View Changelog →](/changelog/integrations/crewai)
## Features
- **Drop-in Storage Backend** - Implements CrewAI's `Storage` interface for `ExternalMemory`

View file

@ -6,6 +6,8 @@ sidebar_position: 7
Persistent long-term memory for [LangGraph](https://langchain-ai.github.io/langgraph/) and [LangChain](https://python.langchain.com/) agents via Hindsight. Three integration patterns at different abstraction levels — the tools pattern works with both LangChain and LangGraph, while nodes and the BaseStore adapter are LangGraph-specific.
[View Changelog →](/changelog/integrations/langgraph)
## Features
- **Memory Tools** — retain, recall, and reflect as LangChain `@tool` functions compatible with `bind_tools()` and `ToolNode`. Works with **both LangChain and LangGraph** — no LangGraph dependency required for this pattern.

View file

@ -6,6 +6,8 @@ sidebar_position: 1
Universal LLM memory integration via [LiteLLM](https://github.com/BerriAI/litellm). Add persistent memory to any LLM application with just a few lines of code.
[View Changelog →](/changelog/integrations/litellm)
## Features
- **Universal LLM Support** - Works with 100+ LLM providers via LiteLLM (OpenAI, Anthropic, Groq, Azure, AWS Bedrock, Google Vertex AI, and more)

View file

@ -8,6 +8,8 @@ Persistent memory for [NemoClaw](https://nemoclaw.ai) sandboxed agents using [Hi
NemoClaw runs [OpenClaw](https://openclaw.ai) inside an OpenShell sandbox with controlled filesystem, process, and network egress policies. The `hindsight-nemoclaw` package automates adding Hindsight memory to a sandbox in one command — no code changes required.
[View Changelog →](/changelog/integrations/nemoclaw)
## Quick Start
```bash

View file

@ -8,6 +8,8 @@ Local, long term memory for [OpenClaw](https://openclaw.ai) agents using [Hindsi
This plugin integrates [hindsight-embed](https://vectorize.io/hindsight/cli), a standalone daemon that bundles Hindsight's memory engine (API + PostgreSQL) into a single command. Everything runs locally on your machine, reuses the LLM you're already paying for, and costs nothing extra.
[View Changelog →](/changelog/integrations/openclaw)
## Quick Start
**Step 1: Set up LLM for memory extraction**

View file

@ -6,6 +6,8 @@ sidebar_position: 6
Persistent memory tools for [Pydantic AI](https://ai.pydantic.dev/) agents via Hindsight. Give your agents long-term memory with retain, recall, and reflect — all async-native with no thread-pool hacks.
[View Changelog →](/changelog/integrations/pydantic-ai)
## Features
- **Async-Native Tools** — Uses Pydantic AI's async tool interface directly (`aretain`, `arecall`, `areflect`)

View file

@ -232,6 +232,12 @@ const sidebars: SidebarsConfig = {
label: 'LangGraph / LangChain',
customProps: { icon: '/img/icons/langgraph.png' },
},
{
type: 'doc',
id: 'sdks/integrations/nemoclaw',
label: 'NemoClaw',
customProps: { icon: '/img/icons/nemoclaw.png' },
},
{
type: 'doc',
id: 'sdks/integrations/skills',

View file

@ -100,6 +100,26 @@
"link": "/sdks/integrations/skills",
"icon": "/img/icons/skills.png"
},
{
"id": "langgraph",
"name": "LangGraph / LangChain",
"description": "Add persistent memory to LangGraph and LangChain agents. Supports Memory Tools, Graph Nodes, and BaseStore adapter patterns.",
"type": "official",
"by": "hindsight",
"category": "framework",
"link": "/sdks/integrations/langgraph",
"icon": "/img/icons/langgraph.png"
},
{
"id": "nemoclaw",
"name": "NemoClaw",
"description": "Persistent memory for NemoClaw sandboxed agents. One-command setup — no code changes required.",
"type": "official",
"by": "hindsight",
"category": "framework",
"link": "/sdks/integrations/nemoclaw",
"icon": "/img/icons/nemoclaw.png"
},
{
"id": "hindsight-openclaw-pro",
"name": "hindsight-openclaw-pro",

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# AI SDK Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-ai-sdk`](https://www.npmjs.com/package/@vectorize-io/hindsight-ai-sdk) — memory integration for Vercel AI SDK.
<PageHero title="Vercel AI SDK Changelog" subtitle="@vectorize-io/hindsight-ai-sdk — memory integration for Vercel AI SDK." />
For the source code, see [`hindsight-integrations/ai-sdk`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/ai-sdk).
← [Back to main changelog](/changelog)
[← Vercel AI SDK integration](/sdks/integrations/ai-sdk)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# Chat SDK Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-chat`](https://www.npmjs.com/package/@vectorize-io/hindsight-chat) — memory integration for Vercel Chat SDK.
<PageHero title="Vercel Chat SDK Changelog" subtitle="@vectorize-io/hindsight-chat — memory integration for Vercel Chat SDK." />
For the source code, see [`hindsight-integrations/chat`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/chat).
← [Back to main changelog](/changelog)
[← Vercel Chat SDK integration](/sdks/integrations/chat)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# CrewAI Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-crewai`](https://pypi.org/project/hindsight-crewai/) — persistent memory for CrewAI agents.
<PageHero title="CrewAI Changelog" subtitle="hindsight-crewai — persistent memory for CrewAI agents." />
For the source code, see [`hindsight-integrations/crewai`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/crewai).
← [Back to main changelog](/changelog)
[← CrewAI integration](/sdks/integrations/crewai)

View file

@ -2,13 +2,11 @@
hide_table_of_contents: true
---
# LangGraph Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-langgraph`](https://pypi.org/project/hindsight-langgraph/) — LangGraph memory integration with tools, nodes, and store patterns.
<PageHero title="LangGraph Changelog" subtitle="hindsight-langgraph — LangGraph and LangChain memory integration." />
For the source code, see [`hindsight-integrations/langgraph`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/langgraph).
← [Back to main changelog](/changelog)
[← LangGraph integration](/sdks/integrations/langgraph)
## [0.1.1](https://github.com/vectorize-io/hindsight/tree/integrations/langgraph/v0.1.1)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# LiteLLM Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-litellm`](https://pypi.org/project/hindsight-litellm/) — universal LLM memory integration via LiteLLM.
<PageHero title="LiteLLM Changelog" subtitle="hindsight-litellm — universal LLM memory integration via LiteLLM." />
For the source code, see [`hindsight-integrations/litellm`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/litellm).
← [Back to main changelog](/changelog)
[← LiteLLM integration](/sdks/integrations/litellm)

View file

@ -2,13 +2,11 @@
hide_table_of_contents: true
---
# NemoClaw Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-nemoclaw`](https://www.npmjs.com/package/@vectorize-io/hindsight-nemoclaw).
<PageHero title="NemoClaw Changelog" subtitle="@vectorize-io/hindsight-nemoclaw — persistent memory for NemoClaw sandboxed agents." />
For the source code, see [`hindsight-integrations/nemoclaw`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/nemoclaw).
← [Back to main changelog](/changelog)
[← NemoClaw integration](/sdks/integrations/nemoclaw)
## [0.1.1](https://github.com/vectorize-io/hindsight/tree/integrations/nemoclaw/v0.1.1)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# OpenClaw Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-openclaw`](https://www.npmjs.com/package/@vectorize-io/hindsight-openclaw) — Hindsight memory plugin for OpenClaw.
<PageHero title="OpenClaw Changelog" subtitle="@vectorize-io/hindsight-openclaw — Hindsight memory plugin for OpenClaw." />
For the source code, see [`hindsight-integrations/openclaw`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/openclaw).
← [Back to main changelog](/changelog)
[← OpenClaw integration](/sdks/integrations/openclaw)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# Pydantic AI Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-pydantic-ai`](https://pypi.org/project/hindsight-pydantic-ai/) — persistent memory tools for Pydantic AI agents.
<PageHero title="Pydantic AI Changelog" subtitle="hindsight-pydantic-ai — persistent memory tools for Pydantic AI agents." />
For the source code, see [`hindsight-integrations/pydantic-ai`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/pydantic-ai).
← [Back to main changelog](/changelog)
[← Pydantic AI integration](/sdks/integrations/pydantic-ai)

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

View file

@ -13,6 +13,7 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
{/* Import raw source files */}
import documentsPy from '!!raw-loader!@site/examples/api/documents.py';
import documentsMjs from '!!raw-loader!@site/examples/api/documents.mjs';
import documentsGo from '!!raw-loader!@site/examples/api/documents.go';
:::tip Prerequisites
Make sure you've completed the [Quick Start](./quickstart) and understand [how retain works](./retain).
@ -60,6 +61,9 @@ hindsight memory retain my-bank "Meeting notes content..." --doc-id notes-2024-0
hindsight memory retain-files my-bank docs/
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={documentsGo} section="document-retain" language="go" />
</TabItem>
</Tabs>
@ -84,6 +88,9 @@ hindsight memory retain my-bank "Project deadline: March 31" --doc-id project-pl
hindsight memory retain my-bank "Project deadline: April 15 (extended)" --doc-id project-plan
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={documentsGo} section="document-update" language="go" />
</TabItem>
</Tabs>
@ -104,6 +111,9 @@ Retrieve a document's original text and metadata. This is useful for expanding d
hindsight document get my-bank meeting-2024-03-15
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={documentsGo} section="document-get" language="go" />
</TabItem>
</Tabs>
@ -128,6 +138,9 @@ hindsight document update-tags my-bank meeting-2024-03-15 --tags team-a --tags t
hindsight document update-tags my-bank meeting-2024-03-15
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={documentsGo} section="document-update" language="go" />
</TabItem>
</Tabs>
@ -152,6 +165,9 @@ Remove a document and all its associated memories:
hindsight document delete my-bank meeting-2024-03-15
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={documentsGo} section="document-delete" language="go" />
</TabItem>
</Tabs>
@ -183,6 +199,9 @@ hindsight document list my-bank --q report
hindsight document list my-bank --tags team-a --tags team-b
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={documentsGo} section="document-list" language="go" />
</TabItem>
</Tabs>

View file

@ -13,6 +13,7 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
{/* Import raw source files */}
import mainMethodsPy from '!!raw-loader!@site/examples/api/main-methods.py';
import mainMethodsMjs from '!!raw-loader!@site/examples/api/main-methods.mjs';
import mainMethodsGo from '!!raw-loader!@site/examples/api/main-methods.go';
:::tip Prerequisites
Make sure you've [installed Hindsight](../installation) and completed the [Quick Start](./quickstart).
@ -33,15 +34,18 @@ Store conversations, documents, and facts into a memory bank.
```bash
# Store a single fact
hindsight retain my-bank "Alice joined Google in March 2024 as a Senior ML Engineer"
hindsight memory retain my-bank "Alice joined Google in March 2024 as a Senior ML Engineer"
# Store from a file
hindsight retain my-bank --file conversation.txt --context "Daily standup"
hindsight memory retain-files my-bank conversation.txt --context "Daily standup"
# Store multiple files
hindsight retain my-bank --files docs/*.md
hindsight memory retain-files my-bank docs/
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mainMethodsGo} section="main-retain" language="go" />
</TabItem>
</Tabs>
@ -66,18 +70,21 @@ Search for relevant memories using multi-strategy retrieval.
```bash
# Basic search
hindsight recall my-bank "What does Alice do at Google?"
hindsight memory recall my-bank "What does Alice do at Google?"
# Search with options
hindsight recall my-bank "What happened last spring?" \
hindsight memory recall my-bank "What happened last spring?" \
--budget high \
--max-tokens 8192 \
--fact-type world
--fact-type world,experience
# Verbose output (shows weights and sources)
hindsight recall my-bank "Tell me about Alice" -v
# Verbose output
hindsight memory recall my-bank "Tell me about Alice" -v
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mainMethodsGo} section="main-recall" language="go" />
</TabItem>
</Tabs>
@ -102,15 +109,15 @@ Generate disposition-aware responses using memories and observations.
```bash
# Basic reflect
hindsight reflect my-bank "Should we adopt TypeScript for our backend?"
# Verbose output (shows sources and observations)
hindsight reflect my-bank "What are Alice's strengths for the team lead role?" -v
hindsight memory reflect my-bank "Should we adopt TypeScript for our backend?"
# With higher reasoning budget
hindsight reflect my-bank "Analyze our tech stack" --budget high
hindsight memory reflect my-bank "Analyze our tech stack" --budget high
```
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mainMethodsGo} section="main-reflect" language="go" />
</TabItem>
</Tabs>

View file

@ -13,8 +13,12 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
{/* Import raw source files */}
import memoryBanksPy from '!!raw-loader!@site/examples/api/memory-banks.py';
import memoryBanksMjs from '!!raw-loader!@site/examples/api/memory-banks.mjs';
import memoryBanksSh from '!!raw-loader!@site/examples/api/memory-banks.sh';
import memoryBanksGo from '!!raw-loader!@site/examples/api/memory-banks.go';
import directivesPy from '!!raw-loader!@site/examples/api/directives.py';
import directivesMjs from '!!raw-loader!@site/examples/api/directives.mjs';
import directivesSh from '!!raw-loader!@site/examples/api/directives.sh';
import directivesGo from '!!raw-loader!@site/examples/api/directives.go';
## What is a Memory Bank?
@ -44,11 +48,10 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
<CodeSnippet code={memoryBanksMjs} section="create-bank" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
hindsight bank create my-bank
```
<CodeSnippet code={memoryBanksSh} section="create-bank" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={memoryBanksGo} section="create-bank" language="go" />
</TabItem>
</Tabs>
@ -205,6 +208,12 @@ How skeptical vs trusting the bank is when evaluating claims during `reflect`. S
<TabItem value="node" label="Node.js">
<CodeSnippet code={memoryBanksMjs} section="bank-with-disposition" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={memoryBanksSh} section="bank-with-disposition" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={memoryBanksGo} section="bank-with-disposition" language="go" />
</TabItem>
</Tabs>
| Value | Behaviour |
@ -275,6 +284,12 @@ Bank configuration fields (retain mission, extraction mode, observations mission
<TabItem value="node" label="Node.js">
<CodeSnippet code={memoryBanksMjs} section="update-bank-config" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={memoryBanksSh} section="update-bank-config" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={memoryBanksGo} section="update-bank-config" language="go" />
</TabItem>
</Tabs>
You can update any subset of fields — only the keys you provide are changed.
@ -288,6 +303,12 @@ You can update any subset of fields — only the keys you provide are changed.
<TabItem value="node" label="Node.js">
<CodeSnippet code={memoryBanksMjs} section="get-bank-config" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={memoryBanksSh} section="get-bank-config" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={memoryBanksGo} section="get-bank-config" language="go" />
</TabItem>
</Tabs>
The response distinguishes:
@ -303,6 +324,12 @@ The response distinguishes:
<TabItem value="node" label="Node.js">
<CodeSnippet code={memoryBanksMjs} section="reset-bank-config" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={memoryBanksSh} section="reset-bank-config" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={memoryBanksGo} section="reset-bank-config" language="go" />
</TabItem>
</Tabs>
This removes all bank-level overrides. The bank reverts to server-wide defaults (set via environment variables).
@ -337,6 +364,12 @@ Use directives for rules that must never be violated:
<TabItem value="node" label="Node.js">
<CodeSnippet code={directivesMjs} section="create-directive" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={directivesSh} section="create-directive" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={directivesGo} section="create-directive" language="go" />
</TabItem>
</Tabs>
### Listing Directives
@ -348,6 +381,12 @@ Use directives for rules that must never be violated:
<TabItem value="node" label="Node.js">
<CodeSnippet code={directivesMjs} section="list-directives" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={directivesSh} section="list-directives" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={directivesGo} section="list-directives" language="go" />
</TabItem>
</Tabs>
### Updating Directives
@ -359,6 +398,12 @@ Use directives for rules that must never be violated:
<TabItem value="node" label="Node.js">
<CodeSnippet code={directivesMjs} section="update-directive" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={directivesSh} section="update-directive" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={directivesGo} section="update-directive" language="go" />
</TabItem>
</Tabs>
### Deleting Directives
@ -370,6 +415,12 @@ Use directives for rules that must never be violated:
<TabItem value="node" label="Node.js">
<CodeSnippet code={directivesMjs} section="delete-directive" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={directivesSh} section="delete-directive" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={directivesGo} section="delete-directive" language="go" />
</TabItem>
</Tabs>
### Directives vs Disposition

View file

@ -12,6 +12,9 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
{/* Import raw source files */}
import mentalModelsPy from '!!raw-loader!@site/examples/api/mental-models.py';
import mentalModelsMjs from '!!raw-loader!@site/examples/api/mental-models.mjs';
import mentalModelsSh from '!!raw-loader!@site/examples/api/mental-models.sh';
import mentalModelsGo from '!!raw-loader!@site/examples/api/mental-models.go';
## What Are Mental Models?
@ -56,22 +59,14 @@ Creating a mental model runs a reflect operation in the background and saves the
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="create-mental-model" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="create-mental-model" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
# Create a mental model (async operation)
curl -X POST "http://localhost:8888/v1/default/banks/my-bank/mental-models" \
-H "Content-Type: application/json" \
-d '{
"name": "Team Communication Preferences",
"source_query": "How does the team prefer to communicate?",
"tags": ["team"]
}'
# Response: {"operation_id": "op-123"}
# Use the operations endpoint to check completion
```
<CodeSnippet code={mentalModelsSh} section="create-mental-model" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="create-mental-model" language="go" />
</TabItem>
</Tabs>
@ -81,12 +76,38 @@ curl -X POST "http://localhost:8888/v1/default/banks/my-bank/mental-models" \
|-----------|------|----------|-------------|
| `name` | string | Yes | Human-readable name for the mental model |
| `source_query` | string | Yes | The query to run to generate content |
| `id` | string | No | Custom ID for the mental model (alphanumeric lowercase with hyphens). Auto-generated if omitted. |
| `tags` | list | No | Tags for filtering during retrieval |
| `max_tokens` | int | No | Maximum tokens for the mental model content |
| `trigger` | object | No | Trigger settings (see [Automatic Refresh](#automatic-refresh)) |
---
## Create with Custom ID
Assign a stable, human-readable ID to a mental model so you can retrieve or update it by name instead of relying on the auto-generated UUID:
<Tabs>
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="create-mental-model-with-id" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="create-mental-model-with-id" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={mentalModelsSh} section="create-mental-model-with-id" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="create-mental-model-with-id" language="go" />
</TabItem>
</Tabs>
:::tip
Custom IDs must be lowercase alphanumeric and may contain hyphens (e.g. `team-policies`, `q4-status`). If a mental model with that ID already exists, the request is rejected.
:::
---
## Automatic Refresh
Mental models can be configured to **automatically refresh** when observations are updated. This keeps them in sync with the latest knowledge without manual intervention.
@ -103,19 +124,14 @@ When `refresh_after_consolidation` is enabled, the mental model will be re-gener
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="create-mental-model-with-trigger" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="create-mental-model-with-trigger" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
# Create a mental model with automatic refresh enabled
curl -X POST "http://localhost:8888/v1/default/banks/my-bank/mental-models" \
-H "Content-Type: application/json" \
-d '{
"name": "Project Status",
"source_query": "What is the current project status?",
"trigger": {"refresh_after_consolidation": true}
}'
```
<CodeSnippet code={mentalModelsSh} section="create-mental-model-with-trigger" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="create-mental-model-with-trigger" language="go" />
</TabItem>
</Tabs>
@ -140,12 +156,14 @@ Enable automatic refresh for mental models that need to stay current. Disable it
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="list-mental-models" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="list-mental-models" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
curl "http://localhost:8888/v1/default/banks/my-bank/mental-models"
```
<CodeSnippet code={mentalModelsSh} section="list-mental-models" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="list-mental-models" language="go" />
</TabItem>
</Tabs>
@ -157,12 +175,14 @@ curl "http://localhost:8888/v1/default/banks/my-bank/mental-models"
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="get-mental-model" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="get-mental-model" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
curl "http://localhost:8888/v1/default/banks/my-bank/mental-models/{mental_model_id}"
```
<CodeSnippet code={mentalModelsSh} section="get-mental-model" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="get-mental-model" language="go" />
</TabItem>
</Tabs>
@ -190,12 +210,14 @@ Re-run the source query to update the mental model with current knowledge:
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="refresh-mental-model" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="refresh-mental-model" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
curl -X POST "http://localhost:8888/v1/default/banks/my-bank/mental-models/{mental_model_id}/refresh"
```
<CodeSnippet code={mentalModelsSh} section="refresh-mental-model" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="refresh-mental-model" language="go" />
</TabItem>
</Tabs>
@ -214,14 +236,14 @@ Update the mental model's name:
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="update-mental-model" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="update-mental-model" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
curl -X PATCH "http://localhost:8888/v1/default/banks/my-bank/mental-models/{mental_model_id}" \
-H "Content-Type: application/json" \
-d '{"name": "Updated Team Communication Preferences"}'
```
<CodeSnippet code={mentalModelsSh} section="update-mental-model" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="update-mental-model" language="go" />
</TabItem>
</Tabs>
@ -233,12 +255,14 @@ curl -X PATCH "http://localhost:8888/v1/default/banks/my-bank/mental-models/{men
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="delete-mental-model" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="delete-mental-model" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
```bash
curl -X DELETE "http://localhost:8888/v1/default/banks/my-bank/mental-models/{mental_model_id}"
```
<CodeSnippet code={mentalModelsSh} section="delete-mental-model" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="delete-mental-model" language="go" />
</TabItem>
</Tabs>
@ -280,6 +304,15 @@ Every time a mental model's content changes (via refresh or manual update), the
<TabItem value="python" label="Python">
<CodeSnippet code={mentalModelsPy} section="get-mental-model-history" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={mentalModelsMjs} section="get-mental-model-history" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={mentalModelsSh} section="get-mental-model-history" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={mentalModelsGo} section="get-mental-model-history" language="go" />
</TabItem>
</Tabs>
### Response

View file

@ -15,6 +15,7 @@ import {ClientsGrid} from '@site/src/components/SupportedGrids';
import quickstartPy from '!!raw-loader!@site/examples/api/quickstart.py';
import quickstartMjs from '!!raw-loader!@site/examples/api/quickstart.mjs';
import quickstartSh from '!!raw-loader!@site/examples/api/quickstart.sh';
import quickstartGo from '!!raw-loader!@site/examples/api/quickstart.go';
## Clients
@ -90,6 +91,15 @@ curl -fsSL https://hindsight.vectorize.io/get-cli | bash
<CodeSnippet code={quickstartSh} section="quickstart-full" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
```bash
go get github.com/vectorize-io/hindsight/hindsight-clients/go
```
<CodeSnippet code={quickstartGo} section="quickstart-full" language="go" />
</TabItem>
</Tabs>

View file

@ -16,6 +16,7 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
import recallPy from '!!raw-loader!@site/examples/api/recall.py';
import recallMjs from '!!raw-loader!@site/examples/api/recall.mjs';
import recallSh from '!!raw-loader!@site/examples/api/recall.sh';
import recallGo from '!!raw-loader!@site/examples/api/recall.go';
:::info How Recall Works
Learn about the four retrieval strategies (semantic, keyword, graph, temporal) and RRF fusion in the [Recall Architecture](/developer/retrieval) guide.
@ -37,6 +38,9 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-basic" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-basic" language="go" />
</TabItem>
</Tabs>
---
@ -59,9 +63,19 @@ Each type runs the full four-strategy retrieval pipeline independently, so narro
<CodeSnippet code={recallPy} section="recall-experience-only" language="python" />
<CodeSnippet code={recallPy} section="recall-observations-only" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-world-only" language="javascript" />
<CodeSnippet code={recallMjs} section="recall-experience-only" language="javascript" />
<CodeSnippet code={recallMjs} section="recall-observations-only" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-fact-type" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-world-only" language="go" />
<CodeSnippet code={recallGo} section="recall-experience-only" language="go" />
<CodeSnippet code={recallGo} section="recall-observations-only" language="go" />
</TabItem>
</Tabs>
:::tip About Observations
@ -79,6 +93,12 @@ Controls retrieval depth and breadth. Accepted values are `low`, `mid` (default)
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-budget-levels" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-budget-levels" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-budget-levels" language="go" />
</TabItem>
</Tabs>
### max_tokens
@ -89,6 +109,15 @@ The maximum number of tokens the returned facts can collectively occupy. Default
<TabItem value="python" label="Python">
<CodeSnippet code={recallPy} section="recall-token-budget" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-token-budget" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-token-budget" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-token-budget" language="go" />
</TabItem>
</Tabs>
### query_timestamp
@ -118,6 +147,12 @@ When enabled and `types` includes `observation`, each observation result is acco
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-source-facts" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-source-facts" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-source-facts" language="go" />
</TabItem>
</Tabs>
#### entities
@ -152,7 +187,20 @@ Consider a bank with these four memories:
Returns memories that have **at least one** matching tag, plus untagged memories.
<Tabs>
<TabItem value="python" label="Python">
<CodeSnippet code={recallPy} section="recall-tags-any" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-tags-any" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-tags-any" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-with-tags" language="go" />
</TabItem>
</Tabs>
Use this for **shared global knowledge + user-specific** patterns, where untagged memories represent information everyone should see.
@ -160,7 +208,20 @@ Use this for **shared global knowledge + user-specific** patterns, where untagge
Same as `any` but untagged memories are excluded.
<Tabs>
<TabItem value="python" label="Python">
<CodeSnippet code={recallPy} section="recall-tags-any-strict" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-tags-any-strict" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-tags-any-strict" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-tags-strict" language="go" />
</TabItem>
</Tabs>
Use this when memories are **fully partitioned by tags** and untagged memories should never be visible.
@ -168,7 +229,20 @@ Use this when memories are **fully partitioned by tags** and untagged memories s
Returns memories that have **every** specified tag, plus untagged memories.
<Tabs>
<TabItem value="python" label="Python">
<CodeSnippet code={recallPy} section="recall-tags-all-mode" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-tags-all-mode" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-tags-all-mode" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-tags-all-mode" language="go" />
</TabItem>
</Tabs>
Use this when memories must belong to a **specific intersection** of scopes (e.g., only memories relevant to both a user and a project), while still surfacing shared global knowledge.
@ -176,7 +250,20 @@ Use this when memories must belong to a **specific intersection** of scopes (e.g
Returns memories that have **every** specified tag, and excludes untagged memories.
<Tabs>
<TabItem value="python" label="Python">
<CodeSnippet code={recallPy} section="recall-tags-all-strict" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={recallMjs} section="recall-tags-all-strict" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={recallSh} section="recall-tags-all-strict" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={recallGo} section="recall-tags-all" language="go" />
</TabItem>
</Tabs>
Use this for strict scope enforcement where a memory must explicitly belong to **all** specified contexts.

View file

@ -16,6 +16,7 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
import reflectPy from '!!raw-loader!@site/examples/api/reflect.py';
import reflectMjs from '!!raw-loader!@site/examples/api/reflect.mjs';
import reflectSh from '!!raw-loader!@site/examples/api/reflect.sh';
import reflectGo from '!!raw-loader!@site/examples/api/reflect.go';
:::info How Reflect Works
Learn about disposition-driven reasoning in the [Reflect Architecture](/developer/reflect) guide.
@ -37,6 +38,9 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
<TabItem value="cli" label="CLI">
<CodeSnippet code={reflectSh} section="reflect-basic" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={reflectGo} section="reflect-basic" language="go" />
</TabItem>
</Tabs>
---
@ -58,6 +62,12 @@ Controls how thoroughly the agent explores the memory bank before answering. Acc
<TabItem value="node" label="Node.js">
<CodeSnippet code={reflectMjs} section="reflect-with-params" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={reflectSh} section="reflect-with-params" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={reflectGo} section="reflect-with-params" language="go" />
</TabItem>
</Tabs>
### max_tokens
@ -78,6 +88,9 @@ An optional JSON Schema object. When provided, the LLM generates a response that
<TabItem value="cli" label="CLI">
<CodeSnippet code={reflectSh} section="reflect-structured-output" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={reflectGo} section="reflect-structured-output" language="go" />
</TabItem>
</Tabs>
### tags
@ -88,6 +101,15 @@ Filters which memories the agent can access during reflection. Works identically
<TabItem value="python" label="Python">
<CodeSnippet code={reflectPy} section="reflect-with-tags" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={reflectMjs} section="reflect-with-tags" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={reflectSh} section="reflect-with-tags" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={reflectGo} section="reflect-with-tags" language="go" />
</TabItem>
</Tabs>
### include
@ -102,6 +124,15 @@ When enabled, the response includes a `based_on` object listing the memories, me
<TabItem value="python" label="Python">
<CodeSnippet code={reflectPy} section="reflect-sources" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={reflectMjs} section="reflect-sources" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={reflectSh} section="reflect-sources" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={reflectGo} section="reflect-sources" language="go" />
</TabItem>
</Tabs>
#### include.tool_calls

View file

@ -16,6 +16,7 @@ import CodeSnippet from '@site/src/components/CodeSnippet';
import retainPy from '!!raw-loader!@site/examples/api/retain.py';
import retainMjs from '!!raw-loader!@site/examples/api/retain.mjs';
import retainSh from '!!raw-loader!@site/examples/api/retain.sh';
import retainGo from '!!raw-loader!@site/examples/api/retain.go';
:::info How Retain Works
Learn about fact extraction, entity resolution, and graph construction in the [Retain Architecture](/developer/retain) guide.
@ -39,6 +40,9 @@ A single retain call accepts one or more **items**. Each item is a piece of raw
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-basic" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-basic" language="go" />
</TabItem>
</Tabs>
### Retaining a Conversation
@ -52,6 +56,12 @@ A full conversation should be retained as a single item. The LLM can parse any f
<TabItem value="node" label="Node.js">
<CodeSnippet code={retainMjs} section="retain-conversation" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-conversation" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-conversation" language="go" />
</TabItem>
</Tabs>
When the conversation grows — a new message arrives — just retain again with the full updated content and the same `document_id`. Hindsight will delete the previous version and reprocess from scratch, so memories always reflect the latest state of the conversation.
@ -92,6 +102,9 @@ Providing context consistently is one of the highest-leverage things you can do
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-with-context" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-with-context" language="go" />
</TabItem>
</Tabs>
### metadata
@ -203,6 +216,12 @@ Multiple items can be submitted in a single request. Batch ingestion is the reco
<TabItem value="node" label="Node.js">
<CodeSnippet code={retainMjs} section="retain-batch" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-batch" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-batch" language="go" />
</TabItem>
</Tabs>
@ -215,18 +234,18 @@ Upload files directly — Hindsight converts them to text and extracts memories
**Supported formats:** PDF, DOCX, DOC, PPTX, PPT, XLSX, XLS, images (JPG, PNG, GIF, etc. — OCR), audio (MP3, WAV, FLAC, etc. — transcription), HTML, and plain text formats (TXT, MD, CSV, JSON, YAML, etc.)
<Tabs>
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-files" language="bash" />
</TabItem>
<TabItem value="curl" label="HTTP">
<CodeSnippet code={retainSh} section="retain-files-curl" language="bash" />
</TabItem>
<TabItem value="python" label="Python">
<CodeSnippet code={retainPy} section="retain-files" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={retainMjs} section="retain-files" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-files" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-files" language="go" />
</TabItem>
</Tabs>
The file retain endpoint always returns asynchronously. The response contains `operation_ids` — one per uploaded file — which you can poll via `GET /v1/default/banks/{bank_id}/operations` to track progress.
@ -237,6 +256,15 @@ Upload up to 10 files per request (max 100 MB total). Each file becomes a separa
<TabItem value="python" label="Python">
<CodeSnippet code={retainPy} section="retain-files-batch" language="python" />
</TabItem>
<TabItem value="node" label="Node.js">
<CodeSnippet code={retainMjs} section="retain-files-batch" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-files" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-files" language="go" />
</TabItem>
</Tabs>
:::info File Storage
@ -256,6 +284,12 @@ For large batches, use async ingestion to avoid blocking your application:
<TabItem value="node" label="Node.js">
<CodeSnippet code={retainMjs} section="retain-async" language="javascript" />
</TabItem>
<TabItem value="cli" label="CLI">
<CodeSnippet code={retainSh} section="retain-async" language="bash" />
</TabItem>
<TabItem value="go" label="Go">
<CodeSnippet code={retainGo} section="retain-async" language="go" />
</TabItem>
</Tabs>
When `async: true`, the call returns immediately with an `operation_id`. Processing runs in the background via the worker service. No `usage` metrics are returned for async operations.

View file

@ -6,6 +6,8 @@ sidebar_position: 4
The `@vectorize-io/hindsight-ai-sdk` package integrates [Hindsight](https://hindsight.vectorize.io) memory with the [Vercel AI SDK](https://ai-sdk.dev). It provides five ready-to-use tools for retaining, recalling, and reflecting on long-term memories.
[View Changelog →](/changelog/integrations/ai-sdk)
import CodeSnippet from '@site/src/components/CodeSnippet';
import aiSdkTs from '!!raw-loader!@site/examples/integrations/ai-sdk.ts';

View file

@ -6,6 +6,8 @@ sidebar_position: 5
We built `@vectorize-io/hindsight-chat` to give [Vercel Chat SDK](https://github.com/vercel/chat) bots persistent, per-user memory with a single handler wrapper. The integration works across Slack, Discord, Teams, Google Chat, GitHub, and Linear — no custom plumbing required.
[View Changelog →](/changelog/integrations/chat)
## Installation
```bash

View file

@ -6,6 +6,8 @@ sidebar_position: 5
Persistent memory for AI agent crews via [CrewAI](https://github.com/crewAIInc/crewAI). Give your crews long-term memory with fact extraction, entity tracking, and temporal awareness.
[View Changelog →](/changelog/integrations/crewai)
## Features
- **Drop-in Storage Backend** - Implements CrewAI's `Storage` interface for `ExternalMemory`

View file

@ -0,0 +1,317 @@
---
sidebar_position: 7
---
# LangGraph / LangChain
Persistent long-term memory for [LangGraph](https://langchain-ai.github.io/langgraph/) and [LangChain](https://python.langchain.com/) agents via Hindsight. Three integration patterns at different abstraction levels — the tools pattern works with both LangChain and LangGraph, while nodes and the BaseStore adapter are LangGraph-specific.
[View Changelog →](/changelog/integrations/langgraph)
## Features
- **Memory Tools** — retain, recall, and reflect as LangChain `@tool` functions compatible with `bind_tools()` and `ToolNode`. Works with **both LangChain and LangGraph** — no LangGraph dependency required for this pattern.
- **Graph Nodes** *(LangGraph)* — Pre-built nodes that auto-inject memories before LLM calls and auto-store after responses
- **BaseStore Adapter** *(LangGraph)* — Drop-in `BaseStore` implementation backed by Hindsight, for LangGraph's native memory patterns
- **Dynamic Banks** — Resolve bank IDs per-request from `RunnableConfig` for per-user memory
- **Async-Native** — Uses `aretain`, `arecall`, `areflect` directly — no thread-pool workarounds
## Installation
```bash
pip install hindsight-langgraph
```
## Quick Start: Tools (LangChain & LangGraph)
The tools pattern creates standard LangChain `@tool` functions that work with any LangChain-compatible model via `bind_tools()`. You can use them with a LangGraph agent or with plain LangChain — no LangGraph required.
**With LangGraph (recommended):**
```python
from hindsight_client import Hindsight
from hindsight_langgraph import create_hindsight_tools
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
client = Hindsight(base_url="http://localhost:8888")
tools = create_hindsight_tools(client=client, bank_id="user-123")
agent = create_react_agent(ChatOpenAI(model="gpt-4o"), tools=tools)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "Remember that I prefer dark mode"}]}
)
```
**With plain LangChain:**
```python
from hindsight_client import Hindsight
from hindsight_langgraph import create_hindsight_tools
from langchain_openai import ChatOpenAI
client = Hindsight(base_url="http://localhost:8888")
tools = create_hindsight_tools(client=client, bank_id="user-123")
model = ChatOpenAI(model="gpt-4o").bind_tools(tools)
response = await model.ainvoke("Remember that I prefer dark mode")
```
When using plain LangChain, you handle the tool execution loop yourself — call the model, check for `tool_calls`, execute them, and feed results back. LangGraph automates this loop for you.
The agent gets three tools it can call:
- **`hindsight_retain`** — Store information to long-term memory
- **`hindsight_recall`** — Search long-term memory for relevant facts
- **`hindsight_reflect`** — Synthesize a reasoned answer from memories
## Quick Start: Memory Nodes (LangGraph)
Add recall and retain nodes to your graph for automatic memory injection and storage.
```python
from hindsight_client import Hindsight
from hindsight_langgraph import create_recall_node, create_retain_node
from langgraph.graph import StateGraph, MessagesState, START, END
client = Hindsight(base_url="http://localhost:8888")
recall = create_recall_node(client=client, bank_id="user-123")
retain = create_retain_node(client=client, bank_id="user-123")
builder = StateGraph(MessagesState)
builder.add_node("recall", recall)
builder.add_node("agent", agent_node) # your LLM node
builder.add_node("retain", retain)
builder.add_edge(START, "recall")
builder.add_edge("recall", "agent")
builder.add_edge("agent", "retain")
builder.add_edge("retain", END)
graph = builder.compile()
```
The recall node extracts the latest user message, searches Hindsight, and injects matching memories as a `SystemMessage`. The retain node stores human messages (optionally AI messages too) after the response.
## Quick Start: BaseStore (LangGraph)
Use Hindsight as a LangGraph `BaseStore` for cross-thread persistent memory with semantic search.
```python
from hindsight_client import Hindsight
from hindsight_langgraph import HindsightStore
client = Hindsight(base_url="http://localhost:8888")
store = HindsightStore(client=client)
graph = builder.compile(checkpointer=checkpointer, store=store)
# Store and search via the store API
await store.aput(("user", "123", "prefs"), "theme", {"value": "dark mode"})
results = await store.asearch(("user", "123", "prefs"), query="theme preference")
```
Namespace tuples are mapped to Hindsight bank IDs with `.` as separator (e.g., `("user", "123")` becomes bank `user.123`). Banks are auto-created on first access.
## Dynamic Bank IDs
Both nodes and the store support per-user bank resolution from `RunnableConfig`:
```python
recall = create_recall_node(client=client, bank_id_from_config="user_id")
retain = create_retain_node(client=client, bank_id_from_config="user_id")
# Bank ID resolved at runtime from config
result = await graph.ainvoke(
{"messages": [{"role": "user", "content": "hello"}]},
config={"configurable": {"user_id": "user-456"}},
)
```
## Selecting Tools
Include only the tools you need:
```python
tools = create_hindsight_tools(
client=client,
bank_id="user-123",
include_retain=True,
include_recall=True,
include_reflect=False, # Omit reflect
)
```
## Global Configuration
Instead of passing a client to every call, configure once:
```python
from hindsight_langgraph import configure, create_hindsight_tools
configure(
hindsight_api_url="http://localhost:8888",
api_key="your-api-key", # Or set HINDSIGHT_API_KEY env var
budget="mid", # Recall budget: low/mid/high
max_tokens=4096, # Max tokens for recall results
tags=["env:prod"], # Tags for stored memories
recall_tags=["scope:global"], # Tags to filter recall
recall_tags_match="any", # Tag match mode: any/all/any_strict/all_strict
)
# Now create tools without passing client — uses global config
tools = create_hindsight_tools(bank_id="user-123")
```
## Retain Node Options
```python
retain = create_retain_node(
client=client,
bank_id="user-123",
retain_human=True, # Store human messages (default: True)
retain_ai=False, # Store AI responses (default: False)
tags=["source:chat"], # Tags applied to stored memories
)
```
## Recall Node Options
```python
recall = create_recall_node(
client=client,
bank_id="user-123",
budget="low", # Recall budget: low/mid/high
max_results=10, # Max memories injected
max_tokens=4096, # Max tokens for recall
tags=["scope:user"], # Filter by tags
tags_match="all", # Tag match mode
)
```
### Using `output_key` for Prompt Control
By default, the recall node appends a `SystemMessage` to `messages`. Use `output_key` to write memory text to a custom state field instead, giving you full control over prompt ordering:
```python
from typing import Optional
from langgraph.graph import MessagesState
class AgentState(MessagesState):
memory_context: Optional[str] = None
recall = create_recall_node(
client=client,
bank_id="user-123",
output_key="memory_context",
)
# In your agent node, read state["memory_context"] and prepend it
# to the system prompt before calling the model.
```
## Limitations and Notes
### HindsightStore
- **Async-only.** All sync methods (`batch`, `get`, `put`, `delete`, `search`, `list_namespaces`) raise `NotImplementedError`. Use the async variants (`abatch`, `aget`, `aput`, `adelete`, `asearch`, `alist_namespaces`) instead.
- **`get()` relies on recall.** There is no direct key lookup — the key is used as a recall query and only exact `document_id` matches are returned. Items that do not rank in the top recall results may appear missing.
- **`list_namespaces` is session-scoped.** It only tracks namespaces that have been written to via `aput()` during the current process. After a restart, `list_namespaces` returns empty even though data still exists in Hindsight.
- **`delete` is a no-op.** Calling `adelete()` logs a debug message but does not remove data from Hindsight. Hindsight's memory model is append-oriented; fact superseding is handled automatically during retain.
### Memory Nodes
- **SystemMessage ordering.** The recall node adds a `SystemMessage` with recalled memories. Because `MessagesState` uses `add_messages` (which appends), this message appears after existing messages rather than at position 0. The message has a stable ID (`hindsight_memory_context`) so it is updated rather than duplicated across invocations. If your LLM provider requires system messages first, sort or filter messages in your agent node before passing them to the model.
### Error Handling
- **Tools** raise `HindsightError` on failure, which surfaces to the agent as a tool error.
- **Nodes** silently log errors and return empty messages, so a Hindsight outage does not crash your graph.
## API Reference
### `create_hindsight_tools()`
| Parameter | Default | Description |
|---|---|---|
| `bank_id` | *required* | Hindsight memory bank ID |
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `budget` | `"mid"` | Recall/reflect budget level (low/mid/high) |
| `max_tokens` | `4096` | Maximum tokens for recall results |
| `tags` | `None` | Tags applied when storing memories |
| `recall_tags` | `None` | Tags to filter when searching |
| `recall_tags_match` | `"any"` | Tag matching mode (any/all/any\_strict/all\_strict) |
| `retain_metadata` | `None` | Default metadata dict for retain operations |
| `retain_document_id` | `None` | Default document\_id for retain (groups/upserts memories) |
| `recall_types` | `None` | Fact types to filter (world, experience, opinion, observation) |
| `recall_include_entities` | `False` | Include entity information in recall results |
| `reflect_context` | `None` | Additional context for reflect operations |
| `reflect_max_tokens` | `None` | Max tokens for reflect results (defaults to `max_tokens`) |
| `reflect_response_schema` | `None` | JSON schema to constrain reflect output format |
| `reflect_tags` | `None` | Tags to filter memories used in reflect (defaults to `recall_tags`) |
| `reflect_tags_match` | `None` | Tag matching for reflect (defaults to `recall_tags_match`) |
| `include_retain` | `True` | Include the retain (store) tool |
| `include_recall` | `True` | Include the recall (search) tool |
| `include_reflect` | `True` | Include the reflect (synthesize) tool |
### `create_recall_node()`
| Parameter | Default | Description |
|---|---|---|
| `bank_id` | `None` | Static bank ID (or use `bank_id_from_config`) |
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `budget` | `"mid"` | Recall budget level |
| `max_tokens` | `4096` | Max tokens for recall results |
| `max_results` | `10` | Max memories to inject |
| `tags` | `None` | Tags to filter recall results |
| `tags_match` | `"any"` | Tag matching mode |
| `bank_id_from_config` | `"user_id"` | Config key to resolve bank ID at runtime |
| `output_key` | `None` | If set, write memory text to this state key instead of appending a SystemMessage to `messages` |
### `create_retain_node()`
| Parameter | Default | Description |
|---|---|---|
| `bank_id` | `None` | Static bank ID (or use `bank_id_from_config`) |
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `tags` | `None` | Tags applied to stored memories |
| `bank_id_from_config` | `"user_id"` | Config key to resolve bank ID at runtime |
| `retain_human` | `True` | Store human messages |
| `retain_ai` | `False` | Store AI responses |
### `HindsightStore()`
| Parameter | Default | Description |
|---|---|---|
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `tags` | `None` | Tags applied to all retain operations |
### `configure()`
| Parameter | Default | Description |
|---|---|---|
| `hindsight_api_url` | Production API | Hindsight API URL |
| `api_key` | `HINDSIGHT_API_KEY` env | API key for authentication |
| `budget` | `"mid"` | Default recall budget level |
| `max_tokens` | `4096` | Default max tokens for recall |
| `tags` | `None` | Default tags for retain operations |
| `recall_tags` | `None` | Default tags to filter recall |
| `recall_tags_match` | `"any"` | Default tag matching mode |
| `verbose` | `False` | Enable verbose logging |
## Requirements
- Python >= 3.10
- langchain-core >= 0.3.0
- hindsight-client >= 0.4.0
- langgraph >= 0.3.0 *(only for nodes and store patterns — install with `pip install hindsight-langgraph[langgraph]`)*

View file

@ -6,6 +6,8 @@ sidebar_position: 1
Universal LLM memory integration via [LiteLLM](https://github.com/BerriAI/litellm). Add persistent memory to any LLM application with just a few lines of code.
[View Changelog →](/changelog/integrations/litellm)
## Features
- **Universal LLM Support** - Works with 100+ LLM providers via LiteLLM (OpenAI, Anthropic, Groq, Azure, AWS Bedrock, Google Vertex AI, and more)

View file

@ -0,0 +1,248 @@
---
sidebar_position: 5
---
# NemoClaw
Persistent memory for [NemoClaw](https://nemoclaw.ai) sandboxed agents using [Hindsight](https://hindsight.vectorize.io).
NemoClaw runs [OpenClaw](https://openclaw.ai) inside an OpenShell sandbox with controlled filesystem, process, and network egress policies. The `hindsight-nemoclaw` package automates adding Hindsight memory to a sandbox in one command — no code changes required.
[View Changelog →](/changelog/integrations/nemoclaw)
## Quick Start
```bash
npx @vectorize-io/hindsight-nemoclaw setup \
--sandbox my-assistant \
--api-url https://api.hindsight.vectorize.io \
--api-token <your-api-key> \
--bank-prefix my-sandbox
```
Get an API key at [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup).
You'll see output like:
```
[0] Preflight checks...
✓ openshell found
✓ openclaw found
[1] Installing @vectorize-io/hindsight-openclaw plugin...
✓ Plugin installed
[2] Configuring plugin in ~/.openclaw/openclaw.json...
✓ Plugin config written (bank: my-sandbox-openclaw)
[3] Applying Hindsight network policy to sandbox "my-assistant"...
✓ Policy version 2 submitted
✓ Policy version 2 loaded (active version: 2)
[4] Restarting OpenClaw gateway...
✓ Gateway restarted
✓ Setup complete!
```
## How It Works
### The sandbox problem
OpenShell enforces strict network egress — every outbound endpoint must be explicitly permitted in the sandbox policy. By default, the Hindsight API (`api.hindsight.vectorize.io`) is not in that list.
The `hindsight-openclaw` plugin supports **external API mode**, where it skips the local daemon entirely and makes direct HTTPS calls to Hindsight Cloud. This is the natural fit for sandboxed environments: the plugin becomes a thin HTTP client, and the only sandbox change needed is one egress rule.
### What the setup command does
1. **Preflight** — verifies `openshell` and `openclaw` are installed
2. **Install plugin** — runs `openclaw plugins install @vectorize-io/hindsight-openclaw`
3. **Configure plugin** — writes external API mode config to `~/.openclaw/openclaw.json`
4. **Apply policy** — reads the current sandbox policy, merges the Hindsight egress block, and re-applies via `openshell policy set`
5. **Restart gateway** — runs `openclaw gateway restart`
### Memory flow
Once set up, the `hindsight-openclaw` plugin hooks into the OpenClaw gateway lifecycle:
- **`before_agent_start`** — recalls relevant memories from past sessions and injects them into context
- **`agent_end`** — retains the conversation to the Hindsight memory bank
The sandbox doesn't interfere with either step — it sees the Hindsight calls as normal HTTPS egress to a permitted endpoint.
## CLI Reference
```
hindsight-nemoclaw setup [options]
Options:
--sandbox <name> NemoClaw sandbox name (required)
--api-url <url> Hindsight API URL (required)
--api-token <token> Hindsight API token (required)
--bank-prefix <prefix> Memory bank prefix (default: "nemoclaw")
--skip-policy Skip sandbox network policy update
--skip-plugin-install Skip openclaw plugin installation
--dry-run Preview changes without applying
--help Show help
```
Use `--dry-run` to preview all changes before applying anything. Use `--skip-policy` if you manage sandbox policies manually.
## Manual Setup
If you prefer to apply the steps yourself instead of using the CLI:
### 1. Install the plugin
```bash
openclaw plugins install @vectorize-io/hindsight-openclaw
```
### 2. Configure `~/.openclaw/openclaw.json`
```json
{
"plugins": {
"entries": {
"hindsight-openclaw": {
"enabled": true,
"config": {
"hindsightApiUrl": "https://api.hindsight.vectorize.io",
"hindsightApiToken": "<your-api-key>",
"llmProvider": "claude-code",
"dynamicBankId": false,
"bankIdPrefix": "my-sandbox"
}
}
}
}
}
```
`llmProvider: "claude-code"` uses the Claude Code process already present in the sandbox — no additional API key needed.
### 3. Add the Hindsight network policy
`openshell policy set` replaces the entire policy document. Export your current policy first, add the Hindsight block, then re-apply:
```yaml
network_policies:
hindsight:
name: hindsight
endpoints:
- host: api.hindsight.vectorize.io
port: 443
protocol: rest
tls: terminate
enforcement: enforce
rules:
- allow:
method: GET
path: /**
- allow:
method: POST
path: /**
- allow:
method: PUT
path: /**
binaries:
- path: /usr/local/bin/openclaw
```
```bash
openshell policy set my-sandbox --policy /path/to/full-policy.yaml --wait
openclaw gateway restart
```
## Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
| `hindsightApiUrl` | string | — | Hindsight API base URL |
| `hindsightApiToken` | string | — | API token for authentication |
| `llmProvider` | string | auto-detect | LLM provider for memory extraction |
| `dynamicBankId` | boolean | `false` | Isolate memory per user (`true`) or share across sessions (`false`) |
| `bankIdPrefix` | string | `"nemoclaw"` | Prefix for the memory bank name |
### Bank naming
When `dynamicBankId: false`, all sessions write to a single bank named `{bankIdPrefix}-openclaw`. When `dynamicBankId: true`, each user gets an isolated bank — useful for multi-tenant deployments.
## Verifying It Works
After setup, check the gateway logs:
```bash
tail -f /tmp/openclaw/openclaw-*.log | grep Hindsight
```
On startup you should see:
```
[Hindsight] Plugin loaded successfully
[Hindsight] ✓ Using external API: https://api.hindsight.vectorize.io
[Hindsight] External API health: {"status":"healthy","database":"connected"}
[Hindsight] Default bank: my-sandbox-openclaw
[Hindsight] ✓ Ready (external API mode)
```
After a conversation:
```
[Hindsight] before_agent_start - bank: my-sandbox-openclaw, channel: undefined/webchat
[Hindsight Hook] agent_end triggered - bank: my-sandbox-openclaw
[Hindsight] Retained 6 messages to bank my-sandbox-openclaw for session agent:main:...
```
## Pitfalls
### Policy replacement is full-document
`openshell policy set` replaces the entire policy document. The `hindsight-nemoclaw setup` command handles this automatically. If you're applying manually, export the current policy first so existing rules aren't lost.
### LaunchAgent can't follow symlinks on macOS
On macOS, the OpenClaw gateway runs as a LaunchAgent under a restricted security context. `openclaw plugins install --link` creates a symlink the LaunchAgent can't follow — the setup command installs as a copy instead. If you see `EPERM: operation not permitted, scandir` in gateway logs, this is the cause.
### Memory retention is asynchronous
Fact extraction and entity resolution happen in the background after `retain`. If you open a new session immediately after closing one, the most recent memories may not be indexed yet — typically a few seconds.
### Binary-scoped egress
The `binaries` field in the network policy restricts the egress rule to a specific executable path. If OpenClaw updates and the binary path changes, the rule silently stops working. Check your binary path after upgrades.
## Troubleshooting
### Plugin not loading
```bash
openclaw plugins list | grep hindsight
# Should show: ✓ enabled │ Hindsight Memory │ ...
# Reinstall
openclaw plugins install @vectorize-io/hindsight-openclaw
```
### Egress blocked
If calls to `api.hindsight.vectorize.io` are being blocked, check the active sandbox policy:
```bash
openshell sandbox get my-assistant
```
Verify the `hindsight` block is present and the `binaries` path matches your OpenClaw binary:
```bash
which openclaw
```
### External API not connecting
```bash
tail -f /tmp/openclaw/openclaw-*.log | grep Hindsight
# If you see daemon startup messages instead of "Using external API",
# the plugin config isn't being read — check ~/.openclaw/openclaw.json
```

View file

@ -8,6 +8,8 @@ Local, long term memory for [OpenClaw](https://openclaw.ai) agents using [Hindsi
This plugin integrates [hindsight-embed](https://vectorize.io/hindsight/cli), a standalone daemon that bundles Hindsight's memory engine (API + PostgreSQL) into a single command. Everything runs locally on your machine, reuses the LLM you're already paying for, and costs nothing extra.
[View Changelog →](/changelog/integrations/openclaw)
## Quick Start
**Step 1: Set up LLM for memory extraction**

View file

@ -6,6 +6,8 @@ sidebar_position: 6
Persistent memory tools for [Pydantic AI](https://ai.pydantic.dev/) agents via Hindsight. Give your agents long-term memory with retain, recall, and reflect — all async-native with no thread-pool hacks.
[View Changelog →](/changelog/integrations/pydantic-ai)
## Features
- **Async-Native Tools** — Uses Pydantic AI's async tool interface directly (`aretain`, `arecall`, `areflect`)

View file

@ -291,6 +291,22 @@
"icon": "/img/icons/hermes.png"
}
},
{
"type": "doc",
"id": "sdks/integrations/langgraph",
"label": "LangGraph / LangChain",
"customProps": {
"icon": "/img/icons/langgraph.png"
}
},
{
"type": "doc",
"id": "sdks/integrations/nemoclaw",
"label": "NemoClaw",
"customProps": {
"icon": "/img/icons/nemoclaw.png"
}
},
{
"type": "doc",
"id": "sdks/integrations/skills",

View file

@ -1,7 +1,6 @@
# Best Practices
Practical guidance for agents and developers integrating Hindsight memory into production systems.
<PageHero title="Best Practices" subtitle="Practical guidance for agents and developers integrating Hindsight memory into production systems." />
**Contents**
- [Core Concepts](#core-concepts) — Memory banks, taxonomy, memory types

View file

@ -2,22 +2,9 @@
hide_table_of_contents: true
---
# Changelog
import PageHero from '@site/src/components/PageHero';
This changelog highlights user-facing changes only. Internal maintenance, CI/CD, and infrastructure updates are omitted.
For full release details, see [GitHub Releases](https://github.com/vectorize-io/hindsight/releases).
## Integration Changelogs
| Integration | Package | Description |
|---|---|---|
| [LiteLLM](integrations/litellm.md) | `hindsight-litellm` | Universal LLM memory via LiteLLM (100+ providers) |
| [Pydantic AI](integrations/pydantic-ai.md) | `hindsight-pydantic-ai` | Persistent memory tools for Pydantic AI agents |
| [CrewAI](integrations/crewai.md) | `hindsight-crewai` | Persistent memory for CrewAI agents |
| [AI SDK](integrations/ai-sdk.md) | `@vectorize-io/hindsight-ai-sdk` | Memory integration for Vercel AI SDK |
| [Chat SDK](integrations/chat.md) | `@vectorize-io/hindsight-chat` | Memory integration for Vercel Chat SDK |
| [OpenClaw](integrations/openclaw.md) | `@vectorize-io/hindsight-openclaw` | Hindsight memory plugin for OpenClaw |
<PageHero title="Changelog" subtitle="User-facing changes only. Internal maintenance and infrastructure updates are omitted." />
## [0.4.19](https://github.com/vectorize-io/hindsight/releases/tag/v0.4.19)
@ -606,3 +593,14 @@ For full release details, see [GitHub Releases](https://github.com/vectorize-io/
**Bug Fixes**
- Fixed the standalone Docker image so it builds/runs correctly. ([`1056a20`](https://github.com/vectorize-io/hindsight/commit/1056a20))
## Integration Changelogs
| Integration | Package | Description |
|---|---|---|
| [LiteLLM](integrations/litellm.md) | `hindsight-litellm` | Universal LLM memory via LiteLLM (100+ providers) |
| [Pydantic AI](integrations/pydantic-ai.md) | `hindsight-pydantic-ai` | Persistent memory tools for Pydantic AI agents |
| [CrewAI](integrations/crewai.md) | `hindsight-crewai` | Persistent memory for CrewAI agents |
| [AI SDK](integrations/ai-sdk.md) | `@vectorize-io/hindsight-ai-sdk` | Memory integration for Vercel AI SDK |
| [Chat SDK](integrations/chat.md) | `@vectorize-io/hindsight-chat` | Memory integration for Vercel Chat SDK |
| [OpenClaw](integrations/openclaw.md) | `@vectorize-io/hindsight-openclaw` | Hindsight memory plugin for OpenClaw |

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# AI SDK Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-ai-sdk`](https://www.npmjs.com/package/@vectorize-io/hindsight-ai-sdk) — memory integration for Vercel AI SDK.
<PageHero title="Vercel AI SDK Changelog" subtitle="@vectorize-io/hindsight-ai-sdk — memory integration for Vercel AI SDK." />
For the source code, see [`hindsight-integrations/ai-sdk`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/ai-sdk).
← [Back to main changelog](../index.md)
[← Vercel AI SDK integration](../../sdks/integrations/ai-sdk.md)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# Chat SDK Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-chat`](https://www.npmjs.com/package/@vectorize-io/hindsight-chat) — memory integration for Vercel Chat SDK.
<PageHero title="Vercel Chat SDK Changelog" subtitle="@vectorize-io/hindsight-chat — memory integration for Vercel Chat SDK." />
For the source code, see [`hindsight-integrations/chat`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/chat).
← [Back to main changelog](../index.md)
[← Vercel Chat SDK integration](../../sdks/integrations/chat.md)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# CrewAI Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-crewai`](https://pypi.org/project/hindsight-crewai/) — persistent memory for CrewAI agents.
<PageHero title="CrewAI Changelog" subtitle="hindsight-crewai — persistent memory for CrewAI agents." />
For the source code, see [`hindsight-integrations/crewai`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/crewai).
← [Back to main changelog](../index.md)
[← CrewAI integration](../../sdks/integrations/crewai.md)

View file

@ -0,0 +1,15 @@
---
hide_table_of_contents: true
---
import PageHero from '@site/src/components/PageHero';
<PageHero title="LangGraph Changelog" subtitle="hindsight-langgraph — LangGraph and LangChain memory integration." />
[← LangGraph integration](../../sdks/integrations/langgraph.md)
## [0.1.1](https://github.com/vectorize-io/hindsight/tree/integrations/langgraph/v0.1.1)
**Features**
- Added LangGraph integration for Hindsight. ([`b4320254`](https://github.com/vectorize-io/hindsight/commit/b4320254))

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# LiteLLM Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-litellm`](https://pypi.org/project/hindsight-litellm/) — universal LLM memory integration via LiteLLM.
<PageHero title="LiteLLM Changelog" subtitle="hindsight-litellm — universal LLM memory integration via LiteLLM." />
For the source code, see [`hindsight-integrations/litellm`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/litellm).
← [Back to main changelog](../index.md)
[← LiteLLM integration](../../sdks/integrations/litellm.md)

View file

@ -0,0 +1,15 @@
---
hide_table_of_contents: true
---
import PageHero from '@site/src/components/PageHero';
<PageHero title="NemoClaw Changelog" subtitle="@vectorize-io/hindsight-nemoclaw — persistent memory for NemoClaw sandboxed agents." />
[← NemoClaw integration](../../sdks/integrations/nemoclaw.md)
## [0.1.1](https://github.com/vectorize-io/hindsight/tree/integrations/nemoclaw/v0.1.1)
**Features**
- Added a setup CLI package for the Hindsight nemoclaw integration. ([`d284de28`](https://github.com/vectorize-io/hindsight/commit/d284de28))

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# OpenClaw Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`@vectorize-io/hindsight-openclaw`](https://www.npmjs.com/package/@vectorize-io/hindsight-openclaw) — Hindsight memory plugin for OpenClaw.
<PageHero title="OpenClaw Changelog" subtitle="@vectorize-io/hindsight-openclaw — Hindsight memory plugin for OpenClaw." />
For the source code, see [`hindsight-integrations/openclaw`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/openclaw).
← [Back to main changelog](../index.md)
[← OpenClaw integration](../../sdks/integrations/openclaw.md)

View file

@ -2,10 +2,8 @@
hide_table_of_contents: true
---
# Pydantic AI Integration Changelog
import PageHero from '@site/src/components/PageHero';
Changelog for [`hindsight-pydantic-ai`](https://pypi.org/project/hindsight-pydantic-ai/) — persistent memory tools for Pydantic AI agents.
<PageHero title="Pydantic AI Changelog" subtitle="hindsight-pydantic-ai — persistent memory tools for Pydantic AI agents." />
For the source code, see [`hindsight-integrations/pydantic-ai`](https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/pydantic-ai).
← [Back to main changelog](../index.md)
[← Pydantic AI integration](../../sdks/integrations/pydantic-ai.md)

View file

@ -129,7 +129,7 @@ go get github.com/vectorize-io/hindsight/hindsight-clients/go
## Integrations
<IntegrationsGrid />
Browse all supported integrations in the Integrations Hub.
## Next Steps

View file

@ -117,7 +117,7 @@ These settings only affect the `reflect` operation, not `recall`.
## Integrations
<IntegrationsGrid />
Browse all supported integrations in the Integrations Hub.
## Next Steps

View file

@ -1,6 +1,6 @@
# Frequently Asked Questions
<PageHero title="FAQ" subtitle="Common questions and answers about Hindsight." />
**Contents**
- [What is Hindsight and how does it differ from RAG?](#what-is-hindsight-and-how-does-it-differ-from-rag)
@ -57,7 +57,7 @@ Unlike vector databases (just search) or RAG systems (document retrieval), Hinds
### Which integrations are supported?
<IntegrationsGrid />
Browse all supported integrations in the Integrations Hub.
---

View file

@ -3,6 +3,8 @@
The `@vectorize-io/hindsight-ai-sdk` package integrates [Hindsight](https://hindsight.vectorize.io) memory with the [Vercel AI SDK](https://ai-sdk.dev). It provides five ready-to-use tools for retaining, recalling, and reflecting on long-term memories.
[View Changelog →](../../changelog/integrations/ai-sdk.md)
## Installation
```bash

View file

@ -6,6 +6,8 @@ sidebar_position: 5
We built `@vectorize-io/hindsight-chat` to give [Vercel Chat SDK](https://github.com/vercel/chat) bots persistent, per-user memory with a single handler wrapper. The integration works across Slack, Discord, Teams, Google Chat, GitHub, and Linear — no custom plumbing required.
[View Changelog →](../../changelog/integrations/chat.md)
## Installation
```bash

View file

@ -6,6 +6,8 @@ sidebar_position: 5
Persistent memory for AI agent crews via [CrewAI](https://github.com/crewAIInc/crewAI). Give your crews long-term memory with fact extraction, entity tracking, and temporal awareness.
[View Changelog →](../../changelog/integrations/crewai.md)
## Features
- **Drop-in Storage Backend** - Implements CrewAI's `Storage` interface for `ExternalMemory`

View file

@ -0,0 +1,317 @@
---
sidebar_position: 7
---
# LangGraph / LangChain
Persistent long-term memory for [LangGraph](https://langchain-ai.github.io/langgraph/) and [LangChain](https://python.langchain.com/) agents via Hindsight. Three integration patterns at different abstraction levels — the tools pattern works with both LangChain and LangGraph, while nodes and the BaseStore adapter are LangGraph-specific.
[View Changelog →](../../changelog/integrations/langgraph.md)
## Features
- **Memory Tools** — retain, recall, and reflect as LangChain `@tool` functions compatible with `bind_tools()` and `ToolNode`. Works with **both LangChain and LangGraph** — no LangGraph dependency required for this pattern.
- **Graph Nodes** *(LangGraph)* — Pre-built nodes that auto-inject memories before LLM calls and auto-store after responses
- **BaseStore Adapter** *(LangGraph)* — Drop-in `BaseStore` implementation backed by Hindsight, for LangGraph's native memory patterns
- **Dynamic Banks** — Resolve bank IDs per-request from `RunnableConfig` for per-user memory
- **Async-Native** — Uses `aretain`, `arecall`, `areflect` directly — no thread-pool workarounds
## Installation
```bash
pip install hindsight-langgraph
```
## Quick Start: Tools (LangChain & LangGraph)
The tools pattern creates standard LangChain `@tool` functions that work with any LangChain-compatible model via `bind_tools()`. You can use them with a LangGraph agent or with plain LangChain — no LangGraph required.
**With LangGraph (recommended):**
```python
from hindsight_client import Hindsight
from hindsight_langgraph import create_hindsight_tools
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
client = Hindsight(base_url="http://localhost:8888")
tools = create_hindsight_tools(client=client, bank_id="user-123")
agent = create_react_agent(ChatOpenAI(model="gpt-4o"), tools=tools)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "Remember that I prefer dark mode"}]}
)
```
**With plain LangChain:**
```python
from hindsight_client import Hindsight
from hindsight_langgraph import create_hindsight_tools
from langchain_openai import ChatOpenAI
client = Hindsight(base_url="http://localhost:8888")
tools = create_hindsight_tools(client=client, bank_id="user-123")
model = ChatOpenAI(model="gpt-4o").bind_tools(tools)
response = await model.ainvoke("Remember that I prefer dark mode")
```
When using plain LangChain, you handle the tool execution loop yourself — call the model, check for `tool_calls`, execute them, and feed results back. LangGraph automates this loop for you.
The agent gets three tools it can call:
- **`hindsight_retain`** — Store information to long-term memory
- **`hindsight_recall`** — Search long-term memory for relevant facts
- **`hindsight_reflect`** — Synthesize a reasoned answer from memories
## Quick Start: Memory Nodes (LangGraph)
Add recall and retain nodes to your graph for automatic memory injection and storage.
```python
from hindsight_client import Hindsight
from hindsight_langgraph import create_recall_node, create_retain_node
from langgraph.graph import StateGraph, MessagesState, START, END
client = Hindsight(base_url="http://localhost:8888")
recall = create_recall_node(client=client, bank_id="user-123")
retain = create_retain_node(client=client, bank_id="user-123")
builder = StateGraph(MessagesState)
builder.add_node("recall", recall)
builder.add_node("agent", agent_node) # your LLM node
builder.add_node("retain", retain)
builder.add_edge(START, "recall")
builder.add_edge("recall", "agent")
builder.add_edge("agent", "retain")
builder.add_edge("retain", END)
graph = builder.compile()
```
The recall node extracts the latest user message, searches Hindsight, and injects matching memories as a `SystemMessage`. The retain node stores human messages (optionally AI messages too) after the response.
## Quick Start: BaseStore (LangGraph)
Use Hindsight as a LangGraph `BaseStore` for cross-thread persistent memory with semantic search.
```python
from hindsight_client import Hindsight
from hindsight_langgraph import HindsightStore
client = Hindsight(base_url="http://localhost:8888")
store = HindsightStore(client=client)
graph = builder.compile(checkpointer=checkpointer, store=store)
# Store and search via the store API
await store.aput(("user", "123", "prefs"), "theme", {"value": "dark mode"})
results = await store.asearch(("user", "123", "prefs"), query="theme preference")
```
Namespace tuples are mapped to Hindsight bank IDs with `.` as separator (e.g., `("user", "123")` becomes bank `user.123`). Banks are auto-created on first access.
## Dynamic Bank IDs
Both nodes and the store support per-user bank resolution from `RunnableConfig`:
```python
recall = create_recall_node(client=client, bank_id_from_config="user_id")
retain = create_retain_node(client=client, bank_id_from_config="user_id")
# Bank ID resolved at runtime from config
result = await graph.ainvoke(
{"messages": [{"role": "user", "content": "hello"}]},
config={"configurable": {"user_id": "user-456"}},
)
```
## Selecting Tools
Include only the tools you need:
```python
tools = create_hindsight_tools(
client=client,
bank_id="user-123",
include_retain=True,
include_recall=True,
include_reflect=False, # Omit reflect
)
```
## Global Configuration
Instead of passing a client to every call, configure once:
```python
from hindsight_langgraph import configure, create_hindsight_tools
configure(
hindsight_api_url="http://localhost:8888",
api_key="your-api-key", # Or set HINDSIGHT_API_KEY env var
budget="mid", # Recall budget: low/mid/high
max_tokens=4096, # Max tokens for recall results
tags=["env:prod"], # Tags for stored memories
recall_tags=["scope:global"], # Tags to filter recall
recall_tags_match="any", # Tag match mode: any/all/any_strict/all_strict
)
# Now create tools without passing client — uses global config
tools = create_hindsight_tools(bank_id="user-123")
```
## Retain Node Options
```python
retain = create_retain_node(
client=client,
bank_id="user-123",
retain_human=True, # Store human messages (default: True)
retain_ai=False, # Store AI responses (default: False)
tags=["source:chat"], # Tags applied to stored memories
)
```
## Recall Node Options
```python
recall = create_recall_node(
client=client,
bank_id="user-123",
budget="low", # Recall budget: low/mid/high
max_results=10, # Max memories injected
max_tokens=4096, # Max tokens for recall
tags=["scope:user"], # Filter by tags
tags_match="all", # Tag match mode
)
```
### Using `output_key` for Prompt Control
By default, the recall node appends a `SystemMessage` to `messages`. Use `output_key` to write memory text to a custom state field instead, giving you full control over prompt ordering:
```python
from typing import Optional
from langgraph.graph import MessagesState
class AgentState(MessagesState):
memory_context: Optional[str] = None
recall = create_recall_node(
client=client,
bank_id="user-123",
output_key="memory_context",
)
# In your agent node, read state["memory_context"] and prepend it
# to the system prompt before calling the model.
```
## Limitations and Notes
### HindsightStore
- **Async-only.** All sync methods (`batch`, `get`, `put`, `delete`, `search`, `list_namespaces`) raise `NotImplementedError`. Use the async variants (`abatch`, `aget`, `aput`, `adelete`, `asearch`, `alist_namespaces`) instead.
- **`get()` relies on recall.** There is no direct key lookup — the key is used as a recall query and only exact `document_id` matches are returned. Items that do not rank in the top recall results may appear missing.
- **`list_namespaces` is session-scoped.** It only tracks namespaces that have been written to via `aput()` during the current process. After a restart, `list_namespaces` returns empty even though data still exists in Hindsight.
- **`delete` is a no-op.** Calling `adelete()` logs a debug message but does not remove data from Hindsight. Hindsight's memory model is append-oriented; fact superseding is handled automatically during retain.
### Memory Nodes
- **SystemMessage ordering.** The recall node adds a `SystemMessage` with recalled memories. Because `MessagesState` uses `add_messages` (which appends), this message appears after existing messages rather than at position 0. The message has a stable ID (`hindsight_memory_context`) so it is updated rather than duplicated across invocations. If your LLM provider requires system messages first, sort or filter messages in your agent node before passing them to the model.
### Error Handling
- **Tools** raise `HindsightError` on failure, which surfaces to the agent as a tool error.
- **Nodes** silently log errors and return empty messages, so a Hindsight outage does not crash your graph.
## API Reference
### `create_hindsight_tools()`
| Parameter | Default | Description |
|---|---|---|
| `bank_id` | *required* | Hindsight memory bank ID |
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `budget` | `"mid"` | Recall/reflect budget level (low/mid/high) |
| `max_tokens` | `4096` | Maximum tokens for recall results |
| `tags` | `None` | Tags applied when storing memories |
| `recall_tags` | `None` | Tags to filter when searching |
| `recall_tags_match` | `"any"` | Tag matching mode (any/all/any\_strict/all\_strict) |
| `retain_metadata` | `None` | Default metadata dict for retain operations |
| `retain_document_id` | `None` | Default document\_id for retain (groups/upserts memories) |
| `recall_types` | `None` | Fact types to filter (world, experience, opinion, observation) |
| `recall_include_entities` | `False` | Include entity information in recall results |
| `reflect_context` | `None` | Additional context for reflect operations |
| `reflect_max_tokens` | `None` | Max tokens for reflect results (defaults to `max_tokens`) |
| `reflect_response_schema` | `None` | JSON schema to constrain reflect output format |
| `reflect_tags` | `None` | Tags to filter memories used in reflect (defaults to `recall_tags`) |
| `reflect_tags_match` | `None` | Tag matching for reflect (defaults to `recall_tags_match`) |
| `include_retain` | `True` | Include the retain (store) tool |
| `include_recall` | `True` | Include the recall (search) tool |
| `include_reflect` | `True` | Include the reflect (synthesize) tool |
### `create_recall_node()`
| Parameter | Default | Description |
|---|---|---|
| `bank_id` | `None` | Static bank ID (or use `bank_id_from_config`) |
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `budget` | `"mid"` | Recall budget level |
| `max_tokens` | `4096` | Max tokens for recall results |
| `max_results` | `10` | Max memories to inject |
| `tags` | `None` | Tags to filter recall results |
| `tags_match` | `"any"` | Tag matching mode |
| `bank_id_from_config` | `"user_id"` | Config key to resolve bank ID at runtime |
| `output_key` | `None` | If set, write memory text to this state key instead of appending a SystemMessage to `messages` |
### `create_retain_node()`
| Parameter | Default | Description |
|---|---|---|
| `bank_id` | `None` | Static bank ID (or use `bank_id_from_config`) |
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `tags` | `None` | Tags applied to stored memories |
| `bank_id_from_config` | `"user_id"` | Config key to resolve bank ID at runtime |
| `retain_human` | `True` | Store human messages |
| `retain_ai` | `False` | Store AI responses |
### `HindsightStore()`
| Parameter | Default | Description |
|---|---|---|
| `client` | `None` | Pre-configured Hindsight client |
| `hindsight_api_url` | `None` | API URL (used if no client provided) |
| `api_key` | `None` | API key (used if no client provided) |
| `tags` | `None` | Tags applied to all retain operations |
### `configure()`
| Parameter | Default | Description |
|---|---|---|
| `hindsight_api_url` | Production API | Hindsight API URL |
| `api_key` | `HINDSIGHT_API_KEY` env | API key for authentication |
| `budget` | `"mid"` | Default recall budget level |
| `max_tokens` | `4096` | Default max tokens for recall |
| `tags` | `None` | Default tags for retain operations |
| `recall_tags` | `None` | Default tags to filter recall |
| `recall_tags_match` | `"any"` | Default tag matching mode |
| `verbose` | `False` | Enable verbose logging |
## Requirements
- Python >= 3.10
- langchain-core >= 0.3.0
- hindsight-client >= 0.4.0
- langgraph >= 0.3.0 *(only for nodes and store patterns — install with `pip install hindsight-langgraph[langgraph]`)*

View file

@ -6,6 +6,8 @@ sidebar_position: 1
Universal LLM memory integration via [LiteLLM](https://github.com/BerriAI/litellm). Add persistent memory to any LLM application with just a few lines of code.
[View Changelog →](../../changelog/integrations/litellm.md)
## Features
- **Universal LLM Support** - Works with 100+ LLM providers via LiteLLM (OpenAI, Anthropic, Groq, Azure, AWS Bedrock, Google Vertex AI, and more)

View file

@ -0,0 +1,248 @@
---
sidebar_position: 5
---
# NemoClaw
Persistent memory for [NemoClaw](https://nemoclaw.ai) sandboxed agents using [Hindsight](https://hindsight.vectorize.io).
NemoClaw runs [OpenClaw](https://openclaw.ai) inside an OpenShell sandbox with controlled filesystem, process, and network egress policies. The `hindsight-nemoclaw` package automates adding Hindsight memory to a sandbox in one command — no code changes required.
[View Changelog →](../../changelog/integrations/nemoclaw.md)
## Quick Start
```bash
npx @vectorize-io/hindsight-nemoclaw setup \
--sandbox my-assistant \
--api-url https://api.hindsight.vectorize.io \
--api-token <your-api-key> \
--bank-prefix my-sandbox
```
Get an API key at [Hindsight Cloud](https://ui.hindsight.vectorize.io/signup).
You'll see output like:
```
[0] Preflight checks...
✓ openshell found
✓ openclaw found
[1] Installing @vectorize-io/hindsight-openclaw plugin...
✓ Plugin installed
[2] Configuring plugin in ~/.openclaw/openclaw.json...
✓ Plugin config written (bank: my-sandbox-openclaw)
[3] Applying Hindsight network policy to sandbox "my-assistant"...
✓ Policy version 2 submitted
✓ Policy version 2 loaded (active version: 2)
[4] Restarting OpenClaw gateway...
✓ Gateway restarted
✓ Setup complete!
```
## How It Works
### The sandbox problem
OpenShell enforces strict network egress — every outbound endpoint must be explicitly permitted in the sandbox policy. By default, the Hindsight API (`api.hindsight.vectorize.io`) is not in that list.
The `hindsight-openclaw` plugin supports **external API mode**, where it skips the local daemon entirely and makes direct HTTPS calls to Hindsight Cloud. This is the natural fit for sandboxed environments: the plugin becomes a thin HTTP client, and the only sandbox change needed is one egress rule.
### What the setup command does
1. **Preflight** — verifies `openshell` and `openclaw` are installed
2. **Install plugin** — runs `openclaw plugins install @vectorize-io/hindsight-openclaw`
3. **Configure plugin** — writes external API mode config to `~/.openclaw/openclaw.json`
4. **Apply policy** — reads the current sandbox policy, merges the Hindsight egress block, and re-applies via `openshell policy set`
5. **Restart gateway** — runs `openclaw gateway restart`
### Memory flow
Once set up, the `hindsight-openclaw` plugin hooks into the OpenClaw gateway lifecycle:
- **`before_agent_start`** — recalls relevant memories from past sessions and injects them into context
- **`agent_end`** — retains the conversation to the Hindsight memory bank
The sandbox doesn't interfere with either step — it sees the Hindsight calls as normal HTTPS egress to a permitted endpoint.
## CLI Reference
```
hindsight-nemoclaw setup [options]
Options:
--sandbox <name> NemoClaw sandbox name (required)
--api-url <url> Hindsight API URL (required)
--api-token <token> Hindsight API token (required)
--bank-prefix <prefix> Memory bank prefix (default: "nemoclaw")
--skip-policy Skip sandbox network policy update
--skip-plugin-install Skip openclaw plugin installation
--dry-run Preview changes without applying
--help Show help
```
Use `--dry-run` to preview all changes before applying anything. Use `--skip-policy` if you manage sandbox policies manually.
## Manual Setup
If you prefer to apply the steps yourself instead of using the CLI:
### 1. Install the plugin
```bash
openclaw plugins install @vectorize-io/hindsight-openclaw
```
### 2. Configure `~/.openclaw/openclaw.json`
```json
{
"plugins": {
"entries": {
"hindsight-openclaw": {
"enabled": true,
"config": {
"hindsightApiUrl": "https://api.hindsight.vectorize.io",
"hindsightApiToken": "<your-api-key>",
"llmProvider": "claude-code",
"dynamicBankId": false,
"bankIdPrefix": "my-sandbox"
}
}
}
}
}
```
`llmProvider: "claude-code"` uses the Claude Code process already present in the sandbox — no additional API key needed.
### 3. Add the Hindsight network policy
`openshell policy set` replaces the entire policy document. Export your current policy first, add the Hindsight block, then re-apply:
```yaml
network_policies:
hindsight:
name: hindsight
endpoints:
- host: api.hindsight.vectorize.io
port: 443
protocol: rest
tls: terminate
enforcement: enforce
rules:
- allow:
method: GET
path: /**
- allow:
method: POST
path: /**
- allow:
method: PUT
path: /**
binaries:
- path: /usr/local/bin/openclaw
```
```bash
openshell policy set my-sandbox --policy /path/to/full-policy.yaml --wait
openclaw gateway restart
```
## Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
| `hindsightApiUrl` | string | — | Hindsight API base URL |
| `hindsightApiToken` | string | — | API token for authentication |
| `llmProvider` | string | auto-detect | LLM provider for memory extraction |
| `dynamicBankId` | boolean | `false` | Isolate memory per user (`true`) or share across sessions (`false`) |
| `bankIdPrefix` | string | `"nemoclaw"` | Prefix for the memory bank name |
### Bank naming
When `dynamicBankId: false`, all sessions write to a single bank named `{bankIdPrefix}-openclaw`. When `dynamicBankId: true`, each user gets an isolated bank — useful for multi-tenant deployments.
## Verifying It Works
After setup, check the gateway logs:
```bash
tail -f /tmp/openclaw/openclaw-*.log | grep Hindsight
```
On startup you should see:
```
[Hindsight] Plugin loaded successfully
[Hindsight] ✓ Using external API: https://api.hindsight.vectorize.io
[Hindsight] External API health: {"status":"healthy","database":"connected"}
[Hindsight] Default bank: my-sandbox-openclaw
[Hindsight] ✓ Ready (external API mode)
```
After a conversation:
```
[Hindsight] before_agent_start - bank: my-sandbox-openclaw, channel: undefined/webchat
[Hindsight Hook] agent_end triggered - bank: my-sandbox-openclaw
[Hindsight] Retained 6 messages to bank my-sandbox-openclaw for session agent:main:...
```
## Pitfalls
### Policy replacement is full-document
`openshell policy set` replaces the entire policy document. The `hindsight-nemoclaw setup` command handles this automatically. If you're applying manually, export the current policy first so existing rules aren't lost.
### LaunchAgent can't follow symlinks on macOS
On macOS, the OpenClaw gateway runs as a LaunchAgent under a restricted security context. `openclaw plugins install --link` creates a symlink the LaunchAgent can't follow — the setup command installs as a copy instead. If you see `EPERM: operation not permitted, scandir` in gateway logs, this is the cause.
### Memory retention is asynchronous
Fact extraction and entity resolution happen in the background after `retain`. If you open a new session immediately after closing one, the most recent memories may not be indexed yet — typically a few seconds.
### Binary-scoped egress
The `binaries` field in the network policy restricts the egress rule to a specific executable path. If OpenClaw updates and the binary path changes, the rule silently stops working. Check your binary path after upgrades.
## Troubleshooting
### Plugin not loading
```bash
openclaw plugins list | grep hindsight
# Should show: ✓ enabled │ Hindsight Memory │ ...
# Reinstall
openclaw plugins install @vectorize-io/hindsight-openclaw
```
### Egress blocked
If calls to `api.hindsight.vectorize.io` are being blocked, check the active sandbox policy:
```bash
openshell sandbox get my-assistant
```
Verify the `hindsight` block is present and the `binaries` path matches your OpenClaw binary:
```bash
which openclaw
```
### External API not connecting
```bash
tail -f /tmp/openclaw/openclaw-*.log | grep Hindsight
# If you see daemon startup messages instead of "Using external API",
# the plugin config isn't being read — check ~/.openclaw/openclaw.json
```

View file

@ -8,6 +8,8 @@ Local, long term memory for [OpenClaw](https://openclaw.ai) agents using [Hindsi
This plugin integrates [hindsight-embed](https://vectorize.io/hindsight/cli), a standalone daemon that bundles Hindsight's memory engine (API + PostgreSQL) into a single command. Everything runs locally on your machine, reuses the LLM you're already paying for, and costs nothing extra.
[View Changelog →](../../changelog/integrations/openclaw.md)
## Quick Start
**Step 1: Set up LLM for memory extraction**

View file

@ -6,6 +6,8 @@ sidebar_position: 6
Persistent memory tools for [Pydantic AI](https://ai.pydantic.dev/) agents via Hindsight. Give your agents long-term memory with retain, recall, and reflect — all async-native with no thread-pool hacks.
[View Changelog →](../../changelog/integrations/pydantic-ai.md)
## Features
- **Async-Native Tools** — Uses Pydantic AI's async tool interface directly (`aretain`, `arecall`, `areflect`)