Commit graph

42 commits

Author SHA1 Message Date
Nicolò Boschi
60574ee08f
fix: add trust_code env config (#347)
* fix: add trust_code env config

* doc
2026-02-11 17:06:59 +01:00
Nicolò Boschi
7d95a002c7
fix: improve model configuration for litellm gateway (#345)
* fix: improve model configuration for litellm gateway

* fix: add missing config imports for Cohere and LiteLLM providers

Add missing DEFAULT_* and ENV_* constants to cross_encoder.py and embeddings.py imports:
- DEFAULT_RERANKER_COHERE_MODEL
- DEFAULT_LITELLM_API_BASE
- DEFAULT_RERANKER_LITELLM_MODEL
- DEFAULT_EMBEDDINGS_COHERE_MODEL
- DEFAULT_EMBEDDINGS_LITELLM_MODEL
- ENV_RERANKER_COHERE_MODEL

This fixes NameError failures in test-api, test-hindsight-all, and test-upgrade CI jobs.
2026-02-11 11:24:26 +01:00
Nicolò Boschi
69dec8ec34
feat: add otel traceability (#330)
* feat: add comprehensive OpenTelemetry tracing

- Add tool execution spans for reflect operations
- Add tool call information (names, params) to spans
- Change verification scope from 'test' to 'verification'
- Add hindsight.reflect_generation span for done() processing
- Implement no-op tracer for improved code readability
- Update documentation for OTEL configuration
- Resolve merge conflicts from rebase

* fix: properly serialize Pydantic models in span recording

- Add _serialize_for_span() helper to handle Pydantic models
- Update all providers to use the helper function
- Fixes test failures with 'Object of type X is not JSON serializable'

* feat: add Grafana LGTM stack for unified local observability

Add Grafana LGTM (Loki, Grafana, Tempo, Mimir) as the recommended
local development observability stack. This provides traces, metrics,
and logs in a single Docker container instead of separate tools.

Changes:
- Add scripts/dev/grafana/ with docker-compose and README
- Add scripts/dev/start-grafana.sh startup script
- Update .env.example to reference Grafana LGTM
- Update configuration docs to emphasize Grafana LGTM as primary option
- Reorder OTLP backend list to show Grafana LGTM first

Benefits:
- Single container vs multiple separate tools (Jaeger, SigNoz, etc.)
- ~515MB image with full observability stack
- Compatible with existing OTLP configuration
- Simpler local development setup

* chore: remove SigNoz scripts and references

Remove SigNoz observability stack in favor of Grafana LGTM as the
sole recommended local development tracing solution.

Changes:
- Delete scripts/dev/signoz/ directory and all SigNoz configurations
- Delete scripts/dev/start-signoz.sh startup script
- Remove SigNoz references from .env.example
- Remove SigNoz from OTLP backends list in configuration docs

Grafana LGTM provides the same capabilities (traces, metrics, logs)
in a simpler single-container setup.

* feat: add consolidation span hierarchy for tracing

Add parent-child span structure for consolidation operations:
- hindsight.consolidation: Parent span for each memory being processed
- hindsight.consolidation_recall: Child span for finding related observations
- LLM call span: Automatically created by LLM provider (scope="consolidation")

This enables detailed timing breakdown in Grafana Tempo:
- Total consolidation time per memory
- Time spent in recall
- Time spent in LLM call
- Time spent executing actions (create/update)

All consolidation tests pass (31/31).

* feat: add Prometheus metrics and GenAI dashboard to Grafana stack

Add comprehensive metrics and dashboarding to the Grafana LGTM stack:

Metrics Collection:
- Configure Prometheus to scrape Hindsight API /metrics endpoint
- Scrape interval: 10 seconds
- Targets hindsight-api on host.docker.internal:8888

GenAI Dashboard:
- Pre-configured dashboard with 6 panels:
  - LLM call rate (by provider/model)
  - LLM call duration (p50/p95 by scope)
  - Token usage - input tokens/sec by scope
  - Token usage - output tokens/sec by scope
  - Operations rate (retain/recall/reflect/consolidation)
  - Operation duration p95 by operation type

Configuration:
- Mount prometheus.yml for metrics scraping
- Mount dashboards directory for auto-provisioning
- Add host.docker.internal mapping for container->host access
- Dashboard provisioning with auto-reload every 10s

Documentation:
- Updated README with metrics viewing instructions
- Added PromQL query examples
- Documented dashboard access and navigation

This provides full observability: traces (Tempo) + metrics (Prometheus/Mimir) + dashboards (Grafana)

* refactor: merge Grafana setup into existing monitoring stack

Consolidate the separate scripts/dev/grafana/ setup into the existing
scripts/dev/monitoring/ stack, using Grafana LGTM (Loki, Grafana, Tempo, Mimir).

Changes:
- Remove separate scripts/dev/grafana/ directory and start-grafana.sh
- Rewrite scripts/dev/monitoring/start.sh to use Docker + Grafana LGTM
  (was: download native Prometheus/Grafana binaries)
- Add docker-compose.yaml for Grafana LGTM container
- Add prometheus.yml for scraping Hindsight API metrics
- Mount existing dashboards from monitoring/grafana/dashboards/
- Add comprehensive README.md

Benefits:
- Single unified monitoring command: ./scripts/dev/start-monitoring.sh
- Uses existing dashboard files (hindsight-operations, hindsight-llm, hindsight-api-service)
- Simpler setup: Docker-based vs downloading/running native binaries
- Full observability: traces + metrics + logs + dashboards in one container
- Standard ports: Grafana on 3000, OTLP on 4317/4318

Architecture:
- Grafana LGTM container (~515MB) provides all components
- Dashboards auto-provisioned from monitoring/grafana/dashboards/
- Prometheus scrapes host.docker.internal:8888/metrics
- Shared hindsight-network for future service-to-service tracing

* fix: run monitoring stack in foreground for easy Ctrl+C stop

Change docker-compose from detached (-d) to foreground mode.
Users can now stop the stack with Ctrl+C instead of needing
to run docker-compose down separately.

* fix: remove invalid home dashboard path and obsolete version field

- Remove GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH environment variable
  (was pointing to wrong path causing 'Failed to load home dashboard' error)
- Remove obsolete 'version' field from docker-compose.yaml
  (docker-compose v2+ doesn't require version field)

* fix: load Hindsight dashboards in Grafana LGTM

Mount Hindsight dashboard JSON files and custom provisioning config
to make dashboards visible in Grafana.

Changes:
- Mount hindsight-operations.json, hindsight-llm.json, hindsight-api-service.json to /otel-lgtm/
- Create grafana-dashboards.yaml with all dashboard providers (default + Hindsight)
- Mount custom provisioning config to override LGTM default

All 3 Hindsight dashboards now appear in Grafana UI with metrics
from Prometheus scraping the Hindsight API /metrics endpoint.

* fix: configure Prometheus to scrape Hindsight API metrics

Update prometheus.yml to include both OTLP receiver config (from LGTM)
and scrape_configs for pulling metrics from Hindsight API.

Changes:
- Mount prometheus.yml to /otel-lgtm/prometheus.yaml (where LGTM reads it)
- Add scrape_configs section to pull from host.docker.internal:8888/metrics
- Keep OTLP receiver configuration for trace metrics
- Set scrape_interval to 5s

Verified: Prometheus now successfully scrapes hindsight_llm_calls_total
and other Hindsight metrics. Dashboards now show live data!

* feat: add comprehensive tracing for recall and improve reflect/mental_model_refresh spans

- Add recall operation tracing with parent-child span hierarchy
  - Parent: hindsight.recall with attributes (bank_id, query, fact_types, etc.)
  - Children: recall_embedding, recall_retrieval, recall_fusion, recall_rerank
  - Fixed context propagation using start_as_current_span()

- Improve reflect tracing spans
  - Remove reflect_generation spans, use reflect instead
  - Change done() tool processing to hindsight.reflect_tool_call

- Fix mental_model_refresh span nesting
  - Add _skip_span parameter to reflect_async to avoid duplicate hindsight.reflect spans
  - Mental model refresh now has clean span hierarchy without nested reflect parent

- Add comprehensive tracing verification tests
  - Test span hierarchy and attributes for all operations
  - Verify parent-child relationships
  - 5 passing tests covering recall, reflect, consolidation, and mental_model_refresh

* refactor: remove redundant is_tracing_enabled() checks

- Remove all is_tracing_enabled() conditional checks before tracing calls
- NoOpTracer/NoOpSpan handle disabled tracing automatically
- Simplify code by always calling tracer methods directly
- Fix NoOpTracer.start_as_current_span() to yield NoOpSpan instead of None

Changes:
- memory_engine.py: Remove 5 is_tracing_enabled checks in recall spans
- agent.py: Remove 2 is_tracing_enabled checks in reflect tool spans
- tracing.py: Fix NoOpTracer context manager to yield proper NoOpSpan

This eliminates ~50 lines of redundant conditional code while maintaining
identical behavior.

* docs: simplify distributed tracing section in monitoring.md

- Make tracing documentation more concise
- Focus on span hierarchy and attributes
- Remove verbose troubleshooting and performance sections
- Keep configuration.md for env vars only
2026-02-10 12:20:48 +01:00
Nicolò Boschi
749478d9f9
feat: improve openclaw and hindisght-embed params (#279)
* feat(openclaw): use hindsight-embed profiles for configuration

- Replace manual config file writing with hindsight-embed configure command
- Create and use 'openclaw' profile for all hindsight-embed operations
- Add support for openai-codex and claude-code providers
- Map special providers (openai-codex -> openai, claude-code -> anthropic)
- Simplify client by removing getEnv() method
- All CLI commands now use --profile openclaw flag
- Add get_cli_profile_override() function to cli.py for profile_manager

* feat: improve openclaw and hindisght-embed params

* feat: improve openclaw and hindisght-embed params

* feat(embed): remove daemon.lock, add profile-specific logs and --merge flag

* fix(embed): restore metadata.json functionality for profile tests

- Restore ProfileMetadata class and metadata tracking
- Fix profile manager create_profile to support both (name, config) and (name, port, config) signatures
- Auto-allocate ports when not provided in configure command
- Fix --profile flag parsing (was consumed by parent parser)
- All 47 hindsight-embed tests now pass

* fix(embed): support HINDSIGHT_EMBED_LLM_* env vars for backward compatibility

- configure command now accepts both HINDSIGHT_API_LLM_* and HINDSIGHT_EMBED_LLM_* prefixes
- Fixes test_configure_without_profile_flag test
- All 47 hindsight-embed tests pass

* style(embed): apply ruff formatting to cli.py

* fix(embed): simplify test.sh to verify hindsight-embed availability via uv

Removed CLI installation code from smoke test. The test now simply verifies
that hindsight-embed command is available via `uv run`, which is all that's
needed for CI to pass. This fixes the test-embed check that was failing with
"ERROR: hindsight CLI not found".

* fix(embed): remove hindsight-embed availability check from test.sh

The verification step was failing in CI because hindsight-embed --version
doesn't work without configuration. Since pytest tests already verify the
package is installed (47 tests passed), we don't need this check. The smoke
test itself will verify functionality by running retain/recall commands.

* chore(embed): add comment to test.sh to trigger CI

* fix(embed): use HINDSIGHT_API_LLM_* env vars consistently

Remove support for HINDSIGHT_EMBED_LLM_* variables to align with
the standard HINDSIGHT_API_LLM_* naming convention used across the codebase.

Changes:
- Update get_config() to only check HINDSIGHT_API_LLM_* variables
- Update _do_configure_from_env() to remove HINDSIGHT_EMBED_LLM_* fallbacks
- Update test.sh to check for HINDSIGHT_API_LLM_API_KEY
- Update CI workflow (test-embed job) to set HINDSIGHT_API_LLM_* env vars
2026-02-03 09:39:04 +01:00
Nicolò Boschi
6c7f057e9d
feat(embed): add hindisght-embed profiles (#277)
* feat(embed): add hindisght-embed profiles

* ci: run pytest tests for hindsight-embed in CI

- Add pytest test run step to test-embed job
- This ensures profile tests (37 tests) are run in CI
- Smoke test still runs after pytest tests

* feat(embed): use 'default' profile name consistently

- Configure command now shows "Profile 'default' configured successfully!"
- Profile list shows "default" instead of empty string
- Profile show displays "default" consistently
- All output now uses "default" label for backward-compatible config
- Added port display for default profile in all commands

* fix(embed): replace requests with httpx in profile_manager

- Use httpx.Client() instead of requests.get() for daemon health check
- Update test mock to use httpx.Client instead of requests.get
- Fixes ModuleNotFoundError in CI (requests not in dependencies)
2026-02-02 14:38:06 +01:00
Nicolò Boschi
1499ce5549
feat: print version during startup (#275)
* feat: print version during startup

* feat: print version during startup
2026-02-02 12:40:45 +01:00
Nicolò Boschi
f4f86e3842
fix: deadlock in worker polling (#250)
* fix: deadlock in worker polling

* fix: deadlock in worker polling

* fixes
2026-01-30 11:09:29 +01:00
Nicolò Boschi
ab5e31f203
chore: remove dead code (#245)
* 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.
2026-01-30 09:16:32 +01:00
Nicolò Boschi
c2ac7d0440
feat: support vertex as llm provider (#233)
* 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
2026-01-29 16:13:57 -05:00
Nicolò Boschi
3f211f0729
feat: add more config options for llm retries (#234) 2026-01-29 17:50:43 +01:00
Nicolò Boschi
c16ccc2c22
fix: hindsight-embed on macos crashes (#228)
* fix: hindsight-embed on macos crashes

* fix: hindsight-embed on macos crashes

* fix(doc): improve docs versioning and release

* fix(doc): improve docs versioning and release

* fixes
2026-01-29 16:57:51 +01:00
Nicolò Boschi
b43ef98686
feat: consolidation performance benchmark and optimization (#227) 2026-01-29 11:24:15 +01:00
Nicolò Boschi
67c47881cb
fix: add defensive error handling to PyTorch device detection (#221)
* fix: include correct __version__ in python packages

* fix(embed): force CPU mode for local models in daemon to prevent XPC crashes

Adds HINDSIGHT_API_EMBEDDINGS_LOCAL_FORCE_CPU and HINDSIGHT_API_RERANKER_LOCAL_FORCE_CPU
environment variables to force CPU-only operation for local sentence-transformer models.

This prevents XPC_ERROR_CONNECTION_INVALID crashes on macOS when running in daemon mode.
The issue occurs because PyTorch's MPS (Metal Performance Shaders) backend has unstable
XPC connections in background processes, leading to C++ assertion failures that Python
exception handlers cannot catch.

Changes:
- config.py: Add ENV_*_FORCE_CPU constants and config dataclass fields
- embeddings.py: Add force_cpu parameter to LocalSTEmbeddings constructor
- cross_encoder.py: Add force_cpu parameter to LocalSTCrossEncoder constructor
- main.py: Set force CPU env vars in daemon mode, add fields to config constructor

The daemon mode automatically enables force CPU for both embeddings and reranker,
while normal mode allows hardware acceleration (GPU/MPS) as before.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add defensive error handling to PyTorch device detection

Wraps all PyTorch device detection code (torch.cuda.is_available()
and torch.backends.mps.is_available()) in try-except blocks that
gracefully fall back to CPU if any errors occur.

This complements PR #218's force_cpu configuration by ensuring the
code works reliably in all environments without configuration:
- CI environments with CPU-only PyTorch builds
- Systems without proper GPU/MPS support
- Partial or misconfigured PyTorch installations

The defensive approach prevents startup failures while still taking
advantage of GPU/MPS acceleration when available and force_cpu is
not explicitly set.

Changes:
- embeddings.py: Added try-except in initialize() and _reinitialize_model_sync()
- cross_encoder.py: Added try-except in initialize() and _reinitialize_model_sync()

* refactor: use get_config() for embeddings and reranker force_cpu

Changes create_embeddings_from_env() and create_cross_encoder_from_env()
to read configuration via get_config() instead of directly accessing
os.environ. This ensures consistency across the codebase and properly
respects the force_cpu configuration set by daemon mode.

Changes:
- embeddings.py: Use config.embeddings_local_model and config.embeddings_local_force_cpu
- cross_encoder.py: Use config.reranker_local_model and config.reranker_local_force_cpu
- Both: Use get_config() for provider, tei_url, and other config fields
- Note: Some fields not in config (like max_concurrent for local reranker) still read from os.environ

This fixes the issue where force_cpu was read inconsistently from environment
variables instead of using the centralized config system.

* test: clear config cache in test_create_from_env

Fixes test failure caused by cached config not picking up
environment variable changes in test. The test now calls
clear_config_cache() before and after patching os.environ
to ensure the factory function reads the test's env vars.

* refactor: add reranker_local_max_concurrent to config system

Adds reranker_local_max_concurrent to HindsightConfig dataclass
and removes the workaround in create_cross_encoder_from_env() that
was reading it directly from os.environ.

Changes:
- config.py: Add reranker_local_max_concurrent field to dataclass and from_env()
- main.py: Add reranker_local_max_concurrent to manual config constructor
- cross_encoder.py: Use config.reranker_local_max_concurrent instead of os.environ

This completes the refactoring to use the centralized config system
for all reranker configuration.

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-28 18:14:54 +01:00
Nicolò Boschi
2b72e1fd68
feat: support different default pg schema (#222)
* feat: support different default pg schema

* feat: support different default pg schema
2026-01-28 18:14:44 +01:00
Nicolò Boschi
3172e99cab
feat: add custom extraction prompt (#213)
* feat: add custom extraction prompt

* feat: add custom extraction prompt

* test
2026-01-28 13:54:52 +01:00
Nicolò Boschi
90e370ef35
fix: misc fixes for observations and mental models (#209)
* 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
2026-01-27 15:37:57 +01:00
Nicolò Boschi
5b52a84fff
chore: internal renames (#204)
This commit renames the terminology across the entire codebase:
- "mental models" (fact_type='mental_model' in memory_units) → "observations"
- "reflections" table (stored reflect responses) → "mental_models"

Changes include:
- Database migration to rename tables, indexes, and constraints
- API endpoints: /reflections → /mental-models, /mental-models → /observations
- Config: ENABLE_MENTAL_MODELS → ENABLE_OBSERVATIONS
- Response models and Pydantic classes
- Reflect agent tools and prompts
- Control plane UI and routes
- Documentation and examples
- Regenerated OpenAPI spec and client SDKs (Python, TypeScript)
- Rust CLI: reflection commands → mental-model commands
- LiteLLM: updated fact_types documentation
2026-01-27 09:53:28 +01:00
Nicolò Boschi
8e39cb7bc8
fix: improve mental model consolidation (#197)
* fix: improve mental model consolidation

* fix skill names

* fixes

* fix: add missing list_tenants to test mocks and update CLI for async refresh
2026-01-26 09:54:25 +01:00
Nicolò Boschi
9db64ecda3
feat: revisit mental models, directives and reflections (#179)
* chore: run benchmarks with reflect mode

* chore: run benchmarks with reflect mode

* fixes

* new mm

* bunch of fixes

* initial commit

* fixes

* fixes

* fixes

* fix: sometimes memories gets extracted in the wrong language
2026-01-22 17:13:16 +01:00
Nicolò Boschi
4c792400c1
feat: new 'worker' service (#176)
* feat: new 'worker' service

* doc

* docs

* tests
2026-01-20 10:17:56 +01:00
Chris Bartholomew
870cfccabb
Add structured JSON logging support (#170)
* Add structured JSON logging support

Add HINDSIGHT_API_LOG_FORMAT environment variable to configure log output
format. Options are "text" (default, human-readable) and "json" (structured).

JSON format outputs logs with a "severity" field that cloud logging systems
can parse for proper log level categorization. Also writes to stdout instead
of stderr so log levels are correctly interpreted.

* Rename GCPJsonFormatter to JsonFormatter
2026-01-19 09:01:24 +01:00
Nicolò Boschi
4f2833873c
feat: introduce mental models (#132)
* mental models

* DRAFT: refactor entity observations

* fix db patch

* agentic

* agentic

* reflect agent

* new style

* more

* fix ci

* fix

* fix
2026-01-16 11:16:41 +01:00
Nicolò Boschi
fa53917c63
feat: support custom url for openai embeddings & cohere (#150)
* feat: support custom url for openai embeddings & cohere

* feat: support custom url for openai embeddings & cohere
2026-01-13 14:01:44 +01:00
Nicolò Boschi
59913086be
fix: batch queries on recall (#149)
* fix: batch queries on recall

* fix: batch queries on recall
2026-01-13 13:20:22 +01:00
Nicolò Boschi
7935b0accd
fix: improve mpfp retrieval (#146)
* fix: improve mpfp retrieval

* fix: improve mpfp retrieval

* fix: improve embeddings service performances

* fix: improve embeddings service performances

* fix: improve embeddings service performances

* fix: improve embeddings service performances
2026-01-12 18:58:05 +01:00
Nicolò Boschi
eb2702bcba
misc: performance improvements (#140)
* misc: performance improvements

* misc: performance improvements

* misc: performance improvements
2026-01-09 14:47:20 +01:00
Nicolò Boschi
a6798f7e2a
fix: improve tei client parameters (#137)
* fix: improve tei client parameters

* fix: improve tei client parameters

* fix: improve tei client parameters
2026-01-09 11:31:22 +01:00
Nicolò Boschi
fb31a35a86
feat: retain modes (#136)
* feat: retain modes

* fix db patch
2026-01-09 11:30:36 +01:00
Nicolò Boschi
ba99b4422a
fix: misc perf improvements (#133)
* fix: misc perf improvements

* more tests

* fix test

* fix: update test files for new extract_facts_from_text signature

- Replace test_fact_extraction_token_analysis with test_fact_extraction_basic_analysis
  using inline sample content instead of external file
- Update test_fact_extraction_output_ratio.py to unpack 3 return values
  (facts, chunks, usage) instead of 2

* fix: make temporal tests more flexible for LLM variation

- test_temporal_absolute_conversion: check occurred_start field instead of
  requiring specific text in facts
- test_date_field_calculation_yesterday: make assertions conditional on
  having temporal data, add more content for better extraction
- test_temporal_ordering: reduce minimum required facts from 3 to 2
2026-01-08 22:49:04 +01:00
Nicolò Boschi
33fac2c5e2
feat: add configs for database connection (#128) 2026-01-08 16:37:08 +01:00
Nicolò Boschi
49e233cdb7
fix: duplicated causal relationships and token optimization (#126)
* fix: duplicated causal relationships and token optimization

* doc

* doc
2026-01-08 14:43:48 +01:00
Nicolò Boschi
e6709d541f
feat: support different provider/models per operation (#125)
* feat: support different provider/models per operation

* fix tests
2026-01-08 14:02:57 +01:00
Nicolò Boschi
233bd2e5d4
feat: run db migrations offline (optionally) (#114)
* feat: run db migrations offline (optionally)

* fix
2026-01-07 15:49:51 +01:00
Nicolò Boschi
7715a5110e
fix: make retain max completion tokens configurable (#109)
* fix: make retain max completion tokens configurable

* fix: make retain max completion tokens configurable
2026-01-07 10:26:42 +01:00
Chris Bartholomew
ce45d301ce
Add operation validator extension support with proper HTTP error handling (#86)
* 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.
2026-01-01 20:19:52 -05:00
Chris Bartholomew
dfa7cec05b
Load operation validator extension in main entry point (#72)
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.
2025-12-23 15:47:26 +01:00
Nicolò Boschi
e6511e7d77
feat: refactor hindsight-embed architecture (#66)
* feat: refactor hindsight-embed architecture

* feat: refactor hindsight-embed architecture

* refactor deamin

* refactor deamin

* refactor deamin

* refactor deamin
2025-12-22 22:02:40 +01:00
Nicolò Boschi
2a0c490c9e
feat: extensions (#54) 2025-12-22 11:05:23 +01:00
Nicolò Boschi
1c6acc3ba0
feat: simplify mcp installation + ui standalone (#41) 2025-12-18 10:24:56 +01:00
Nicolò Boschi
9394cf92f2
fix: doc build and lint files (#34)
* fix doc build

* fix doc build
2025-12-16 13:49:09 +01:00
Nicolò Boschi
fa554b8980 brandind and misc fixes 2025-12-11 12:46:48 +01:00
Nicolò Boschi
f42476bf94
fix: make sure openai provider works + docs updates (#23)
* fix: make sure openai provider works

* fix: make sure openai provider works

* fix
2025-12-10 16:10:10 +01:00