* fix: tagged directives should be applied to tagged mental models
* test: add unit test for based_on structure
Verify that reflect returns the correct based_on structure with:
- directives as dicts (id, name, content) in based_on.directives
- mental models as MemoryFact objects in based_on.mental-models
- memories separated properly
This ensures directives and mental models are not mixed together
in the API response.
* 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.
* feat: improve mental models ux on control plane
* feat: improve mental models ux on control plane
* gen
* feat(cli): add --id flag to mental model create command
* fix(cli): revert unused variable underscore prefix that breaks compilation
The underscore prefix on stdout/stderr variables was added to suppress
warnings, but these variables are actually used in assert messages,
causing compilation errors. Reverting to original names.
* 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.
The control plane proxy routes never sent an Authorization header to
the dataplane API. With the tenant extension active, all GUI requests
failed with "Invalid API key".
Add HINDSIGHT_CP_DATAPLANE_API_KEY env var support to hindsight-client.ts
and propagate auth headers to both SDK clients and all direct fetch routes.
When the backend graph API returns an error, the SDK sets response.data
to undefined. NextResponse.json(undefined) throws "Value is not JSON
serializable". Check for error/missing data before serializing.
* 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
* expose the delete API
* add deleteBank
* Add a button and confirmation dialog to delete a memory bank
* commit lint changes
* add CI test for delete bank
* revert alembic lint changes due to version differences
* revert alembic lint changes
* fix the delete bank test
* account for ruff lint third party alembic
* Improve graph visualization on the UI
* Fix double animation when loading the graph visualization
* Fix typescript issues
* CI test changes for temporal scenarios
* Fix typescript errors
* Fix animation issue on opinions and experiences
* Added hindsight_liteLLM implementation
* Add instructions for entity vs bank id
* Add another line about entity
* Address PR review comments and enhance litellm integration
- Remove deprecated limit parameter from recall() and arecall() functions
since Hindsight uses budget/max_tokens for result control
- Remove dead MODEL_MAX_OUTPUT_TOKENS dict and max_output_tokens property
from LLMProvider (superseded by hardcoded max_completion_tokens)
- Add test-litellm-integration job to CI workflow
- Add reflect API support with use_reflect config option
- Add verbose mode debug info via get_last_injection_debug()
- Add entity_id support for multi-user memory isolation
- Add retain() and reflect() wrapper functions
- Update docstrings and examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Make max_memories optional to allow unlimited memory injection
- Change max_memories default from 10 to None (no limit)
- When max_memories is None, all results from the API are used
- Fix recall result handling to properly detect list vs object return
- Update wrappers (OpenAI, Anthropic) with same optional behavior
This allows users to control memory limits via max_memory_tokens
and recall_budget without an artificial count limit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove entity_id from hindsight_litellm; add gpt-4o token cap
Multi-user support now uses separate bank_ids per user instead of
entity_id scoping (e.g., bank_id=f"user-{user_id}"). This simplifies
the API and aligns with the Hindsight architecture.
Also fixes max_completion_tokens error for gpt-4o models by capping
the value at 16384 (gpt-4o's limit) instead of sending the default
65000 which exceeds the model's supported maximum.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix dark mode styling across Control Plane UI components
Improvements to ensure proper text visibility and contrast in both light
and dark modes:
- Add global CSS rules for datetime-local calendar picker icon visibility
using filter: invert() for both light (0.5) and dark (1) modes
- Fix text colors in dialog components to use theme-aware foreground colors
- Update memory detail panel, document/chunk modals, and data views to use
proper dark mode text classes (text-foreground, text-card-foreground)
- Fix form labels, headings, and content text in bank selector dialogs
- Update entities view and documents view table styling for dark mode
- Bump package versions to 0.1.4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove session_id feature and add How It Works section to README
- Remove session_id and session management (new_session, set_session,
get_session) from config.py, callbacks.py, and __init__.py
- Session management was a client-only abstraction not backed by core API
- Add "How It Works" section to README with visual flow diagram
- Update README to remove session management documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix readme example
* Add dark mode again
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Improve LongMemEval benchmark with structured prompts and better options
- Add --context-format option with 'json' (original) and 'structured' modes
- Structured format groups facts with source chunks for better LLM comprehension
- Add detailed instructions for date calculations, relative time handling, and abstention
- Add --source-results flag to read failed questions from a different file
- Allow --category to be combined with --max-instances for sampling
- Fix Gemini structured output by passing response_schema parameter
- Add retry logic for empty Gemini responses with block reason logging
- Add judge prompt comparison documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix recall in benchmarks
* Improve LongMemEval prompt and Gemini error handling
- Add JSONDecodeError retry for Gemini truncated responses
- Increase max_tokens to 32768 for thinking models
- Add counting/disambiguation guidance to structured prompt
- Add "when in doubt, undercount" and overlap detection rules
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add connection error retry and preference question guidance
- Add APIConnectionError retry for OpenAI client (server disconnects)
- Add recommendation/preference question guidance to structured prompt
- Instruct model to build on user's existing tools/experiences
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Make reasoning optional
* Seed for LLM through Groq
* fix entity and observations
* Increase graph retrieval neighbor limit for expanded entities
Doubled the neighbor limit multiplier from 10 to 20 in graph retrieval.
With expanded entity extraction (now including objects and concepts like
"kitchen"), facts share more common entities, causing the previous limit
to arbitrarily exclude relevant results. This fix ensures better recall
for questions about related items (e.g., kitchen items).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Expand entity extraction to include objects and concepts
Updated entity extraction prompt to include:
- Specific objects (coffee maker, toaster, car, laptop, kitchen)
- Abstract concepts/themes (friendship, career growth, loss, celebration)
- Places and organizations (IKEA, Goodwill, New York)
This enables better fact linking through shared entities. For example,
kitchen appliances now share a "kitchen" entity, allowing graph traversal
to find related facts like "replaced coffee maker" when querying about
"kitchen items".
Works in conjunction with the increased neighbor limit to improve recall.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Chris Bartholomew <chris.bartholomew@vectorize.io>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: andrew <andrew.neeser@me.com>