Skip to content

feat(session): add match and except filters - #198

Merged
BegoniaHe merged 3 commits into
masterfrom
feat/session-bridge-filter-195
Sep 15, 2026
Merged

BegoniaHe merged 3 commits into
masterfrom
feat/session-bridge-filter-195

Conversation

@BegoniaHe

Copy link
Copy Markdown
Collaborator

Summary

Add post-create /session filter so each directed session-bridge edge can
include or exclude human messages by authorization subject, source-session
AstrBot role, or portable text.

Related issue

Fixes #195

Behavior

  • Empty match and except still forward every human message.
  • Dimensions AND; values in one dimension OR; an except hit drops the message.
  • subjects rebuild Subject.im from the source route platform id, the source adapter self_id, and SenderSnapshot.id.
  • roles use the sender's AstrBot role on the source session, not platform_member_role. Lookup miss is guest.
  • text concatenates PortablePart string values and uses stdlib re.search. Invalid patterns are rejected at save time. Media-only bodies fail match.text and do not trip except.text.
  • Each dimension accepts at most 16 values. Schema is unchanged.
  • /session filter <rule_id> shows the filter; match / except / clear change one edge. clear without a side equals all. Pair edges can differ.
  • Create commands do not parse filter flags.

Non-goals

  • Dashboard filter editor
  • Filter flags on /session watch, connect, or pair
  • A non-re regex engine
  • Using platform group roles instead of AstrBot Role
  • Plugin SDK filter methods (links / unlink / filter stay IM-only)

Implementation notes

Evaluation lives in session_bridge_filter.py and runs in observe() before
the source header is added. Filters persist in the S1 match / except JSON
columns. View and mutate scope match links / unlink.

Validation

uv run ruff format --check astrbot/core/platform/session_bridge_filter.py astrbot/core/platform/session_bridge.py astrbot/core/platform/session_bridge_state.py astrbot/builtin_stars/builtin_commands/commands/session.py tests/unit/test_session_bridge.py tests/unit/test_session_bridge_filter.py tests/unit/test_session_commands.py
uv run ruff check astrbot/core/platform/session_bridge_filter.py astrbot/core/platform/session_bridge.py astrbot/core/platform/session_bridge_state.py astrbot/builtin_stars/builtin_commands/commands/session.py tests/unit/test_session_bridge.py tests/unit/test_session_bridge_filter.py tests/unit/test_session_commands.py
uv run pytest tests/unit/test_session_bridge_filter.py tests/unit/test_session_bridge.py tests/unit/test_session_commands.py tests/unit/test_builtin_command_extensions.py tests/unit/test_builtin_command_i18n.py tests/unit/test_import_boundaries.py --test-profile blocking

make check and make test-blocking were not run.

Compatibility and risk

No schema change. Existing empty filters keep forwarding all human messages.
Role lookup adds a session.read authorize call only when a role filter is set.

Checklist

  • A Feature request Issue exists for large work, or this is a small, obvious addition.
  • The change is focused and does not include unrelated refactoring.
  • I added or updated tests, or explained why tests are not practical.
  • User-visible behavior updates both docs/zh/ and docs/en/.
  • OpenAPI, generated client, docs/public/openapi.json, and tests change together when routes or schemas change.
  • No secrets committed. Runtime Python deps update pyproject.toml, requirements.txt, and uv.lock together.
  • I did not restore legacy shims, Python <3.14 fallbacks, or upstream publish/docs URLs as fork artifacts.
  • Breaking API or behavior changes use ! and a BREAKING CHANGE: footer.
  • I will not merge this PR myself. Merge needs a human maintainer review plus a separate AI-assisted review (AI_POLICY.md).
  • AI use follows AI_POLICY.md. Keep exactly one author note below. Do not fabricate the other.

Agent note

S3 of #192 / #195. Goal: post-create match/except filters on directed edges.
Touched session_bridge_filter.py, session_bridge.py, session_bridge_state.py,
/session filter, bilingual command docs, and session-bridge/command tests.
Checks run: ruff format/check on the touched Python files; 117 focused pytest
tests passed. Residual risk: pair live-index still belongs to S2; this slice
persists pair-edge filters and evaluates live watch/connect grants. Tools:
OpenCode / grok-4.6.

@xero-team-bot

xero-team-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown

⚠️ This PR conflicts with its base branch and needs a rebase.

git fetch origin master
git rebase origin/master
# after resolving the conflicts
git push --force-with-lease

The needs-rebase label is removed automatically once the conflicts are gone.
(Xero-Team/AstrBot · detected by xero-bot)

Allow operators to restrict forwarded human messages per directed
edge with /session filter after a watch or connect exists.

Fixes #195
AI-Generated: true
Generated-At: 2026-09-15T02:55:53Z
Re-read the stored edge under the lock before committing
match/except, and treat a missing store update as a miss.

AI-Generated: true
Generated-At: 2026-09-15T03:55:12Z
Pass get_self_id through the session-bridge test manager so
subject filters still rebuild after rebasing onto pair.

AI-Generated: true
Generated-At: 2026-09-15T04:04:31Z
@BegoniaHe
BegoniaHe force-pushed the feat/session-bridge-filter-195 branch from de312e4 to e5948ac Compare September 15, 2026 04:04
@xero-team-bot

xero-team-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown

✅ Conflicts resolved; removing the needs-rebase label.

@BegoniaHe
BegoniaHe merged commit 5d3f241 into master Sep 15, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] add session-bridge match/except filters

1 participant