feat(api): add owning-entity external_id to search results - #1101
Merged
Conversation
SearchResult now carries the owning entity's external_id UUID (the parent entity for observation and relation hits), populated in to_search_results from the already-batch-fetched entity. This lets the hosted MCP layer build stable web-app deep-links to the note each search hit matched (#1423). No search-index column and no reindex is needed: the parent entity is already loaded to shape the entity/permalink fields. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Joe P <joe@basicmemory.com>
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
External agents calling the hosted Basic Memory Cloud
/mcpsearch_notestool have no way to link a search hit back to the note in the web app. Every other content tool already returns web-app links, but search was excluded becauseSearchResultdid not expose the entityexternal_idUUID that link-building needs (#1423).What
SearchResultgainsexternal_id: Optional[str]— the owning entity's UUID (the parent entity for observation and relation hits, the note itself for entity hits).to_search_results()populates it fromparent_entity.external_id, which is already batch-fetched to shape the existingentity/permalinkfields.Pure plumbing: no search-index column, no reindex.
How it was tested
tests/api/v2/test_search_hydration.py:_make_entitynow carriesexternal_id; addedtest_external_id_populated_for_all_result_types(entity/observation/relation all resolve to the owning entity's UUID) andtest_external_id_none_when_owning_entity_missing.tests/api/v2/test_utils_telemetry.py.uv run pytest tests/api/v2/test_search_hydration.py tests/api/v2/test_utils_telemetry.py tests/api/v2/test_search_router_telemetry.py tests/schemas/test_search.py→ 22 passed. Lint + pyright clean.Companion
The consumer is a basic-memory-cloud PR that builds
/notes?id=cloud|...deep-links per search result from this field. That PR pins itsbasic-memorygit rev to this branch's commit and must be re-pinned to the merged commit here.🤖 Generated with Claude Code