Hindsight Memory plugin thumbnail

Hindsight Memory

Hindsight retain/recall memory integration for Agent Zero using lifecycle hooks.

Author Jehu 2 stars Version 0.4.0 Updated

README

<div align="right"> <img src="webui/thumbnail.jpg" width="128" height="128" alt="Hindsight Memory Plugin Icon" /> </div>

Hindsight Memory for Agent Zero

Hindsight Memory connects Agent Zero to a self-hosted Hindsight memory service so conversations can use durable long-term memory.

The plugin can:

  • recall relevant memories before an Agent Zero response,
  • inject those memories as context into the prompt,
  • retain useful conversation context after a response,
  • answer explicit memory questions through agent-callable tools,
  • fail open when Hindsight is unavailable so Agent Zero keeps working.

It is designed for private or self-hosted memory deployments. Do not point it at an untrusted public Hindsight endpoint for private conversations.

Status

Item Current value
Plugin ID a0hindsight
Version 0.4.0
Runtime type Agent Zero user plugin
Settings scope Per agent profile, per project
Default memory mode hybrid
Default bank strategy a0:v2:project:<slug>-<hash> (project-scoped)
Default service URL http://host.docker.internal:8888
Repository git@github.com:Jehu/a0-hindsight.git

Implemented:

  • automatic prompt-time recall,
  • background retain,
  • dynamic agent-profile bank IDs,
  • settings UI,
  • retain filtering and redaction baseline,
  • Hindsight bank mission configuration,
  • optional Hindsight Reflect path,
  • agent tools for recall, reflect, and retain,
  • deadline, cache, and circuit-breaker safeguards,
  • optional Bearer API key auth (settings, env var, A0 secrets store),
  • automatic project and repo tagging on retains.

Requirements

You need:

  1. Agent Zero with user-plugin support.
  2. A reachable Hindsight API service.
  3. Network access from the Agent Zero container to Hindsight.

The plugin expects compatible Hindsight endpoints for:

Endpoint Purpose
GET /health Health check
PUT /v1/default/banks/{bank_id} Apply bank-level missions/settings
POST /v1/default/banks/{bank_id}/memories/recall Raw memory recall
POST /v1/default/banks/{bank_id}/reflect Synthesized memory answers
POST /v1/default/banks/{bank_id}/memories Retain memories

Default local service URL:

http://host.docker.internal:8888

Authentication

The plugin sends requests without auth headers by default, which works with unsecured local deployments. For secured Hindsight instances (for example an ApiKeyTenantExtension fronting a shared central bank), enable Bearer auth:

Authorization: Bearer <key>

The key is resolved in this order:

  1. api_key setting,
  2. HINDSIGHT_API_KEY environment variable,
  3. Agent Zero secrets store (usr/secrets.env, plus project secrets).

An empty key keeps the legacy no-auth behavior. The key is only used in HTTP headers and never appears in logs or retained metadata.

Installation

Clone the plugin into Agent Zero's user plugin directory:

git clone git@github.com:Jehu/a0-hindsight.git /a0/usr/plugins/a0hindsight

The manifest must be located at:

/a0/usr/plugins/a0hindsight/plugin.yaml

Then restart Agent Zero or refresh the plugin list. The plugin should appear as:

a0hindsight

Enable it through the Agent Zero Plugins UI. A local runtime toggle may also exist:

/a0/usr/plugins/a0hindsight/.toggle-1

Runtime toggle files, local config, caches, and .env files are intentionally not part of the repository.

How it works

The plugin participates in two main lifecycle points:

  1. Before the model response: it can recall relevant memories from Hindsight and inject them into the system prompt as context.
  2. After the model response: it can retain recent conversation context in Hindsight for future use.

Hindsight is treated as helpful context, not as a hard dependency. If the service is slow or offline, the plugin logs the issue and Agent Zero continues without memory context.

Memory modes

memory_mode controls how the plugin participates in a turn.

Mode Automatic prompt recall Agent-callable tools Recommended use
context yes no Quiet automatic memory context only
tools no yes No automatic injection; agent uses memory only when needed
hybrid yes yes Recommended default: fast context plus explicit tools
off no no Fully disable memory behavior without disabling the plugin

Default:

memory_mode: "hybrid"

The plugin does not use keyword matching or an extra LLM classifier to decide when to switch between recall and reflect. The behavior is explicit:

  • automatic recall uses the configured recall_method,
  • high-quality synthesized memory answers are available through the hindsight_reflect tool,
  • users or agents can explicitly call memory tools when needed.

Agent tools

When memory_mode is tools or hybrid, the plugin exposes three tools.

Tool Purpose Typical use
hindsight_recall Raw Hindsight recall Fast lookup of matching memories
hindsight_reflect Synthesized answer from Hindsight memory Questions like “what do you remember about my preferences?”
hindsight_retain Explicit durable memory write Store an important preference, decision, or project fact

hindsight_recall

Use for fast retrieval of matching memories.

Common arguments:

Argument Description
query Required memory search query
bank_id Optional override; defaults to the agent-profile bank
budget Optional Hindsight budget, e.g. low, mid, high
max_tokens Optional response budget
types Optional memory types, e.g. world
tags Optional tag filter
tags_match any or all

hindsight_reflect

Use for explicit memory questions where a synthesized answer is better than raw snippets.

Common arguments:

Argument Description
query Required memory question
bank_id Optional override
budget Optional Hindsight budget
max_tokens Optional answer budget
fact_types Optional memory types to consider
tags Optional tag filter
include_facts Include supporting evidence when available

Reflect is slower than raw recall, but it can answer natural preference questions better than simple similarity search.

hindsight_retain

Use to explicitly store a durable fact.

Common arguments:

Argument Description
content Required text to store
context Optional retain context/instruction
bank_id Optional override
tags Optional tags
document_prefix Optional document ID prefix
async_mode Queue retain work asynchronously when supported

Store only durable information: user preferences, project facts, stable decisions, and reusable constraints. Do not store secrets.

Settings UI

The plugin provides a configuration panel in Agent Zero settings for agent profiles because plugin.yaml contains:

settings_sections:
  - agent
per_agent_config: true

Use the Settings modal Save button to persist changes.

The UI covers:

  • plugin enablement,
  • memory mode,
  • Hindsight base URL and API key,
  • bank ID override and bank ID prefix,
  • bank missions for reflect, retain, and observations,
  • recall deadlines, budget, tags, types, cache, and circuit breaker,
  • retain policy, context size, async mode, redaction/noise controls,
  • automatic project and repo tagging toggles,
  • observability settings.

Configuration reference

Defaults live in:

/a0/usr/plugins/a0hindsight/default_config.yaml

Important settings:

Setting Default Purpose
enabled true Master plugin switch
memory_mode hybrid Controls automatic context and tool availability
base_url http://host.docker.internal:8888 Hindsight API base URL
api_key empty Optional Bearer token for API auth; falls back to HINDSIGHT_API_KEY env var
bank_id empty Optional explicit bank ID override
bank_config_timeout_seconds 5 Timeout for applying bank-level settings
reflect_mission see config Mission used by Hindsight Reflect
retain_mission see config Mission used by Hindsight retain/extraction
retain_extraction_mode custom Hindsight retain extraction mode; empty = keep bank default, no bank override (recommended for shared banks)
retain_project_tag true Tag retains from an active project with project:<name> (coding-agents compatible)
retain_repo_tags true Add repo:<name> tags for git repos referenced by file paths in the retained content (multi-repo aware)
retain_custom_instructions see config Durable-memory extraction guidance
enable_observations true Enables Hindsight observation consolidation
observations_mission see config Guides observation synthesis
recall_enabled true Enables prompt-time recall when context mode is active
retain_enabled true Enables retain after responses
recall_mode deadline Fail-open recall mode for prompt path
recall_method recall recall for raw recall or reflect for synthesized prompt injection
recall_deadline_ms 2200 Normal prompt-path recall deadline
recall_http_timeout_seconds 3.0 Hindsight recall HTTP timeout
recall_force_deadline_ms 3200 Longer deadline for forced memory questions
recall_timeout_seconds 3 Legacy compatibility field
recall_budget low Hindsight recall budget
recall_max_tokens 400 Maximum recall/reflect result budget
recall_query_max_chars 800 Local query length cap
recall_types observation Memory types used by default recall
prefer_observations true Ask Hindsight to prefer observations when available
recall_tags agent-zero, hindsight Tags used for recall filtering
recall_tags_match any Recall tag match mode
retain_tags agent-zero, hindsight Tags applied to retained content
retain_async true Queue retain work asynchronously when supported
retain_timeout_seconds 12 Retain HTTP timeout
retain_context_chars 5000 Retained conversation character cap
retain_min_chars 80 Skip retain below this size
retain_document_prefix a0-chat Prefix for retained documents
inject_heading Hindsight recalled memories Heading for injected prompt context
log_enabled true Emit Agent Zero log entries
observability_verbose true Include detailed log fields
retain_policy_enabled true Apply local retain filtering
retain_skip_if_no_user_message true Skip retain for no-user turns
retain_strip_tool_results true Collapse obvious tool-result noise
retain_max_tool_result_chars 400 Max preserved chars for collapsed tool blocks
retain_recent_history_chars 5000 Recent-history cap for retain policy

Retain-side reflect is reserved for a future rollout:

Setting Default Note
reflect_enabled false Retain-side rollout flag; not needed for hindsight_reflect tool

For most users, leave this advanced flag unchanged.

Bank ID strategy

By default, memories are scoped by Agent Zero project (shared across agent profiles within the same project):

a0:v2:project:<project_slug>-<hash>

For the default agent0 profile, the bank is:

a0:v2:project:hindsight_implementation-<hash>

You can override this with bank_id if you want a fixed bank. If bank_id is non-empty, it fully replaces the dynamic strategy.

Project-scoped routing is the default (bank_scope: project). Set bank_scope: agent for a per-agent-profile bank, or explicit to require bank_id.

Recall behavior and latency safeguards

Prompt-time recall is designed to be safe for interactive use:

  1. Trivial acknowledgements can be skipped by conditional recall.
  2. Normal recall waits only up to recall_deadline_ms.
  3. Explicit forced recall can use recall_force_deadline_ms.
  4. Hindsight HTTP calls have their own timeout.
  5. Exact cache hits are used only for identical query and settings dimensions.
  6. Repeated service failures open a circuit breaker to avoid repeated slow failures.
  7. Misses, failures, and deadline misses fail open.

This means Hindsight can improve context, but should not block normal Agent Zero operation.

Retain behavior

Retain runs after responses and is asynchronous by default.

Before content is sent to Hindsight, the plugin can:

  • skip no-user turns,
  • cap retained history size,
  • collapse obvious large tool-result blocks,
  • redact common secret-looking strings,
  • skip very short content,
  • attach metadata such as source, plugin name, agent profile, bank strategy, context ID, redaction count, and tool-block count.

Automatic project and repo tags

Retains are tagged with project and repository context, compatible with the coding-agents project:{gitProject} convention:

  1. Project tag (retain_project_tag, default on): every retain from an active Agent Zero project gets project:<project-name>. This covers non-git projects too and matches coding-agents tags exactly whenever the repository name equals the project name.
  2. Repo tags (retain_repo_tags, default on): every git repository actually referenced by a file path in the retained conversation content adds a repo:<name> tag. Unlike a CWD-based single tag, a conversation touching several nested repositories gets several tags, and conversations without repository paths get none. The repository named after the project itself is skipped to avoid duplicating the project tag.

The repository index is cached per project (TTL 300s, scan depth 6, pruning node_modules, venvs, and caches). Explicit tags passed to the hindsight_retain tool bypass this enrichment.

The configured retain mission and custom instructions tell Hindsight to prefer durable facts such as:

  • explicit user preferences,
  • tool and workflow preferences,
  • package manager preferences,
  • project facts,
  • stable implementation decisions,
  • recurring constraints.

Observability

When log_enabled is true, the plugin writes Agent Zero log entries for important memory events, including:

  • bank configuration applied or failed,
  • recall skipped,
  • recall started,
  • recall completed with no memories,
  • recall completed with injected memories,
  • recall deadline miss or failure,
  • retain skipped,
  • retain started,
  • retain completed,
  • retain queued after timeout fallback,
  • retain failed.

When observability_verbose is true, logs can include fields such as:

bank=<bank_id> query_chars=<n> content_chars=<n> results=<n> latency_ms=<n> redactions=<n> tool_blocks_collapsed=<n>

WebUI notifications on critical failures

The plugin raises Agent Zero WebUI notifications (with a helpful hint) when a critical Hindsight failure occurs, so degraded memory is visible without reading logs. Each notification type is de-duplicated with a 5-minute cooldown to avoid flooding the UI.

Trigger Hint
Circuit breaker opens Recall paused; check that the Hindsight API and PostgreSQL are running. Auto-retries after 60s.
Recall connection failure Recall could not run; verify API reachability and database health.
Retain failure Memories could not be stored; verify API reachability and database health.

Persistent JSONL file logging

Optional structured file logging (off by default) writes one JSON object per line to a rotating file. Secrets (API keys, tokens, passwords) are redacted and custom log directories are constrained to the allowed log base.

Setting Default Purpose
file_log_enabled false Enable JSONL file logging
file_log_dir empty Custom log dir (must resolve under the allowed base)
file_log_level debug Minimum level: debug < info < util < warning < error
file_log_max_bytes 5000000 Rotation size per file
file_log_backup_count 3 Number of rotated backups to keep

Default path: /a0/usr/logs/a0hindsight/hindsight.log.jsonl (or $A0_LOGS_DIR/a0hindsight/ when set).

Smoke tests and verification

Run the plugin smoke script (no PYTHONPATH needed; it resolves the framework root itself):

cd /a0/usr/plugins/a0hindsight
/opt/venv-a0/bin/python execute.py

The smoke script uses the effective plugin configuration:

  • base_url, bank_id/bank_scope, recall parameters and the API key come from the plugin config (config.json via helpers.plugins.get_plugin_config, with a direct config.json fallback) and the A0 secrets store (HINDSIGHT_API_KEY).
  • HINDSIGHT_BASE_URL / HINDSIGHT_BANK_ID env vars still override the config.
  • With bank_scope: project and no active project (execute runs outside the agent loop), it falls back to the agent bank so the smoke test always runs.
  • The script removes its own directory from sys.path first, so the plugin's helpers package cannot shadow the framework's top-level helpers namespace.

Run unit tests:

cd /a0/usr/plugins/a0hindsight
PYTHONPATH=/a0 /opt/venv-a0/bin/python -m pytest tests/ -v

99 tests passing as of v0.4.0.

Run a compile check:

cd /a0/usr/plugins/a0hindsight
PYTHONPATH=/a0 /opt/venv-a0/bin/python -m py_compile \
  helpers/client.py \
  helpers/repo_tags.py \
  helpers/recall_policy.py \
  helpers/recall_manager.py \
  helpers/runtime.py \
  tools/*.py

Run the recall benchmark:

cd /a0/usr/plugins/a0hindsight
PYTHONPATH=/a0 /opt/venv-a0/bin/python scripts/recall_benchmark.py \
  --iterations 5 \
  --output /a0/usr/workdir/hindsight_recall_benchmark.json

Benchmark queries are stored in:

scripts/recall_benchmark_queries.json

Troubleshooting

Plugin does not appear

Check:

ls /a0/usr/plugins/a0hindsight/plugin.yaml
PYTHONPATH=/a0 /opt/venv-a0/bin/python -c "import yaml; yaml.safe_load(open('/a0/usr/plugins/a0hindsight/plugin.yaml')); print('ok')"

Restart Agent Zero or refresh plugins after installing or changing manifest files.

No memories are recalled

Check:

  • plugin is enabled,
  • memory_mode is context or hybrid,
  • recall_enabled is true,
  • base_url points to a reachable Hindsight service,
  • the current agent profile uses the bank you expect,
  • recall tags/types are not filtering out relevant memories.

Tools are unavailable

Check:

  • memory_mode is tools or hybrid,
  • plugin is enabled,
  • Agent Zero has refreshed plugin discovery after the tools/ files were added.

Reflect works but is slow

That is expected. Reflect synthesizes an answer from memory and can be much slower than raw recall. Keep automatic prompt injection on recall_method: recall for interactive speed and use hindsight_reflect for explicit memory questions.

Hindsight is offline or slow

Agent Zero should continue normally. Check Agent Zero logs for Hindsight warnings and check the Hindsight service health endpoint:

curl -s http://host.docker.internal:8888/health

Security and privacy

  • Use a private, trusted Hindsight service for private conversations.
  • Do not intentionally store credentials, API keys, passwords, private keys, or access tokens.
  • The plugin includes basic redaction, but it is not a full data-loss-prevention system.
  • Review retained memories and Hindsight service access controls according to your deployment needs.
  • Treat Hindsight memories as context, not as current user instructions. Current chat instructions should take precedence.

Repository layout

plugin.yaml
README.md
default_config.yaml
execute.py
helpers/
  bank_scope.py
  client.py
  file_logger.py
  recall_cache.py
  recall_circuit.py
  recall_errors.py
  recall_manager.py
  recall_policy.py
  repo_tags.py
  runtime.py
hooks.py
extensions/
  python/
    message_loop_prompts_after/
      _56_hindsight_recall.py
    monologue_end/
      _56_hindsight_retain.py
tools/
  hindsight_recall.py
  hindsight_reflect.py
  hindsight_retain.py
webui/
  config.html
scripts/
  recall_benchmark.py
  recall_benchmark_queries.json
tests/

Known limitations

  • Existing memories in older banks are not migrated automatically (use the migration script in scripts/).
  • Retain filtering is conservative and may still store more context than ideal.
  • Reflect is intentionally explicit because it is slower than raw recall.

Roadmap

Planned improvements:

  1. Improve duplicate suppression and durable-memory extraction quality.
  2. Implement retain-side reflect (currently reserved behind reflect_enabled).

License

Released under the MIT License. See LICENSE for the full text.