Skip to content

fix(skills): treat absent embedding_model payload field as model mismatch#3411

Merged
bug-ops merged 1 commit intomainfrom
3402-skill-injection-qdrant
Apr 25, 2026
Merged

fix(skills): treat absent embedding_model payload field as model mismatch#3411
bug-ops merged 1 commit intomainfrom
3402-skill-injection-qdrant

Conversation

@bug-ops
Copy link
Copy Markdown
Owner

@bug-ops bug-ops commented Apr 25, 2026

Summary

  • model_has_changed in zeph-memory used is_some_and which returns false for absent embedding_model payload fields. Legacy Qdrant points written before fix(skills): skip skill matcher in bare mode and stabilize embed model name #3395 have no such field, so stale vectors from a previous embedding model were permanently retained, producing cosine scores of ~0.022 on every query.
  • AgentSessionConfig::embed_model used effective_embedding_model instead of stable_skill_embedding_model, causing the runtime skill-sync to use a different collection version key than startup sync and re-introducing the oscillating rebuild loop.

Changes

  • crates/zeph-memory/src/embedding_registry.rs: None arm in model_has_changed now returns true when config_model is non-empty, forcing a clean rebuild when any point lacks the embedding_model field.
  • crates/zeph-core/src/agent/session_config.rs: replaced effective_embedding_model with stable_skill_embedding_model for embed_model.

Test plan

  • All 8502 unit tests pass (cargo nextest run --workspace --lib --bins)
  • Two new unit tests cover the absent-field fix: model_has_changed_absent_field_with_config_model_is_true and model_has_changed_absent_field_with_empty_config_model_is_false
  • Live test: start agent in full mode, send a query, verify skill candidates score ≥ 0.20 and injection fires

Closes #3402

@github-actions github-actions Bot added memory zeph-memory crate (SQLite) rust Rust code changes core zeph-core crate bug Something isn't working size/S Small PR (11-50 lines) labels Apr 25, 2026
…atch

Legacy Qdrant points written before #3395 lack an `embedding_model` payload
field. `model_has_changed` used `is_some_and`, which returns false for absent
fields, so stale vectors from a previous model were never cleared and caused
cosine scores of ~0.022 on every query.

Change the match arm so `None` returns `true` when `config_model` is non-empty,
forcing a collection rebuild when any point lacks the field.

Also replace `effective_embedding_model` with `stable_skill_embedding_model` in
`AgentSessionConfig::embed_model` so the runtime skill-sync uses the same
collection version key as the startup sync, preventing oscillating rebuilds.

Closes #3402
@bug-ops bug-ops force-pushed the 3402-skill-injection-qdrant branch from 8dfb2d5 to 635b076 Compare April 25, 2026 20:33
@bug-ops bug-ops enabled auto-merge (squash) April 25, 2026 20:33
@bug-ops bug-ops merged commit f1936f8 into main Apr 25, 2026
32 checks passed
@bug-ops bug-ops deleted the 3402-skill-injection-qdrant branch April 25, 2026 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working core zeph-core crate memory zeph-memory crate (SQLite) rust Rust code changes size/S Small PR (11-50 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skill injection non-functional: Qdrant skill matcher still returns near-zero cosine scores after #3395 fix

1 participant