FastAPI >= 0.115 stores included routers as _IncludedRouter objects in
app.routes (no .path attribute) instead of flattening them. Collect
paths from both direct routes and original_router.routes.
- File adapter keys reply/quote files by object_id; add v3 migration to rename/write
- DB unique constraint and upsert keys now include object_id
- Update mention index entries to include object_id
- Preserve empty cc when to/cc provided; default only when unaddressed
- Fan out to follower inboxes only when activity targets followers/public
- Add tests for direct message and unlisted delivery behavior
- Add _is_publicly_addressed check before storing Create interactions
- Private mentions/replies (no Public in to/cc) are not stored
- Unlisted posts (Public in cc) are still stored
- Callback still fires for all interactions (enables notifications)
- Document behavior in README under Interaction Callbacks
Fixes fetch issues (401) with instances that enforce signed requests.
- Add HTTP Signature headers via sign_request for actor fetch requests
- Add tests asserting signing and signed headers are included
- Add `async_delivery` param to handler and outbox (default True)
- Run delivery in background daemon thread when enabled
- Update docs and adjust tests to use synchronous delivery
OutboxProcessor.publish() now delivers to actors in the activity's
to and cc fields, not just followers. This enables notifications
for mentioned users (e.g., @user@domain mentions).
- Add _is_actor_url() to filter non-actor URLs
- Add _extract_recipient_actors() to extract actors from to/cc
- Add _fetch_actor() with caching for actor document fetches
- Add _collect_recipient_inboxes() to resolve actor inboxes
- Deduplicate inboxes when mentioned actor is also a follower
- Add .schema_version tracking and v2 object_id index backfill migration
- Document auto_migrate option in README and architecture docs
- Add tests for version file, opt-out, and index backfill behavior
The method scans `data_dir/interactions/*/*.json`.
That includes the reverse-mention index files under
`interactions/_mentions/*.json`, which are stored as a JSON list. When
the scan hits one of those, the old code did `data.get(...)` and crashed
with:
```
AttributeError: 'list' object has no attribute 'get'.
```
- Ignore non-dict JSON while scanning
- Keep the mention index consistent: when an interaction is deleted by
object_id, we now remove its entry from _mentions (same behavior as
delete_interaction).
- Add CHANGELOG entry for mention indexing, new APIs, and handler
options
- Add README section on enabling DB mention index and using
backfill_mentions