* 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
* feat(mcp): Add multi-bank access and new MCP tools
Enables orchestrator agents to access multiple memory banks from a
single MCP connection, with new tools for bank management.
## New MCP Tools
- `reflect` - Thoughtful analysis using bank's personality and memories
- `list_banks` - Discover all available memory banks
- `create_bank` - Create new banks programmatically
## Multi-Bank Access
- Added optional `bank_id` parameter to `retain`, `recall`, `reflect`
- Allows cross-bank operations from a single MCP session
- Defaults to session bank if not specified
## Claude Code Compatibility
- Enabled `stateless_http=True` for proper Claude Code integration
- Responses now include `bank_id` for transparency
## Documentation
- Added docker-compose.example.yml with env var substitution
- Added HINDSIGHT-DOCKER.md setup guide with volume persistence docs
- Updated .gitignore to exclude local docker-compose.yml
## Use Case
Orchestrator agents can now:
- Maintain a private meta-orchestration bank
- Access shared project knowledge banks
- Query across banks for cross-context insights
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Address PR review feedback: remove docker files, improve reflect description
- Remove HINDSIGHT-DOCKER.md and docker-compose.example.yml per reviewer request
- Improve reflect tool description with clearer guidance for AI agents:
- Added "WHEN TO USE THIS TOOL" section
- Added "EXAMPLES OF GOOD QUERIES" with concrete use cases
- Added "HOW IT DIFFERS FROM RECALL" to clarify when to use each tool
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Load operation validator extension in main entry point
Enable the operation validator extension to be loaded from environment
configuration and passed to MemoryEngine, allowing pre/post operation
hooks for usage metering, rate limiting, and audit logging.
* Fix reflect background task authentication and add internal flag
- Pass API key to background opinion storage task for proper auth
- Add internal flag to RequestContext for tracking internal operations
- Background opinion storage now authenticates correctly with tenant
* Add api_key_id to RequestContext for usage tracking
- Add api_key_id field to RequestContext to track which API key was used
- Enables per-API-key usage analytics in the metering system
* Fix HTTP error handling for authentication and validation errors
- Add status_code parameter to ValidationResult and OperationValidationError
- Convert OperationValidationError to HTTPException with proper status codes
- Fix authentication errors to return 401 instead of raising internal errors
- Re-raise HTTPException in exception handlers to prevent swallowing errors
* Fix AuthenticationError handling in memory engine
- Raise AuthenticationError from memory_engine._authenticate_tenant instead
of HTTPException so unit tests pass
- Add AuthenticationError handling in HTTP layer to convert to 401 responses
- Fixes failing TestMemoryEngineTenantAuth tests
* Add global exception handler for AuthenticationError
Returns proper 401 status code for all authentication failures
across all endpoints, not just the ones with explicit handlers.
* Simplify exception handling: use global AuthenticationError handler
- Remove redundant individual exception handlers
- Add 'except AuthenticationError: raise' before generic Exception handlers
to let global handler process auth errors uniformly
* Refactor background tasks to use tenant_id instead of api_key
This makes the core more generic - it passes tenant_id (which is
extension-agnostic) rather than api_key (which is cloud-specific).
- Add tenant_id field to RequestContext
- Pass tenant_id instead of api_key to background tasks
- Extensions can check internal=True with tenant_id to bypass normal auth
* Fix exception propagation: include HTTPException in re-raise
After cleanup of redundant exception handlers, 404 errors were
returning 500 because HTTPException was caught by the generic
except Exception handler. Fixed by combining AuthenticationError
and HTTPException in the re-raise pattern.
The MCP server's lifespan was not being properly chained with the
FastAPI app's lifespan, causing the MCP server to not start/stop
correctly when mounted as a sub-application.
Changes:
- Create MCP app before FastAPI app to access its lifespan
- Chain MCP lifespan context with FastAPI's lifespan context
- Ensures MCP server lifecycle is properly managed
This fix is required for the MCP server to function correctly when
used with Claude Code and other MCP clients.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>