Add RSS knowledge expiry, recent_knowledge and promote_knowledge tools #9

Closed
timstoop wants to merge 2 commits from rss-knowledge-expiry into feat/rss-reader-improvements
timstoop commented 2026-03-30 13:05:44 +00:00 (Migrated from codeberg.org)

Implements the two features discussed in issue #6, plus a promote_knowledge tool as requested by @ric_harvey.

Changes

expires_at field on RSS-ingested knowledge items

At ingest time, the RSS worker now sets expires_at = created_at + MAX_KNOWLEDGE_AGE_DAYS * 86400 on every ingested article. MAX_KNOWLEDGE_AGE_DAYS is a new env var (default 30). Manually stored knowledge items via remember(namespace="knowledge") never get expires_at set, so they are unaffected.

During auto-maintenance (Phase 3, global), any RSS-ingested item (identified by feed_name being set) whose expires_at has passed is archived. The run_maintenance return dict gains a knowledge_expired key listing archived keys.

The idx:knowledge index gains a NumericField("expires_at") — the existing startup migration handles the field count change automatically.

recent_knowledge tool

Query knowledge items by recency rather than relying on vector similarity scoring:

recent_knowledge(days=7, feed_name=None, topics=None, limit=20)

Returns active knowledge items created within the lookback window, sorted newest first. Optionally filter by feed name or topic tags. Days clamped to 1–365, limit to 1–50.

promote_knowledge tool

Mark an RSS-ingested article as permanently useful by clearing its expires_at:

promote_knowledge(key="mem:knowledge:...")

Clears expires_at so the item is never auto-archived. Returns an error if the key is not in the knowledge namespace, does not exist, or is already archived.

Tests

17 new tests covering all three features, using in-memory fakes (no Docker required):

  • tests/test_knowledge_tool.py — 15 tests for recent_knowledge and promote_knowledge
  • tests/test_knowledge_maintenance.py — 7 tests for expire_knowledge_items and run_maintenance

Full suite: 438 passed, 1 pre-existing unrelated failure (test_sorted_newest_first).

Closes #6

Implements the two features discussed in issue #6, plus a `promote_knowledge` tool as requested by @ric_harvey. ## Changes ### `expires_at` field on RSS-ingested knowledge items At ingest time, the RSS worker now sets `expires_at = created_at + MAX_KNOWLEDGE_AGE_DAYS * 86400` on every ingested article. `MAX_KNOWLEDGE_AGE_DAYS` is a new env var (default 30). Manually stored knowledge items via `remember(namespace="knowledge")` never get `expires_at` set, so they are unaffected. During auto-maintenance (Phase 3, global), any RSS-ingested item (identified by `feed_name` being set) whose `expires_at` has passed is archived. The `run_maintenance` return dict gains a `knowledge_expired` key listing archived keys. The `idx:knowledge` index gains a `NumericField("expires_at")` — the existing startup migration handles the field count change automatically. ### `recent_knowledge` tool Query knowledge items by recency rather than relying on vector similarity scoring: ``` recent_knowledge(days=7, feed_name=None, topics=None, limit=20) ``` Returns active knowledge items created within the lookback window, sorted newest first. Optionally filter by feed name or topic tags. Days clamped to 1–365, limit to 1–50. ### `promote_knowledge` tool Mark an RSS-ingested article as permanently useful by clearing its `expires_at`: ``` promote_knowledge(key="mem:knowledge:...") ``` Clears `expires_at` so the item is never auto-archived. Returns an error if the key is not in the knowledge namespace, does not exist, or is already archived. ## Tests 17 new tests covering all three features, using in-memory fakes (no Docker required): - `tests/test_knowledge_tool.py` — 15 tests for `recent_knowledge` and `promote_knowledge` - `tests/test_knowledge_maintenance.py` — 7 tests for `expire_knowledge_items` and `run_maintenance` Full suite: 438 passed, 1 pre-existing unrelated failure (`test_sorted_newest_first`). Closes #6

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ric/omnimem!9
No description provided.