diff --git a/CHANGELOG.md b/CHANGELOG.md index e9fbb829..b720c364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.2] - 2026-07-07 + +### Fixed + +- **Agent-track search broken by `deprecated_by IS NULL` filter** — + `compile_filters()` unconditionally appended a `deprecated_by IS NULL` + clause to every LanceDB query, but only `episode` and `atomic_fact` + tables have this column. Agent-track search (`agent_case`, + `agent_skill`) failed on any method. The clause is now conditional on + `owner_type == "user"`. + ## [1.1.1] - 2026-07-06 ### Added @@ -215,7 +226,8 @@ for AI agents. - **Decoupled algorithms** — memory extraction algorithms live in the standalone `everalgo-*` libraries published on PyPI. -[Unreleased]: https://github.com/EverMind-AI/everos/compare/v1.1.1...HEAD +[Unreleased]: https://github.com/EverMind-AI/everos/compare/v1.1.2...HEAD +[1.1.2]: https://github.com/EverMind-AI/everos/compare/v1.1.1...v1.1.2 [1.1.1]: https://github.com/EverMind-AI/everos/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/EverMind-AI/everos/compare/v1.0.1...v1.1.0 [1.0.1]: https://github.com/EverMind-AI/everos/releases/tag/v1.0.1 diff --git a/docs/openapi.json b/docs/openapi.json index 53cc024c..58ad559e 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -3,7 +3,7 @@ "info": { "title": "everos", "description": "md-first memory extraction framework", - "version": "1.1.1" + "version": "1.1.2" }, "paths": { "/health": { diff --git a/pyproject.toml b/pyproject.toml index d173a810..0e359b6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "everos" -version = "1.1.1" +version = "1.1.2" description = "EverOS — local-first markdown memory framework for AI agents and user chats; lightweight, dev-friendly, small-team" license = {text = "Apache-2.0"} readme = "README.md" diff --git a/src/everos/memory/search/filters.py b/src/everos/memory/search/filters.py index 9903cb77..2dd9aa80 100644 --- a/src/everos/memory/search/filters.py +++ b/src/everos/memory/search/filters.py @@ -107,8 +107,11 @@ def compile_filters( f"owner_type = '{owner_type}'", f"app_id = '{_escape_str(app_id)}'", f"project_id = '{_escape_str(project_id)}'", - "deprecated_by IS NULL", ] + # Only episode / atomic_fact tables carry the ``deprecated_by`` column + # (Reflection V1 marks superseded entries). Agent tables don't have it. + if owner_type == "user": + base.append("deprecated_by IS NULL") if node is None: return " AND ".join(base) compiled = _compile_node(node.model_dump(exclude_none=True)) diff --git a/tests/unit/test_memory/test_get/test_filters_adapter.py b/tests/unit/test_memory/test_get/test_filters_adapter.py index eef5debe..4d6c48f4 100644 --- a/tests/unit/test_memory/test_get/test_filters_adapter.py +++ b/tests/unit/test_memory/test_get/test_filters_adapter.py @@ -33,6 +33,12 @@ def test_no_filters_emits_base_clause() -> None: ) +def test_no_filters_agent_omits_deprecated_by() -> None: + """Agent tables lack ``deprecated_by`` — clause must be absent.""" + where = compile_filters_for_get(None, owner_id="bot", owner_type="agent") + assert "deprecated_by" not in where + + def test_owner_id_quote_is_escaped() -> None: """SQL-standard double-quote escape on ``owner_id``.""" where = compile_filters_for_get(None, owner_id="o'reilly", owner_type="user") diff --git a/tests/unit/test_memory/test_search/test_filters.py b/tests/unit/test_memory/test_search/test_filters.py index 19647616..808c2a38 100644 --- a/tests/unit/test_memory/test_search/test_filters.py +++ b/tests/unit/test_memory/test_search/test_filters.py @@ -22,6 +22,15 @@ def test_no_filters_emits_base_clause() -> None: ) +def test_no_filters_agent_omits_deprecated_by() -> None: + where = compile_filters(None, owner_id="bot_42", owner_type="agent") + assert "deprecated_by" not in where + assert where == ( + "owner_id = 'bot_42' AND owner_type = 'agent' " + "AND app_id = 'default' AND project_id = 'default'" + ) + + def test_owner_type_agent_pinned() -> None: where = compile_filters(None, owner_id="alice", owner_type="agent") assert "owner_type = 'agent'" in where @@ -249,6 +258,11 @@ def test_empty_and_array_skips_combinator() -> None: # ── Deprecated exclusion ────────────────────────────────────────────── -def test_compile_filters_excludes_deprecated_by_default() -> None: +def test_compile_filters_excludes_deprecated_by_for_user() -> None: result = compile_filters(None, owner_id="u_a", owner_type="user") assert "deprecated_by IS NULL" in result + + +def test_compile_filters_omits_deprecated_by_for_agent() -> None: + result = compile_filters(None, owner_id="agent_1", owner_type="agent") + assert "deprecated_by" not in result diff --git a/uv.lock b/uv.lock index 0af64919..65fa5d51 100644 --- a/uv.lock +++ b/uv.lock @@ -560,7 +560,7 @@ wheels = [ [[package]] name = "everos" -version = "1.1.1" +version = "1.1.2" source = { editable = "." } dependencies = [ { name = "aiosqlite" },