* feat: ai sdk integration
* more fixes
* fix(security): mental model refresh tag-based security
- Mental model refresh now passes tags with all_strict matching
- Consolidation only triggers refresh for mental models with matching tags
- Consolidation filters related observations by tags (all_strict)
- Added tests to verify tag-based security boundaries
- Updated OpenAPI spec to include tags and text_preview in list_documents
- Added tags column to documents UI table
* chore: regenerate OpenAPI spec after rebase
* fix: improve consolidation prompt for contradiction handling and mental model refresh security
- Enhanced consolidation prompt to be more explicit about capturing temporal changes in contradictions
- Fixed mental model refresh security: tagged memories now only trigger refresh of mental models with matching tags
- Added stricter tag filtering to prevent cross-scope mental model refreshes
Fixes test_consolidation_merges_contradictions by improving LLM instructions to use temporal markers like "used to X, now Y" when merging contradictory facts.
Note: test_refresh_with_tags_only_accesses_same_tagged_models still needs investigation - REFLECT operation may need additional tag filtering.
* fix: mental model refresh security - proper tag filtering in search
Fixed tool_search_mental_models to properly handle all_strict tag matching mode by using the centralized build_tags_where_clause function. Previously, the function only handled "all" vs "any" modes and always included untagged mental models when using non-"all" modes.
This ensures that when a tagged mental model is refreshed with all_strict matching, it cannot access untagged mental models, preventing cross-scope information leakage.
Fixes test_refresh_with_tags_only_accesses_same_tagged_models.
Note: test_sensory_dimension_preservation is failing but this is a pre-existing issue on main branch - the LLM model (gpt-oss-20b) is not extracting facts from sensory text. Not related to security changes.
* chore: apply formatting from pre-commit hook
* fix: allow untagged mental models to be refreshed by any consolidation
Untagged mental models are considered "global" and should be refreshed
by any consolidation, regardless of whether tagged or untagged memories
were consolidated. This maintains security boundaries while allowing
global mental models to stay fresh.
When tagged memories are consolidated:
- Refresh mental models with matching tags (security boundary)
- Also refresh untagged mental models (they're global)
- DO NOT refresh mental models with different tags
When untagged memories are consolidated:
- Only refresh untagged mental models
- DO NOT refresh tagged mental models (security boundary)
Fixes test_consolidation_only_refreshes_matching_tagged_models.
Replace the OpenAI-compatible endpoint approach with the native
google-genai SDK for Vertex AI. This eliminates the custom token
refresher, TokenInjectingTransport, and async lifecycle complexity
while also removing the 8192 output token cap that the OpenAI
endpoint enforced.
Changes:
- vertexai provider now uses genai.Client(vertexai=True) instead of
AsyncOpenAI with token-injecting transport
- Routes through existing _call_gemini/_call_with_tools_gemini paths
- Strips google/ prefix from model names (native SDK uses bare names)
- Preserves service account key auth via credentials parameter
- Delete vertexai_token_refresher.py (no longer needed)
- Strip markdown code fences in consolidator JSON parsing
- Rewrite vertexai tests for native SDK integration
* 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
* 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