* feat: add TenantExtension auth to MCP endpoint
Replace static MCP_AUTH_TOKEN check with TenantExtension authentication,
making MCP use the same auth path as REST API.
- MCPMiddleware now calls tenant_extension.authenticate()
- Sets _current_schema from TenantContext for multi-tenant isolation
- Returns 401 on AuthenticationError (same as REST API)
- DefaultTenantExtension: no auth (local dev)
- ApiKeyTenantExtension: validates against env var
- CloudTenantExtension: HMAC + DB lookup (production)
Adds tests for middleware auth rejection, acceptance, and schema routing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Address PR review: backwards compatibility for MCP auth
- Keep MCP_AUTH_TOKEN env var for legacy MCP servers
- Add authenticate_mcp() method to TenantExtension base class
- Default implementation calls authenticate()
- Extensions can override to opt-out of MCP auth
- Add mcp_auth_disabled config option to ApiKeyTenantExtension
- Set HINDSIGHT_API_TENANT_MCP_AUTH_DISABLED=true to skip MCP auth
- Remove CloudTenantExtension from public docstring
- Add tests for legacy auth token and mcp_auth_disabled flag
- Update MCP docs with new auth configuration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add search_docs MCP tool for documentation search
Implements a new MCP tool that searches Hindsight documentation using
Vectorize RAG pipelines. The tool supports:
- Searching core (OSS) docs, cloud docs, or both
- Configurable number of results (1-10)
- Returns ranked results with URLs, similarity scores, and text snippets
New environment variables:
- HINDSIGHT_API_VECTORIZE_ORG_ID
- HINDSIGHT_API_VECTORIZE_API_TOKEN
- HINDSIGHT_API_VECTORIZE_CORE_PIPELINE_ID
- HINDSIGHT_API_VECTORIZE_CLOUD_PIPELINE_ID
- HINDSIGHT_API_VECTORIZE_API_BASE_URL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add documentation for search_docs MCP tool
- Add Vectorize environment variables to configuration.md
- Add search_docs tool to MCP server available tools
- Add reflect tool documentation (was missing)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add tests for search_docs MCP tool
Tests cover:
- DocsSource enum values and parsing
- _clean_text HTML stripping helper
- _search_vectorize_pipeline with mocked httpx
- Tool registration and function execution
- Source filtering (core/cloud/all)
- Result sorting by similarity
- Error handling for pipeline failures
- HTML cleaning in results
- Invalid source defaulting to 'all'
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Move search_docs to hindsight-cloud, add MCPExtension pattern
- Add MCPExtension base class for registering additional MCP tools
- Load MCPExtension in create_mcp_server when configured
- Remove search_docs tool (moved to hindsight-cloud CloudMCPExtension)
- Remove Vectorize config from hindsight-core
- Add tests for MCPExtension pattern
- Update docs to remove search_docs references
The MCPExtension pattern allows cloud (or any extension package) to
register additional MCP tools via:
HINDSIGHT_API_MCP_EXTENSION=package.module:ExtensionClass
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Address PR review feedback
- Remove CloudTenantExtension mention from MCPMiddleware docstring
- Fix docs: clarify that ApiKeyTenantExtension must be explicitly enabled
- Revert changes to versioned docs (0.3 and 0.4) - synced automatically on release
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Format mcp.py line length
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: support for codex and claude-code as llm
* Remove refactoring plan file
* Consolidate Anthropic tests into main LLM provider test suite
- Add Anthropic models (Sonnet, Opus, Haiku) to MODEL_MATRIX
- Remove separate test_anthropic_provider.py file
- All Anthropic models now tested with standard memory operations
* Add provider-specific default models
Each LLM provider now has a sensible default model that's used when
HINDSIGHT_API_LLM_MODEL is not explicitly set. This simplifies
configuration - users can specify just the provider and API key.
Changes:
- Add PROVIDER_DEFAULT_MODELS mapping in config.py
- Update config logic to use provider defaults for both global and
per-operation LLM configs
- Add comprehensive tests for provider default model selection
- Document provider defaults in models.md
Example usage:
export HINDSIGHT_API_LLM_PROVIDER=anthropic
export HINDSIGHT_API_LLM_API_KEY=sk-ant-xxx
# Automatically uses claude-sonnet-4-20250514
Provider defaults:
- openai: gpt-5-mini
- anthropic: claude-sonnet-4-20250514
- gemini: gemini-2.5-flash
- groq: openai/gpt-oss-120b
- ollama: gemma3:12b
- lmstudio: local-model
- vertexai: gemini-2.0-flash-001
- openai-codex: o3-mini
- claude-code: claude-sonnet-4-20250514
- mock: mock-model
* Update provider default models
- openai: gpt-5-mini -> o3-mini
- anthropic: claude-sonnet-4-20250514 -> claude-haiku-4-5-20251001
- openai-codex: o3-mini -> gpt-5.2-codex
- claude-code: claude-sonnet-4-20250514 -> claude-sonnet-4-5-20250929
Updated tests and documentation to reflect new defaults.
* Move OpenAI Codex and Claude Code setup to models.md
Moved detailed setup instructions for OpenAI Codex and Claude Code from
configuration.md to models.md where they better fit with model-specific
documentation.
Changes:
- Move "OpenAI Codex Setup" section from configuration.md to models.md
- Move "Claude Code Setup" section from configuration.md to models.md
- Add cross-reference tip in configuration.md pointing to models.md
- Update default model in Claude Code example to claude-sonnet-4-5-20250929
- Keep basic provider examples in configuration.md for quick reference
This makes the configuration.md page more focused on environment
variables while models.md contains provider-specific setup details.
* chore: remove dead code
* chore: remove extract_opinions from test and regenerate openapi
- Remove extract_opinions parameter from test_fact_extraction_analysis
- Regenerate OpenAPI spec after removing entity observations code
* chore: update generated files and apply formatting
- Regenerate Python and TypeScript client SDKs after main merge
- Apply ruff formatting to llm_wrapper.py
* fix: accept and filter deprecated 'opinion' fact type in recall
The dead code removal eliminated support for the 'opinion' fact type,
but existing clients may still pass it. Instead of rejecting it with
a ValueError, silently filter it out before validation to maintain
backward compatibility.
* feat: support vertex as llm provider
* fix
* fix: add uv index-strategy to resolve dependency conflicts with pytorch index
When using pytorch index for faster torch downloads in CI,
filelock dependency resolution was failing because pytorch index
only has older versions. Adding unsafe-best-match strategy allows
uv to search all configured indexes.
Also fix type checking warnings from ty.
* fix: add index-strategy to root pyproject.toml for workspace-level uv resolution
* chore: regenerate client SDKs after Vertex AI support
* chore: cleanup benchmarks runner with old flags
* fix tests
* fix: observations rely on source_memory_ids, no link copying
Observations no longer copy any memory_links from their source facts.
Instead, retrieval uses source_memory_ids to traverse:
- Entity connections: observation → source_memory_ids → unit_entities
- Semantic similarity: observations have their own embeddings
- Temporal proximity: observations have their own temporal fields
This avoids data duplication and fixes bidirectionality issues with
entity links being copied to observations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* test: update consolidation test for source_memory_ids behavior
Updated test_consolidation_creates_memory_links to test_consolidation_uses_source_memory_ids
to reflect the new behavior where observations use source_memory_ids instead of memory_links
for traversal.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: misc fixes for observations and mental models
* feat: improve graph retrieval for observations
- Update LinkExpansionRetriever to traverse through source_memory_ids
for observation entity connections (avoiding data duplication)
- Remove entity link copy from world facts to observations in consolidator
- Add tests for link expansion graph retrieval
- Add directives_applied field to ReflectResult
- Include user's other changes (CLI, docs, client updates)
* fix: CI test failures
- Add mental_model_id parameter to create_mental_model function
- Fix ToolCallTrace not including reason field from ToolCall
- Improve test_link_expansion_observation_graph_retrieval to wait for consolidation with retry
* chore: reduce link expansion log verbosity
* Revert "chore: reduce link expansion log verbosity"
This reverts commit 3ce759391cead1012157785fa78fef16ef9bfe3b.
* feat: add semantic/temporal/entity links as fallback in graph retrieval
- Add fallback query for semantic, temporal, and entity links from memory_links
- Check both directions (outgoing and incoming links)
- Weight fallback results at 0.5x to prioritize entity links via unit_entities
- Fixes graph retrieval returning 0 when data has cross-cluster temporal connections
* fix: enable observations fixture for link expansion test
- Add enable_observations fixture to ensure observations are created
- Increase wait time from 10 to 30 seconds for CI reliability
* feat: Record LLM token metrics via Prometheus
Wire up the existing token metrics infrastructure to actually record
token usage from LLM calls. The MetricsCollector already had
record_tokens() method and Prometheus counters (hindsight.tokens.input,
hindsight.tokens.output), but they were never being populated.
Changes:
- Import get_metrics_collector in llm_wrapper.py
- Call record_tokens() after successful LLM calls for:
- OpenAI/Groq (using response.usage.prompt_tokens, completion_tokens)
- Anthropic (using response.usage.input_tokens, output_tokens)
- Gemini (using response.usage_metadata.prompt_token_count, candidates_token_count)
- Add test file to verify token metrics are recorded
Note: Ollama's native API doesn't return token usage, so metrics
are not recorded for that provider.
The token metrics will now be available via /metrics endpoint:
- hindsight_tokens_input_total
- hindsight_tokens_output_total
* feat: add per-request token usage tracking to retain and reflect endpoints
- Add TokenUsage model with input_tokens, output_tokens, total_tokens
- Return usage metrics in retain response (sync operations only)
- Return usage metrics in reflect response
- Update Python, TypeScript, and Rust clients
- Add API documentation for usage fields
- Add changelog entry
* misc: add mcp integration tests and increase test coverage
* misc: add mcp integration tests and increase test coverage
* misc: add mcp integration tests and increase test coverage
* Fix main-methods.py: entities is a dict, use .items() and .canonical_name
* Migrate docs to use CodeSnippet components
- Convert quickstart.md, retain.md, recall.md, reflect.md, memory-banks.md to .mdx
- Use CodeSnippet to pull code from validated example scripts
- Add missing 'name' parameter to create_bank calls
- Fix main-methods.py entities iteration (dict not list)
- Remove retain-new.mdx demo file
* Migrate existing docs to match testing pattern with code snippet and add CLI tests to the CI
* Fix doc-id issue + add main-method tests
* CLI fixes
* Update openAPI json
* Fix rust build issues
* increase sleep time for Hindsight to process the document
* Added a polling sleep instead of fixed
* Delete immediately fails, so create the doc a earlier in the test to get the doc ready
* Add debug logs
* Remove debug logs
* Add documentation code validation system
- Create runnable example scripts in examples/api/ (19 files)
- Add CodeSnippet component for extracting marked sections
- Add raw-loader dependency for importing source files
- Create sample retain-new.mdx showing new approach
- Add README documenting coverage and gaps
* Fix wheel glob expansion in test-doc-examples CI job
* Fix CI issue
* Fix wheel path - uv build outputs to repo root dist/
* Fix: use explicit shell expansion for wheel install
* Fix: run cd in subshell so install runs from repo root
* Add documentation code validation CI job
- Use uv sync + uv run pattern (matches existing CI)
- Add requests to test dependencies for cleanup scripts
* Fix async API client usage in documents.py example
* Fix main-methods.py: RecallResult and ReflectFact don't have weight attribute
* Fix opinions.py: use actual API attributes instead of non-existent ones
* Fix example scripts: remove non-existent API attributes
- recall.py: remove .weight, fix entities iteration (dict not list)
- retain.mjs: remove result.async check
* bump pg0 0.11.x and improve documentation
* bump pg0 0.11.x and improve documentation
* bump pg0 0.11.x and improve documentation
* ci: test notebooks on ci
* ci: test notebooks on ci
* rm llms-full from repo
* formatting
* formatting
* feat: support for gemini-3-pro and gpt-5.2
* feat: support for gemini-3-pro and gpt-5.2
* feat: support for gemini-3-pro and gpt-5.2
* feat: support for gemini-3-pro and gpt-5.2
* feat: add local mcp server
* docs
* docs