Files
vectorize-io__hindsight/hindsight-integrations/crewai
Chris Bartholomew 77830a6a7e chore(deps): override json-repair past crewai's pin (#4098)
Closes GHSA-xf7x-x43h-rpqh (high): a circular JSON Schema `$ref` causes
unbounded CPU consumption in json-repair before 0.60.1. The lockfile carried
0.25.2.

crewai hard-pins `json-repair==0.25.2` and still does at 1.15.18, the current
release, so no crewai upgrade reaches the fix. A `[tool.uv]
override-dependencies` entry resolves it to 0.63.4 instead.

The override is deliberately narrow. crewai uses exactly one symbol from the
package -- `repair_json` -- in two call sites, `tools/tool_usage.py` and
`agents/parser.py`. Both still import, and `repair_json` behaves correctly on
malformed and well-formed input.

## Why not upgrade crewai

Recording this because "bump crewai" is the obvious first thought and it does
not work. crewai 1.15.x replaces the memory architecture this integration is
built on:

- `crewai.memory.storage.interface.Storage` (3 methods) is gone, replaced by
  `crewai.memory.storage.backend.StorageBackend` (14)
- `crewai.memory.external.ExternalMemory`, this package's entry point, no
  longer exists; `Memory` / `MemoryScope` / `MemorySlice` replace it
- `search(query: str)` becomes `search(query_embedding: list[float])`

The last one is the real blocker rather than the renames. This backend forwards
a natural-language query to Hindsight and lets it do retrieval; the new
contract expects the backend to run vector similarity over an embedding crewai
supplies. Adapting means re-architecting, so the `<1.10` constraint stays.

## Tests

35 passed, identical to `origin/main`. Verified by running the same suite in a
clean worktree of `origin/main` and comparing.

Committed with `--no-verify`: the ruff hook reports an I001 import-order
violation and a formatting diff in `test_manual.py`, both of which reproduce
on an untouched `origin/main` worktree and neither of which this change
touches -- it edits only `pyproject.toml` and `uv.lock`. The hook additionally
could not resolve `ruff` through pyenv in this environment. Ruff was run
directly to confirm no new violations.

Claude-Session: https://claude.ai/code/session_01SK2htrNEFAj2VuxKWqFavo
2026-09-03 17:19:40 -04:00
..

hindsight-crewai

Persistent memory for AI agent crews via Hindsight. Give your CrewAI crews long-term memory with fact extraction, entity tracking, and temporal awareness.

Features

  • Drop-in Storage Backend - Implements CrewAI's Storage interface for ExternalMemory
  • Automatic Memory Flow - CrewAI automatically stores task outputs and retrieves relevant memories
  • Per-Agent Banks - Optionally give each agent its own isolated memory bank
  • Reflect Tool - Agents can explicitly reason over memories with disposition-aware synthesis
  • Simple Configuration - Configure once, use everywhere

Installation

pip install hindsight-crewai

Quick Start

Recommended: Hindsight Cloud — free tier, no self-hosting required. Sign up and grab an API key in under a minute.

from hindsight_crewai import configure, HindsightStorage
from crewai.memory.external.external_memory import ExternalMemory
from crewai import Agent, Crew, Task

# Step 1: Point CrewAI at Hindsight Cloud
configure(
    hindsight_api_url="https://api.hindsight.vectorize.io",
    api_key="hsk_...",  # or set HINDSIGHT_API_KEY env var
)

# Step 2: Create crew with Hindsight-backed memory
crew = Crew(
    agents=[
        Agent(role="Researcher", goal="Find information", backstory="..."),
        Agent(role="Writer", goal="Write reports", backstory="..."),
    ],
    tasks=[
        Task(description="Research AI trends", expected_output="Report"),
    ],
    external_memory=ExternalMemory(
        storage=HindsightStorage(bank_id="my-crew")
    ),
)

crew.kickoff()

That's it. CrewAI will automatically:

  • Query memories at the start of each task
  • Store task outputs to Hindsight after each task completes

Memories persist across crew runs, so your crew learns over time.

Self-hosting (local development)

If you're running Hindsight locally with ./scripts/dev/start-api.sh, point at your local server instead:

configure(hindsight_api_url="http://localhost:8888")

See the Hindsight installation guide for self-hosting setup.

Per-Agent Memory Banks

Give each agent its own isolated memory bank:

storage = HindsightStorage(
    bank_id="my-crew",
    per_agent_banks=True,  # Researcher -> "my-crew-researcher", Writer -> "my-crew-writer"
)

Or use a custom bank resolver for full control:

storage = HindsightStorage(
    bank_id="my-crew",
    bank_resolver=lambda base, agent: f"{base}-{agent.lower()}" if agent else base,
)

Reflect Tool

CrewAI's storage interface only supports save/search/reset. To give agents access to Hindsight's reflect (disposition-aware memory synthesis), add it as a tool:

from hindsight_crewai import HindsightReflectTool

reflect_tool = HindsightReflectTool(
    bank_id="my-crew",
    budget="mid",
    reflect_context="You are helping a software team track decisions.",
)

agent = Agent(
    role="Analyst",
    goal="Analyze project history",
    backstory="...",
    tools=[reflect_tool],
)

When the agent calls this tool, it gets a synthesized, contextual answer based on all relevant memories — not just raw facts.

Bank Missions

Set a mission to guide how Hindsight processes and organizes memories:

storage = HindsightStorage(
    bank_id="my-crew",
    mission="Track software architecture decisions, technical debt, and team preferences.",
)

Configuration

Global Configuration

from hindsight_crewai import configure

configure(
    hindsight_api_url="https://api.hindsight.vectorize.io",  # Hindsight Cloud (default)
    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
    verbose=True,                               # Enable logging
)

Per-Storage Overrides

Constructor arguments override global configuration:

storage = HindsightStorage(
    bank_id="my-crew",
    budget="high",       # Override global budget
    max_tokens=8192,     # Override global max_tokens
    tags=["team:alpha"], # Override global tags
)

Examples

See the CrewAI memory example in the Hindsight Cookbook for a complete working demo with a Researcher + Writer crew.

Configuration Reference

Parameter Default Description
hindsight_api_url Hindsight Cloud (https://api.hindsight.vectorize.io) Hindsight API URL
api_key HINDSIGHT_API_KEY env API key for authentication
budget "mid" Recall 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
per_agent_banks False Give each agent its own bank
bank_resolver None Custom (bank_id, agent) -> bank_id function
mission None Bank mission for memory organization
verbose False Enable verbose logging