|
|
@@ -115,6 +115,37 @@ class HermesChatType(StrEnum):
|
|
|
told about where it is.
|
|
|
|
|
|
A StrEnum so it stays a drop-in ``str`` at every one of those call sites.
|
|
|
+
|
|
|
+ GROUP vs CHANNEL
|
|
|
+ ----------------
|
|
|
+ There is no strict contract between the two, and the adapters disagree in
|
|
|
+ practice: Slack labels every non-DM conversation ``"group"`` (including real
|
|
|
+ channels), Discord uses both, and Telegram reserves ``"channel"`` for actual
|
|
|
+ broadcast channels. The intended reading is ``group`` = ordinary
|
|
|
+ multi-participant chat, ``channel`` = broadcast surface.
|
|
|
+
|
|
|
+ The distinction only changes behaviour in three places:
|
|
|
+
|
|
|
+ 1. Authorization (``gateway/authz_mixin.py``) — the only security-relevant
|
|
|
+ one. The group-scoped env allowlists apply to ``{"group", "forum"}``
|
|
|
+ ONLY, never to ``"channel"``: ``{PLATFORM}_GROUP_ALLOWED_USERS`` /
|
|
|
+ ``_GROUP_ALLOWED_CHATS`` (:616), the chat-id allowlist (:708) and the
|
|
|
+ Telegram legacy shim (:724). The adapter-delegation paths in turn treat
|
|
|
+ all three alike (:461, :649, :674, :694), where the value only picks
|
|
|
+ ``group_allow_from`` over ``allow_from`` from ``config.extra``.
|
|
|
+ For Chatto both choices are equivalent today: those group env maps hold
|
|
|
+ Telegram and QQBot only (:535-541), and our own allowlist runs through
|
|
|
+ ``CHATTO_ALLOWED_USERS``, which is chat_type-independent.
|
|
|
+ 2. What the agent is told — ``SessionSource.description`` renders
|
|
|
+ ``"group: Name"`` vs ``"channel: Name"`` (session.py:239-246), likewise
|
|
|
+ the PII-redacted variant (session.py:537-544).
|
|
|
+ 3. The session key, which embeds the literal (session.py:1192). Changing
|
|
|
+ the value for a room re-buckets its existing sessions.
|
|
|
+
|
|
|
+ Explicitly NOT affected: ``is_shared_multi_user_session`` (session.py:1063)
|
|
|
+ only looks at ``"dm"`` and ``thread_id``, so sender prefixes, the multi-user
|
|
|
+ prompt line and ``group_sessions_per_user`` treat group and channel
|
|
|
+ identically.
|
|
|
"""
|
|
|
|
|
|
DM = "dm"
|
|
|
@@ -126,6 +157,9 @@ class HermesChatType(StrEnum):
|
|
|
# because build_session_key rewrites the slot to "thread" itself
|
|
|
# (session.py:1190).
|
|
|
THREAD = "thread"
|
|
|
+ # Not declared in session.py:161 but real: Telegram forum topics travel as
|
|
|
+ # "forum", and the authz group allowlists above accept it alongside "group".
|
|
|
+ # Chatto has no equivalent, so we never emit it.
|
|
|
|
|
|
|
|
|
# Chatto only distinguishes DMs from channels. UNSPECIFIED means the server
|
|
|
@@ -133,6 +167,11 @@ class HermesChatType(StrEnum):
|
|
|
# multi-user bucket rather than guessing "channel", and never to "dm" — that
|
|
|
# value drives session isolation (is_shared_multi_user_session, session.py:1063)
|
|
|
# and would silently turn a room into a private conversation.
|
|
|
+#
|
|
|
+# CHANNEL for RoomKind.CHANNEL is the descriptive choice and carries no
|
|
|
+# behavioural cost (see the GROUP vs CHANNEL note above). Switching to GROUP for
|
|
|
+# Slack parity would be this one line — plus the re-bucketing of existing
|
|
|
+# sessions that point 3 of that note describes.
|
|
|
_ROOM_KIND_TO_CHAT_TYPE: Dict[RoomKind, HermesChatType] = {
|
|
|
RoomKind.DM: HermesChatType.DM,
|
|
|
RoomKind.CHANNEL: HermesChatType.CHANNEL,
|