Compare commits

..
5 Commits
Author SHA1 Message Date
Nicolò Boschi 6c84e33100 chore: update OpenAPI spec with correct version example 2026-01-28 18:26:07 +01:00
Nicolò Boschi 45aa8b1e93 fix: /version endpoint return wrong version 2026-01-28 18:14:17 +01:00
Nicolò Boschi fccbdfef16 fix: include correct __version__ in python packages (#218)
Updates:
- hindsight-api/hindsight_api/__init__.py: bump __version__ to 0.4.0
- scripts/release.sh: add logic to update __version__ in Python __init__.py files during release
2026-01-28 17:25:17 +01:00
Nicolò Boschi 20f2b92069 doc: release notes for 0.4.0 (#217)
* doc: release notes for 0.4.0

* doc: release notes for 0.4.0

* doc: release notes for 0.4.0

* doc: release notes for 0.4.0
2026-01-28 16:54:05 +01:00
Nicolò Boschi 1bf90358c3 doc: add blog (#201)
* doc: introduce mental models blog post

Write blog post introducing Mental Models in Hindsight 0.4.0:
- Evolution from observations and opinions
- How mental models work (consolidation, evidence tracking)
- Breaking changes and migration path
- Environment variable to enable (experimental)
- Agentic reflect explanation

* updates

* Update 2026-01-26-learning-capabilities.md

* fix: doc build issues

- Add missing code snippets for versioned docs (recall-opinions-only, recall-include-entities, bank-background)
- Fix broken links by using relative paths for version compatibility
- Update blog post title to sentence case
- Clear versions.json since v0.3 versioned docs don't exist yet
- Enable INCLUDE_CURRENT_VERSION in build script

* fix: update doc links after rebase

- Fix blog post to link to correct pages (/developer/api/mental-models and /developer/observations)
- Fix CLI docs to link to /api-reference instead of /api

* feat: add directives section to blog post

- Update intro to mention three layers of knowledge
- Add concise Directives section for compliance/guardrails
- Add directives to resources section
- Keep focus on learning capabilities (observations and mental models)

* fix: revert intro to focus on learning capabilities only

Directives are a separate feature for compliance/guardrails, not a learning capability. The blog post is about observations and mental models.
2026-01-28 15:42:14 +01:00
148 changed files with 8871 additions and 371 deletions
+2 -1
View File
@@ -50,4 +50,5 @@ hindsight-clients/rust/target
.claude
whats-next.md
TASK.md
CHANGELOG.md
# Changelog is now tracked in hindsight-docs/src/pages/changelog.md
# CHANGELOG.md
+3 -2
View File
@@ -1323,7 +1323,7 @@ class VersionResponse(BaseModel):
model_config = ConfigDict(
json_schema_extra={
"example": {
"api_version": "1.0.0",
"api_version": "0.4.0",
"features": {
"observations": False,
"mcp": True,
@@ -1567,11 +1567,12 @@ def _register_routes(app: FastAPI):
Returns version info and feature flags that can be used by clients
to determine which capabilities are available.
"""
from hindsight_api import __version__
from hindsight_api.config import get_config
config = get_config()
return VersionResponse(
api_version="1.0.0",
api_version=__version__,
features=FeaturesInfo(
observations=config.enable_observations,
mcp=config.mcp_enabled,
@@ -137,26 +137,15 @@ class LocalSTCrossEncoder(CrossEncoderModel):
# which can cause issues when accelerate is installed but no GPU is available.
# Note: We do NOT use device_map because CrossEncoder internally calls .to(device)
# after loading, which conflicts with accelerate's device_map handling.
import os
import torch
# Force CPU mode if HINDSIGHT_FORCE_CPU is set (used in daemon mode to avoid MPS/XPC issues)
force_cpu = os.getenv("HINDSIGHT_FORCE_CPU", "0") == "1"
# Check for GPU (CUDA) or Apple Silicon (MPS)
has_gpu = torch.cuda.is_available() or (hasattr(torch.backends, "mps") and torch.backends.mps.is_available())
if force_cpu:
device = "cpu"
logger.info("Reranker: forcing CPU mode (HINDSIGHT_FORCE_CPU=1)")
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
# Check for GPU (CUDA) or Apple Silicon (MPS)
has_gpu = torch.cuda.is_available() or (
hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
)
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
device = "cpu"
device = "cpu"
self._model = CrossEncoder(
self.model_name,
@@ -222,21 +211,12 @@ class LocalSTCrossEncoder(CrossEncoderModel):
)
# Determine device based on hardware availability
import os
has_gpu = torch.cuda.is_available() or (hasattr(torch.backends, "mps") and torch.backends.mps.is_available())
force_cpu = os.getenv("HINDSIGHT_FORCE_CPU", "0") == "1"
if force_cpu:
device = "cpu"
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
has_gpu = torch.cuda.is_available() or (
hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
)
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
device = "cpu"
device = "cpu"
self._model = CrossEncoder(
self.model_name,
@@ -132,26 +132,15 @@ class LocalSTEmbeddings(Embeddings):
# Determine device based on hardware availability.
# We always set low_cpu_mem_usage=False to prevent lazy loading (meta tensors)
# which can cause issues when accelerate is installed but no GPU is available.
import os
import torch
# Force CPU mode if HINDSIGHT_FORCE_CPU is set (used in daemon mode to avoid MPS/XPC issues)
force_cpu = os.getenv("HINDSIGHT_FORCE_CPU", "0") == "1"
# Check for GPU (CUDA) or Apple Silicon (MPS)
has_gpu = torch.cuda.is_available() or (hasattr(torch.backends, "mps") and torch.backends.mps.is_available())
if force_cpu:
device = "cpu"
logger.info("Embeddings: forcing CPU mode (HINDSIGHT_FORCE_CPU=1)")
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
# Check for GPU (CUDA) or Apple Silicon (MPS)
has_gpu = torch.cuda.is_available() or (
hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
)
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
device = "cpu"
device = "cpu"
self._model = SentenceTransformer(
self.model_name,
@@ -210,21 +199,12 @@ class LocalSTEmbeddings(Embeddings):
)
# Determine device based on hardware availability
import os
has_gpu = torch.cuda.is_available() or (hasattr(torch.backends, "mps") and torch.backends.mps.is_available())
force_cpu = os.getenv("HINDSIGHT_FORCE_CPU", "0") == "1"
if force_cpu:
device = "cpu"
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
has_gpu = torch.cuda.is_available() or (
hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
)
if has_gpu:
device = None # Let sentence-transformers auto-detect GPU/MPS
else:
device = "cpu"
device = "cpu"
self._model = SentenceTransformer(
self.model_name,
-6
View File
@@ -140,12 +140,6 @@ def main():
args.port = DEFAULT_DAEMON_PORT
args.host = "127.0.0.1" # Only bind to localhost for security
# Force CPU mode for daemon to avoid macOS MPS/XPC issues
# MPS (Metal Performance Shaders) has unstable XPC connections in background processes
# that can cause assertion failures and process crashes at the C++ level
# (which Python exception handlers cannot catch)
os.environ["HINDSIGHT_FORCE_CPU"] = "1"
# Check if another daemon is already running
daemon_lock = DaemonLock()
if not daemon_lock.acquire():
@@ -1063,3 +1063,38 @@ async def test_retain_async_no_usage(api_client):
# Usage should be None for async operations
assert result.get("usage") is None, "Async retain should not include usage"
@pytest.mark.asyncio
async def test_version_endpoint_returns_correct_version(api_client):
"""Test that the /version endpoint returns the correct API version.
The version should match the __version__ defined in hindsight_api.__init__.py
and should not be a hardcoded string.
"""
from hindsight_api import __version__
# Call the /version endpoint
response = await api_client.get("/version")
assert response.status_code == 200
result = response.json()
# Verify response structure
assert "api_version" in result, "Response should include 'api_version' field"
assert "features" in result, "Response should include 'features' field"
# Verify the version matches the package version
assert result["api_version"] == __version__, (
f"API version should be {__version__}, got {result['api_version']}"
)
# Verify features field structure
features = result["features"]
assert "observations" in features
assert "mcp" in features
assert "worker" in features
assert isinstance(features["observations"], bool)
assert isinstance(features["mcp"], bool)
assert isinstance(features["worker"], bool)
print(f"Version endpoint returned: api_version={result['api_version']}, features={features}")
+125
View File
@@ -0,0 +1,125 @@
use std::process::Command;
#[test]
fn test_cli_help() {
let output = Command::new("cargo")
.args(["run", "--", "--help"])
.output()
.expect("Failed to execute command");
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Hindsight CLI"));
}
#[test]
fn test_cli_version() {
let output = Command::new("cargo")
.args(["run", "--", "--version"])
.output()
.expect("Failed to execute command");
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("hindsight"));
}
#[test]
fn test_ui_command_without_config() {
// Test that the ui command handles missing config gracefully
// Create a temp home directory with no config
let temp_dir = std::env::temp_dir().join(format!("hindsight-test-ui-{}", std::process::id()));
std::fs::create_dir_all(&temp_dir).expect("Failed to create temp dir");
let output = Command::new("cargo")
.args(["run", "--", "ui"])
.env_remove("HINDSIGHT_API_URL")
.env_remove("HINDSIGHT_API_KEY")
.env("HOME", &temp_dir)
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
// Either it fails with a config error or it succeeds if there's a default config
// Just verify it doesn't crash unexpectedly
assert!(
!output.status.success()
|| stdout.contains("Launching Hindsight Control Plane UI")
|| stderr.contains("Configuration error")
|| stderr.contains("HINDSIGHT_API_URL"),
"Unexpected output - stdout: {}, stderr: {}",
stdout,
stderr
);
// Cleanup
std::fs::remove_dir_all(&temp_dir).ok();
}
#[test]
fn test_ui_command_with_config() {
// This test is skipped by default since it requires a running control plane
// and would block for a long time. The other tests cover the basic functionality.
// To run this test manually:
// 1. Build the control plane: cd hindsight-control-plane && npm run build
// 2. Run: cargo test test_ui_command_with_config -- --ignored
// Just verify that the ui command accepts the configuration
let temp_dir = std::env::temp_dir().join(format!("hindsight-test-ui-valid-{}", std::process::id()));
std::fs::create_dir_all(&temp_dir).expect("Failed to create temp dir");
// Write a minimal config
let config_dir = temp_dir.join(".config").join("hindsight");
std::fs::create_dir_all(&config_dir).expect("Failed to create config dir");
let config_file = config_dir.join("config");
std::fs::write(&config_file, "api_url=http://localhost:8888\napi_key=test-key\n")
.expect("Failed to write config");
let output = Command::new("cargo")
.args(["run", "--", "ui", "--help"])
.env("HOME", &temp_dir)
.output()
.expect("Failed to execute command");
// The --help should work regardless
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Hindsight CLI") || output.status.success());
// Cleanup
std::fs::remove_dir_all(&temp_dir).ok();
}
#[test]
fn test_configure_command() {
// Test that configure command creates/updates config
let temp_dir = std::env::temp_dir().join(format!("hindsight-test-{}", std::process::id()));
std::fs::create_dir_all(&temp_dir).expect("Failed to create temp dir");
let output = Command::new("cargo")
.args([
"run",
"--",
"configure",
"--api-url",
"http://localhost:9999",
"--api-key",
"test-key-123"
])
.env("HOME", &temp_dir)
.output()
.expect("Failed to execute command");
assert!(
output.status.success(),
"Configure command failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Configuration saved") || stdout.contains("success"));
// Cleanup
std::fs::remove_dir_all(&temp_dir).ok();
}
@@ -7,7 +7,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -489,7 +489,7 @@ class Configuration:
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\
"Version of the API: 0.1.0\n"\
"Version of the API: 0.4.0\n"\
"SDK Package Version: 0.0.7".\
format(env=sys.platform, pyversion=sys.version)
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -6,7 +6,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -5,7 +5,7 @@
HTTP API for Hindsight
The version of the OpenAPI document: 0.1.0
The version of the OpenAPI document: 0.4.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
@@ -25,7 +25,7 @@ GITHUB_REPO = "vectorize-io/hindsight"
GITHUB_RELEASES_URL = f"https://github.com/{GITHUB_REPO}/releases"
GITHUB_COMMIT_URL = f"https://github.com/{GITHUB_REPO}/commit"
REPO_PATH = Path(__file__).parent.parent.parent
CHANGELOG_PATH = REPO_PATH / "hindsight-docs" / "docs" / "changelog" / "index.md"
CHANGELOG_PATH = REPO_PATH / "hindsight-docs" / "src" / "pages" / "changelog.md"
class ChangelogEntry(BaseModel):
@@ -238,7 +238,7 @@ def read_existing_changelog() -> tuple[str, str]:
"""Read existing changelog and split into header and content."""
if not CHANGELOG_PATH.exists():
header = """---
sidebar_position: 1
hide_table_of_contents: true
---
# Changelog
@@ -0,0 +1,284 @@
---
slug: learning-capabilities
title: "Agent memory that learns: observations and mental models"
authors: [hindsight]
image: /img/reflect-operation.webp
hide_table_of_contents: true
---
Today we're releasing Hindsight 0.4.0, which introduces two powerful learning capabilities for AI agents: **Observations** for automatic knowledge consolidation, and **Mental Models** for user-curated summaries.
<!-- truncate -->
## Two Levels of Learning
Hindsight 0.4.0 introduces a hierarchical learning system:
| Level | What It Is | How It's Created |
|-------|------------|------------------|
| **Mental Models** | User-curated summaries for common queries | Manually created via API |
| **Observations** | Consolidated knowledge from facts | Automatically after retain |
During `reflect`, the agent checks these in priority order — mental models first (your curated knowledge), then observations (automatic synthesis), then raw facts.
---
## Observations: Automatic Knowledge Consolidation
### Evolution from Entity Summaries and Opinions
In Hindsight 0.3.0, we had two separate systems for synthesized knowledge:
- **Entity summaries**: Per-entity summaries synthesized from related facts. Generated automatically for frequently-mentioned entities — if "Alice" appeared in many facts, you'd get a summary like "Alice is a software engineer at Google who joined in 2020 and leads the search team." Objective and entity-scoped.
- **Opinions**: Beliefs formed during `reflect` operations, influenced by the bank's disposition traits. These captured subjective judgments with confidence scores, like "Python is best for data science" (confidence: 0.85).
Both systems served their purpose well, but they operated independently. Entity summaries were entity-centric, opinions were belief-centric, and neither captured the full picture of how knowledge evolves over time.
**Observations** unify these concepts into a single, more expressive system that captures patterns, preferences, and learnings as they emerge from accumulated evidence.
### What Are Observations?
Observations are **consolidated knowledge** synthesized from multiple facts. Unlike raw facts which are individual pieces of information, observations represent patterns and insights that emerge from accumulated evidence.
| Raw Facts | Observation |
|-----------|--------------|
| "Alice prefers Python" | "Alice is a Python-focused developer who values readability and simplicity, recommends type hints, and prefers pytest for testing" |
| "Alice dislikes verbose code" | |
| "Alice recommends type hints" | |
### Automatic Background Consolidation
After every `retain()` call, Hindsight's consolidation engine runs automatically:
1. **Analyzes new facts** against existing knowledge
2. **Detects patterns** across related information
3. **Synthesizes observations** that capture higher-order insights
4. **Tracks evidence** linking each observation to its supporting facts
```mermaid
graph LR
A[New Facts] --> B[Consolidation Engine]
B --> C{Existing Observation?}
C -->|Yes| D[Refine Observation]
C -->|No| E[Create Observation]
D --> F[Observations]
E --> F
```
### Evidence-Based Evolution
Observations evolve as new evidence arrives, capturing the full journey rather than just the current state:
| Time | Fact | Observation |
|------|------|--------------|
| Week 1 | "User loves React" | "User prefers React for frontend development" |
| Week 2 | "User praises React's component model" | "User is enthusiastic about React, particularly its component model" |
| Week 3 | "User switched to Vue and won't use React anymore" | "User was previously a React enthusiast who appreciated its component model, but has now switched to Vue" |
Notice how the final observation captures the **full journey** — not just "User prefers Vue" but the complete evolution. Your agent now understands:
- The user deliberately moved away from React (it wasn't ignorance)
- They previously appreciated React's component model (relevant context)
- Recommending React tutorials would be inappropriate
### Mission-Oriented Consolidation
Observations are influenced by your bank's **mission**. When you set a mission, the consolidation engine focuses on extracting knowledge that serves that purpose:
```python
client.create_bank(
bank_id="support-agent",
mission="You're a customer support agent - track customer preferences, "
"past issues, and communication styles."
)
```
With this mission, the engine prioritizes customer-relevant observations while skipping ephemeral details. Without a mission, it performs general-purpose consolidation.
---
## Mental Models: User-Curated Knowledge
While observations are created automatically, **mental models** give you explicit control over how your agent answers common questions.
### What Are Mental Models?
Mental models are **saved reflect responses** that you curate for your memory bank. When you create a mental model, Hindsight runs a reflect operation with your source query and stores the result. During future reflect calls, these pre-computed summaries are checked first.
```mermaid
graph LR
A[Create Mental Model] --> B[Run Reflect]
B --> C[Store Result]
C --> D[Future Queries]
D --> E{Match Found?}
E -->|Yes| F[Return Mental Model]
E -->|No| G[Run Full Reflect]
```
### Why Use Mental Models?
| Benefit | Description |
|---------|-------------|
| **Consistency** | Same answer every time for common questions |
| **Speed** | Pre-computed responses are returned instantly |
| **Quality** | Manually curated summaries you've reviewed |
| **Control** | Define exactly how key topics should be answered |
### Two Ways to Use Mental Models
Mental models work in two ways:
1. **Automatic via Reflect**: During `reflect` calls, the agent automatically checks mental models first. If a relevant one exists, it's used to inform the response.
2. **Direct Lookup**: Mental models work like a key-value store — you can retrieve them instantly by ID, bypassing the reflect reasoning loop entirely.
```python
# Direct lookup by ID — instant response, no LLM call
mental_model = client.get_mental_model(
bank_id="my-bank",
mental_model_id="team-communication"
)
print(mental_model.content) # Pre-computed answer, ready to use
```
This is useful when you know exactly what mental model you need and want the fastest possible response — no LLM reasoning required, just a simple database lookup.
### Creating Mental Models
```python
# Create a mental model for a common question
response = client.create_mental_model(
bank_id="my-bank",
name="Team Communication Preferences",
source_query="How does the team prefer to communicate?",
tags=["team"]
)
```
### Automatic Refresh
Mental models can automatically stay in sync with your observations:
```python
# Mental model that refreshes when observations update
response = client.create_mental_model(
bank_id="my-bank",
name="Project Status",
source_query="What is the current project status?",
trigger={"refresh_after_consolidation": True}
)
```
---
## Directives: Compliance and Guardrails
In addition to learning capabilities, **directives** provide hard rules that your agent must always follow during reflect operations. Unlike disposition traits which *influence* reasoning style, directives are absolute requirements that are enforced in every response.
Use directives for compliance, privacy, and safety constraints:
- "Never provide medical diagnoses or treatment advice"
- "Always respond in formal English"
- "Never share personally identifiable information"
- "Always cite sources when making factual claims"
Directives are injected into reflect prompts as hard constraints and are included in the response's `based_on` field. See the [Directives documentation](../developer/api/memory-banks#directives) for how to create and manage them.
---
## What Changes from 0.3.0
### Unified Memory Types
Opinions and entity summaries are now consolidated into observations:
```python
# 0.3.0 - opinions via types, entity summaries via include_entities
response = client.recall(
bank_id="my-bank",
query="What do you think about Python?",
types=["opinion"],
include_entities=True # to get entity summaries
)
# 0.4.0 - observations unify both
response = client.recall(
bank_id="my-bank",
query="What do you think about Python?",
types=["observation"]
)
```
### From Confidence Scores to Evidence Tracking
Opinions had numeric confidence scores (0.0-1.0). Observations instead track:
- **Supporting facts**: The evidence behind the observation
- **Last updated**: When the observation was last refined
- **Freshness**: Whether the observation reflects recent information
This shift from a single score to evidence tracking means your agent can explain *why* it believes something, not just *how confident* it is.
### Automatic vs On-Demand
Entity summaries were created automatically for top entities, but opinions only formed during `reflect`. Observations are always consolidated automatically after `retain`, ensuring knowledge stays current without explicit queries.
### Background Becomes Mission
The bank's `background` field has been renamed to `mission`. During the migration, your existing background text is automatically copied to the mission field — no action needed.
### Agentic Reflect
The `reflect` operation is now agentic — it reasons more deeply by iteratively retrieving memories and consulting mental models and observations before formulating a response. This makes reflect significantly smarter, especially for complex questions that require synthesizing information across multiple topics.
The trade-off is that reflect may take longer to respond. For latency-sensitive use cases, consider using `recall` directly when you just need to retrieve facts.
### Data Migration
**Important:** When upgrading to 0.4.0, existing opinions and entity summaries will be deleted. The consolidation engine will automatically create new observations from your existing facts. This is a one-time migration — your raw facts are preserved, and observations will be synthesized from them after the upgrade.
### Migration Checklist
**If you were using `types=["opinion"]` in recall:**
1. Update to `types=["observation"]`
2. Observations combine both entity-centric summaries and belief-based insights
**If you were using `include_entities=True` in recall:**
1. Entity summaries are now included in observations
2. Use `types=["observation"]` to retrieve them
**If you were relying on confidence scores:**
1. Use the `based_on` field to access supporting evidence
2. The number and recency of supporting facts indicates strength
**If you were setting `background` on banks:**
1. The field is now called `mission`
2. Existing values are migrated automatically
**No changes needed for reflect:**
Observations are automatically included in reflect responses via the `based_on` field.
---
## What's Next
These learning capabilities are the foundation for more sophisticated agent memory capabilities we're exploring:
- **Temporal reasoning**: Better understanding of how knowledge evolves over time
- **Selective consolidation**: Fine-grained control over what gets synthesized into observations
- **Consolidation insights**: Visibility into how observations are formed and updated
---
**Resources:**
- [Recall API](../developer/api/recall) — retrieve observations alongside facts
- [Reflect API](../developer/api/reflect) — responses now include supporting observations
- [Mental Models API](../developer/api/mental-models) — create and manage curated summaries
- [Observations Guide](../developer/observations) — deep dive into knowledge consolidation
- [Directives](../developer/api/memory-banks#directives) — hard rules for compliance and guardrails
- [Full Changelog](../changelog)
+3
View File
@@ -0,0 +1,3 @@
hindsight:
name: Hindsight Team
url: https://github.com/vectorize-io/hindsight
+1 -1
View File
@@ -4,7 +4,7 @@ sidebar_position: 3
# CLI Reference
The Hindsight CLI provides command-line access to memory operations and bank management. All commands follow the [OpenAPI specification](/api), so you can use `--help` on any command to see all available options.
The Hindsight CLI provides command-line access to memory operations and bank management. All commands follow the [OpenAPI specification](/api-reference), so you can use `--help` on any command to see all available options.
## Installation
+17 -5
View File
@@ -66,7 +66,6 @@ const config: Config = {
{
docs: {
sidebarPath: './sidebars.ts',
editUrl: 'https://github.com/vectorize-io/hindsight/tree/main/hindsight-docs/',
routeBasePath: '/',
// Only show "next" version in development or when INCLUDE_CURRENT_VERSION=true
// In production, only show released versions from versions.json
@@ -97,7 +96,14 @@ const config: Config = {
return config;
})(),
},
blog: false,
blog: {
showReadingTime: true,
blogTitle: 'Hindsight Blog',
blogDescription: 'Updates, insights, and deep dives into agent memory',
postsPerPage: 10,
blogSidebarTitle: 'Recent posts',
blogSidebarCount: 'ALL',
},
theme: {
customCss: './src/css/custom.css',
},
@@ -151,7 +157,8 @@ const config: Config = {
{
hashed: true,
docsRouteBasePath: '/',
indexBlog: false,
indexBlog: true,
blogRouteBasePath: '/blog',
highlightSearchTermsOnTargetPage: false,
},
],
@@ -207,8 +214,13 @@ const config: Config = {
className: 'navbar-item-cookbook',
},
{
type: 'doc',
docId: 'changelog/index',
to: '/blog',
position: 'left',
label: 'Blog',
className: 'navbar-item-blog',
},
{
to: '/changelog',
position: 'left',
label: 'Changelog',
className: 'navbar-item-changelog',
@@ -38,6 +38,33 @@ for opinion in response.results:
# [/docs:opinion-search]
# [docs:recall-opinions-only]
# Only retrieve opinions (beliefs and preferences)
opinions = client.recall(
bank_id="my-bank",
query="What are my preferences?",
types=["opinion"]
)
# [/docs:recall-opinions-only]
# [docs:recall-include-entities]
# Include entity summaries in recall results
response = client.recall(
bank_id="my-bank",
query="What do I know about Alice?",
include_entities=True,
max_entity_tokens=500
)
# Results include both facts and entity summaries
for result in response.results:
print(f"- {result.text}")
if hasattr(result, 'entity_summary'):
print(f" Entity: {result.entity_summary}")
# [/docs:recall-include-entities]
# [docs:opinion-disposition]
# Bank disposition affects how opinions are formed
# High skepticism = lower confidence, requires more evidence
@@ -39,6 +39,16 @@ await client.createBank('financial-advisor', {
// [/docs:bank-mission]
// [docs:bank-background]
// Legacy snippet for v0.3 docs (background renamed to mission in v0.4)
await client.createBank('legacy-bank', {
name: 'Legacy Example',
mission: `I'm a personal assistant helping a software engineer. I should track their
project preferences, coding style, and technology choices.`
});
// [/docs:bank-background]
// =============================================================================
// Cleanup (not shown in docs)
// =============================================================================
@@ -43,6 +43,17 @@ client.create_bank(
# [/docs:bank-mission]
# [docs:bank-background]
# Legacy snippet for v0.3 docs (background renamed to mission in v0.4)
client.create_bank(
bank_id="legacy-bank",
name="Legacy Example",
mission="""I'm a personal assistant helping a software engineer. I should track their
project preferences, coding style, and technology choices."""
)
# [/docs:bank-background]
# [docs:bank-with-disposition]
client.create_bank(
bank_id="architect-bank",
+27
View File
@@ -147,6 +147,33 @@ response = client.recall(
# [/docs:recall-tags-all]
# =============================================================================
# Legacy snippets for v0.3 docs (kept for backward compatibility)
# =============================================================================
# [docs:recall-opinions-only]
# Legacy: opinions replaced by observations in v0.4+
# Only retrieve opinions (beliefs and preferences)
opinions = client.recall(
bank_id="my-bank",
query="What are my preferences?",
types=["opinion"]
)
# [/docs:recall-opinions-only]
# [docs:recall-include-entities]
# Legacy: entity summaries replaced by observations in v0.4+
# Include entity summaries in recall results
response = client.recall(
bank_id="my-bank",
query="What do I know about Alice?",
include_entities=True,
max_entity_tokens=500
)
# [/docs:recall-include-entities]
# =============================================================================
# Cleanup (not shown in docs)
# =============================================================================
+1 -1
View File
@@ -5,7 +5,7 @@
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"build": "INCLUDE_CURRENT_VERSION=true docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
-7
View File
@@ -246,13 +246,6 @@ const sidebars: SidebarsConfig = {
],
},
],
changelogSidebar: [
{
type: 'doc',
id: 'changelog/index',
label: 'Changelog',
},
],
};
export default sidebars;

Some files were not shown because too many files have changed in this diff Show More