diff --git a/hindsight-docs/blog/2026-02-09-resolving-memory-conflicts.md b/hindsight-docs/blog/2026-02-09-resolving-memory-conflicts.md index 2a8db62f..93d77dfd 100644 --- a/hindsight-docs/blog/2026-02-09-resolving-memory-conflicts.md +++ b/hindsight-docs/blog/2026-02-09-resolving-memory-conflicts.md @@ -2,7 +2,6 @@ title: How We Solved Memory Conflicts in Hindsight description: Learn how Hindsight handles contradictory information by tracking temporal evolution and preserving history in its memory consolidation system. authors: [hindsight] -tags: [engineering, memory-systems, conflict-resolution] image: /img/blog/2026-02-09/consolidation-pipeline.png date: 2026-02-09 --- diff --git a/hindsight-docs/blog/2026-02-13-version-0-4-11.md b/hindsight-docs/blog/2026-02-13-version-0-4-11.md new file mode 100644 index 00000000..d4f30179 --- /dev/null +++ b/hindsight-docs/blog/2026-02-13-version-0-4-11.md @@ -0,0 +1,116 @@ +--- +title: "What's new in Hindsight 0.4.11" +description: New features and improvements in Hindsight 0.4.11 +authors: [hindsight] +date: 2026-02-13 +--- + +Hindsight 0.4.11 focuses on production-ready deployments with improved flexibility and observability. + +- [**Hierarchical Configuration**](#hierarchical-configuration): Customize operational settings per memory bank. +- [**LiteLLM SDK Integration**](#litellm-sdk-integration): Direct API access without proxy server. +- [**Expanded Database Support**](#expanded-database-support): TimescaleDB pg_textsearch and additional Postgres extensions. +- [**OpenTelemetry Tracing**](#opentelemetry-tracing): Request-level observability with ready-to-use Grafana stack. +- [**MCP Mental Models**](#mcp-mental-models): Full lifecycle management via Model Context Protocol. +- [**Documentation Skill**](#documentation-skill): Build documentation-aware assistants. + + + +## Upgrade Today + +```bash +# Docker +docker pull ghcr.io/vectorize-io/hindsight:0.4.11 + +# Python SDK +pip install --upgrade hindsight-sdk +``` + +## Hierarchical Configuration + +You can now customize operational settings per memory bank. Configure retention behavior, extraction modes, and custom instructions for each bank independently. + +```bash +# Update retention settings for a specific bank +curl -X PATCH http://localhost:8888/v1/default/banks/my-bank/config \ + -H "Content-Type: application/json" \ + -d '{ + "updates": { + "retain_chunk_size": 1000, + "retain_extraction_mode": "custom", + "retain_custom_instructions": "Keep specific details about incidents, ignore complaints." + } + }' +``` + +Configuration cascades from system defaults (env vars) → tenant overrides → bank-specific settings. The bank config API is disabled by default for security—enable it with `HINDSIGHT_API_ENABLE_BANK_CONFIG_API=true`. + +Type-safe access prevents accidentally using global defaults when bank overrides exist. See the Configuration Guide for details on hierarchical configuration. + +## LiteLLM SDK Integration + +Hindsight already supported LiteLLM via proxy mode (routing requests through a LiteLLM proxy server). Now you can use LiteLLM directly via the Python SDK for embeddings and reranking—no proxy server needed. + +This means simpler setup, lower latency, and fewer infrastructure components while still getting LiteLLM's benefits: unified observability, model fallback, and multi-provider support. + +```bash +# Before: Required running a separate LiteLLM proxy server +export HINDSIGHT_API_EMBEDDINGS_PROVIDER=litellm +export HINDSIGHT_API_EMBEDDINGS_LITELLM_API_BASE=http://localhost:4000 + +# Now: Direct SDK access, no proxy needed +export HINDSIGHT_API_EMBEDDINGS_PROVIDER=litellm-sdk +export HINDSIGHT_API_EMBEDDINGS_LITELLM_SDK_API_KEY=your-api-key +export HINDSIGHT_API_EMBEDDINGS_LITELLM_SDK_MODEL=cohere/embed-english-v3.0 +``` + +The same applies to reranking with `HINDSIGHT_API_RERANKER_PROVIDER=litellm-sdk`. Use proxy mode when you need centralized rate limiting and caching; use SDK mode for simpler deployments. + +## Expanded Database Support + +PostgreSQL search support now includes: + +- **TimescaleDB pg_textsearch** for better full-text search in time-series workloads ([docker-compose example](https://github.com/vectorize-io/hindsight/tree/main/docker/docker-compose/pg_textsearch)) +- **vchord and pgvector** for flexible vector storage options ([docker-compose example](https://github.com/vectorize-io/hindsight/tree/main/docker/docker-compose/vchord)) +- Better support for external Postgres instances with custom configurations + +This gives you more deployment options whether you're running in the cloud, on-prem, or in specialized environments. + +## OpenTelemetry Tracing + +Hindsight now emits OpenTelemetry traces for all operations, providing request-level observability across distributed systems. Combined with actual LLM token usage (not estimates) and improved user-initiated attribution in request context, you get complete visibility into costs and performance. + +For local development, run `./scripts/dev/start-monitoring.sh` to launch a ready-to-use Grafana LGTM stack (Loki, Grafana, Tempo, Mimir) with pre-configured dashboards—traces, metrics, and logs in a single container. + +Async background operations are also properly attributed, making it easier to track usage and debug issues in production. + +## MCP Mental Models + +The Model Context Protocol server now supports full mental model lifecycle management. Agents using Hindsight via MCP can create, read, update, and delete mental models—not just query them. + +## Documentation Skill + +A new "docs" skill enables documentation-oriented capabilities, making it easier to build documentation-aware assistants that can access and reason over your documentation. + +## Reverse Proxy Support + +Running Hindsight behind a reverse proxy or at a non-root path? Configure your base path and Hindsight handles routing correctly, making it easier to integrate with existing infrastructure. + +See the [nginx docker-compose example](https://github.com/vectorize-io/hindsight/tree/main/docker/docker-compose/nginx) for a ready-to-use setup. + +## Other Updates + +- **Helm chart improvements**: Split TEI deployments for embeddings and reranking, PodDisruptionBudgets, per-component affinity controls, and fixed GKE port configuration. +- **Slim Docker image**: Slim image now includes tiktoken to prevent download errors. + + +## Feedback and Community + +Hindsight 0.4.11 is a drop-in replacement for 0.4.x with no breaking changes. + +Share your feedback: + +- [GitHub Discussions](https://github.com/vectorize-io/hindsight/discussions) +- [GitHub Issues](https://github.com/vectorize-io/hindsight/issues) + +For detailed changes, see the [full changelog](/changelog). diff --git a/hindsight-docs/src/pages/changelog.md b/hindsight-docs/src/pages/changelog.md index 2199199e..67275d36 100644 --- a/hindsight-docs/src/pages/changelog.md +++ b/hindsight-docs/src/pages/changelog.md @@ -8,6 +8,38 @@ This changelog highlights user-facing changes only. Internal maintenance, CI/CD, For full release details, see [GitHub Releases](https://github.com/vectorize-io/hindsight/releases). +## [0.4.11](https://github.com/vectorize-io/hindsight/releases/tag/v0.4.11) + +**Features** + +- Added support for LiteLLM SDK as an embeddings and reranking provider. ([`e408b7e`](https://github.com/vectorize-io/hindsight/commit/e408b7e)) +- Expanded Postgres search support with additional text/vector extensions, including TimescaleDB pg_textsearch and vchord/pgvector options. ([`d871c30`](https://github.com/vectorize-io/hindsight/commit/d871c30)) +- Added hierarchical configuration scopes (system, tenant, bank) for more flexible multi-tenant setup and overrides. ([`8d731f2`](https://github.com/vectorize-io/hindsight/commit/8d731f2)) +- Added reverse proxy/base-path support for running Hindsight behind a proxy. ([`93ddd41`](https://github.com/vectorize-io/hindsight/commit/93ddd41)) +- Added MCP tools to create, read, update, and delete mental models. ([`f641b30`](https://github.com/vectorize-io/hindsight/commit/f641b30)) +- Added a "docs" skill for agents/tools to access documentation-oriented capabilities. ([`dd1e098`](https://github.com/vectorize-io/hindsight/commit/dd1e098)) +- Added an OpenClaw configuration option to skip recall/retain for specific providers. ([`fb7be3e`](https://github.com/vectorize-io/hindsight/commit/fb7be3e)) + +**Improvements** + +- Improved LiteLLM gateway model configuration for more reliable provider/model selection. ([`7d95a00`](https://github.com/vectorize-io/hindsight/commit/7d95a00)) +- Exposed actual LLM token usage in retain results to improve cost/usage visibility. ([`83ca669`](https://github.com/vectorize-io/hindsight/commit/83ca669)) +- Added user-initiated attribution to request context to improve async task and usage attribution. ([`90be7c6`](https://github.com/vectorize-io/hindsight/commit/90be7c6)) +- Added OpenTelemetry tracing for improved request traceability and observability. ([`69dec8e`](https://github.com/vectorize-io/hindsight/commit/69dec8e)) +- Helm chart: split TEI embedding and reranker into separate deployments for independent scaling and rollout. ([`43f9a8b`](https://github.com/vectorize-io/hindsight/commit/43f9a8b)) +- Helm chart: added PodDisruptionBudgets and per-component affinity controls for more resilient scheduling. ([`9943957`](https://github.com/vectorize-io/hindsight/commit/9943957)) + +**Bug Fixes** + +- Fixed a recursion issue in memory retention that could cause failures or runaway memory usage. ([`4f11210`](https://github.com/vectorize-io/hindsight/commit/4f11210)) +- Fixed Reflect API serialization/schema issues for "based_on" so reflections are returned and stored correctly. ([`f9a8a8e`](https://github.com/vectorize-io/hindsight/commit/f9a8a8e)) +- Improved MCP server compatibility by allowing extra tool arguments when appropriate and fixing bank ID resolution priority. ([`7ee229b`](https://github.com/vectorize-io/hindsight/commit/7ee229b)) +- Added missing trust_code environment configuration support. ([`60574ee`](https://github.com/vectorize-io/hindsight/commit/60574ee)) +- Hardened the MCP server with fixes to routing/validation and more accurate usage metering. ([`e798979`](https://github.com/vectorize-io/hindsight/commit/e798979)) +- Fixed the slim Docker image to include tiktoken to prevent runtime tokenization errors. ([`6eec83b`](https://github.com/vectorize-io/hindsight/commit/6eec83b)) +- Fixed MCP operations not being tracked correctly for usage metering. ([`888b50d`](https://github.com/vectorize-io/hindsight/commit/888b50d)) +- Helm chart: fixed GKE deployments overriding the configured HINDSIGHT_API_PORT. ([`03f47e2`](https://github.com/vectorize-io/hindsight/commit/03f47e2)) + ## [0.4.10](https://github.com/vectorize-io/hindsight/releases/tag/v0.4.10) **Features** diff --git a/hindsight-integrations/openclaw/src/index.test.ts b/hindsight-integrations/openclaw/src/index.test.ts new file mode 100644 index 00000000..f0eff7bc --- /dev/null +++ b/hindsight-integrations/openclaw/src/index.test.ts @@ -0,0 +1,83 @@ +import { describe, it, expect } from 'vitest'; + +/** + * Unit tests for the memory feedback loop fix. + * Verifies that and tags + * are stripped from content before RETAIN to prevent duplicates. + */ +describe('Memory Tag Stripping', () => { + /** + * Simulates the tag stripping logic from agent_end hook + */ + function stripMemoryTags(content: string): string { + // Strip plugin-injected memory tags to prevent feedback loop + content = content.replace(/[\s\S]*?<\/hindsight_memories>/g, ''); + content = content.replace(/[\s\S]*?<\/relevant_memories>/g, ''); + return content; + } + + it('should strip simple hindsight_memories tags', () => { + const input = 'User: Hello\n\nRelevant memories here...\n\nAssistant: How can I help?'; + const expected = 'User: Hello\n\nAssistant: How can I help?'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should strip relevant_memories tags', () => { + const input = 'Before\n\nSome data\n\nAfter'; + const expected = 'Before\n\nAfter'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should strip multiple hindsight_memories blocks', () => { + const input = 'Start\n\nBlock 1\n\nMiddle\n\nBlock 2\n\nEnd'; + const expected = 'Start\n\nMiddle\n\nEnd'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should handle multiline memory blocks with JSON', () => { + const input = 'User: What is the weather?\n\nRelevant memories:\n{\n "memory": "User likes sunny weather"\n}\n\nAssistant: Let me check'; + const expected = 'User: What is the weather?\n\nAssistant: Let me check'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should preserve content without memory tags', () => { + const input = 'User: Hello\nAssistant: Hi there!'; + const expected = 'User: Hello\nAssistant: Hi there!'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should handle nested-like content without actual nesting', () => { + const input = 'Outer start\n\nSafe content\n\nOuter end'; + const expected = '\nSafe content\n'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should strip both tag types in same content', () => { + const input = 'A\n\nH mem\n\nB\n\nR mem\n\nC'; + const expected = 'A\n\nB\n\nC'; + const result = stripMemoryTags(input); + expect(result).toBe(expected); + }); + + it('should handle real-world agent conversation with injected memories', () => { + const input = '[role: system]\n\nRelevant memories from past conversations (score 1=highest, prioritize recent when conflicting):\n[\n {\n "content": "User prefers dark mode",\n "relevance_score": 0.95\n }\n]\n\nUser message: How do I enable dark mode?\n\n[system:end]\n\n[role: user]\nHow do I enable dark mode?\n[user:end]\n\n[role: assistant]\nBased on your previous preference, let me help you enable dark mode.\n[assistant:end]'; + + const result = stripMemoryTags(input); + + // Should not contain the memory tags + expect(result).not.toContain(''); + expect(result).not.toContain(''); + expect(result).not.toContain('Relevant memories from past conversations'); + + // Should still contain the actual conversation + expect(result).toContain('[role: user]'); + expect(result).toContain('How do I enable dark mode?'); + expect(result).toContain('[role: assistant]'); + }); +});