{{ message }}
Repository navigation
Refresh the ontology vector index when the editor creates or relabels a class or property, before alignment runs - #956
Merged
Conversation
… a class or property, before alignment runs The four editor handlers (create and update for classes and for properties) wrote the element and enqueued `align_types` or `align_phrases`, but nothing refreshed the ontology vector index. The phrase aligner picks its shortlist by vector whenever a signature has more than ten structural candidates, and the kind-word aligner retrieves candidate classes by vector, so an element without a vector never reached the model; the 0053 fingerprint of the shapes it could bind did not change and they were never re-decided. Only OWL import, bootstrap, type resolution, build_proposals and (since 0061 cut 1.1) the agent's adoption refreshed the index; the `bordered_by` case on a real base was this gap on the adoption path, and the editor had the same one. The handlers now share one step: queue `embed_ontology` with a two second debounce, then the alignment job with its existing five second one. The embed job is deduplicated against queued copies only (`enqueue_unless_queued_after`), not running ones: a refresh already running has read its stale set and cannot see this edit, so a second copy must follow it. A changed label or description is covered without any extra bookkeeping, because the index judges staleness by comparing the stored text with label plus description. The debounce alone does not order the two jobs, so both aligners now wait while an `embed_ontology` job for the base is queued or running, the way the phrase aligner already waits for the kind-word round: they re-enqueue themselves thirty seconds later, at most one queued copy. The order is therefore vectors, then kind words, then phrases. This also covers OWL import, which queues the same job. Tests, scripted model and real Postgres: a property created through `create_relation_type` leaves the embed job queued ahead of the alignment, the alignment defers without a model call while it is pending, the property is in the vector table once the job body has run and the model is then asked with it among the candidates; an update that changes the description queues the refresh again and re-embeds exactly that row. The kind-word aligner has the matching wait test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com>
…ps both cut 1.1 and cut 3 clauses) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

Problem
The four editor handlers in
ontology_routes.rs(create_entity_type,update_entity_type,create_relation_type,update_relation_type) write the element and enqueuealign_typesoralign_phrases, but nothing refreshes the ontology vector index.phrase_alignment::shortlistpicks candidates by vector whenever a signature has more than ten structural candidates, andtype_alignment::candidates_forretrieves candidate classes by vector. An element without a vector never reaches the model, so the 0053 fingerprint of the shapes it could bind does not change and they are never re-decided. Only OWL import, bootstrap, type resolution,build_proposalsand, since 0061 cut 1.1, the agent's adoption refreshed the index. Thebordered_bycase seen on a real base was this gap on the adoption path; the editor had the same one.Change
reindex_then_align): queueembed_ontologywith a two second debounce, then the alignment job with its existing five second one. The embed job is deduplicated against queued copies only (enqueue_unless_queued_after), not running ones: a refresh already running has read its stale set and cannot see this edit, so a second copy must follow it. Queuing rather than embedding in place keeps a batch of edits on the ontology page to one embedding call.types_needing_embeddingjudges staleness by comparing the storedembedded_textwith label plus description, so an update whose text changed is re-embedded by the same job, and an update that only touched domain or range is a no-op for it.embed_ontologyis queued or running for the base, the way the phrase aligner already waits for the kind-word round: they re-enqueue themselves thirty seconds later, at most one queued copy. The debounce alone would not order the jobs. The order is now vectors, then kind words, then phrases. OWL import queues the same job, so a large import is covered too.docs/design/ontology.md; ADR 0061's status line notes the editor path.Verification
Run against a local Postgres 16 with pgvector via
UTOPIA_DATABASE_URL.a_property_created_in_the_editor_has_its_vector_before_phrases_are_alignedinphrase_alignment_tests.rs, scripted chat and embedding endpoints, calling the real handlers:create_relation_type, the base's queue isembed_ontologythenalign_phrases, and the row has no vector;label\ndescriptionas the embedded text; the aligner then asks the model and the new property is among the candidates;update_relation_typewith a new description queues the refresh again, and it re-embeds exactly that row.kind_word_alignment_waits_while_the_ontology_index_is_refreshingintype_alignment_tests.rs, mirroring the existing kind-word wait test.cargo fmt,cargo clippy --all-targets -- -D warningsclean;cargo test -p utopia-server: 457 passed.🤖 Generated with Claude Code