refactor: MessageEvent to gateway/platforms/event.py; ElicitationHandler takes a call_context thunk

Breaks the two import cycles that forced Protocol stand-ins in the F821 sweep, so the two
sites now name the real types.

gateway/platforms/event.py (new leaf): MessageType, ProcessingOutcome, MessageEvent moved
out of base.py verbatim. Their only dependency is gateway.session.SessionSource; base.py
imported helpers.py at module level, so helpers could not name MessageEvent. Now
TextBatchAggregator is typed by the real MessageEvent. 249 importers repointed
(`from gateway.platforms.base import` -> `.event`, preserving each import's layout);
gateway.platforms.__init__ re-exports from .event. The three revert-scheduled PLUGIN-COMPAT
pointers that named these symbols (gateway.slash_commands → MessageType, dingtalk → MessageType,
photon → ProcessingOutcome) and their COMPAT_MANIFEST rows now target gateway.platforms.event.
Docs updated: ADDING_A_PLATFORM.md, adding-platform-adapters.md (en + zh-Hans).

tools/mcp_tool_sampling.py: ElicitationHandler no longer holds a back-reference to its
MCPServerTask (mcp_tool imports sampling, so the task type cannot be named there). It only
ever read owner._pending_call_context, so it takes `call_context: Callable[[], Context | None]`
and MCPServerTask passes `lambda: self._pending_call_context`. The consent call is one
`functools.partial`, run directly or inside the captured Context.

ty on the 11 touched production files vs origin/main: 0 new diagnostics, 14 resolved.
(The one `source: SessionSource = None` diagnostic moves with the class; typing it Optional
exposes ~60 unguarded call sites — separate follow-up.)

Tests: tests/gateway + tests/plugins + tests/tools + touched files, 18,235 passed; the 31
failures reproduce identically on origin/main (macOS /private/tmp, systemd socket,
long-path fixtures, live-service tests).
This commit is contained in:
kshitijk4poor
2026-09-04 22:37:25 +05:30
committed by kshitij
parent c5ff900761
commit ab2f4602de
259 changed files with 524 additions and 464 deletions
+3 -3
View File
@@ -1025,7 +1025,7 @@ to the public equivalent or the new module. Test monkeypatch seams are likewise
|---|---|---|
| `Any` | import | `typing` |
| `HISTORY_UNREADABLE` | moved-lazy | `gateway.slash_commands_status` |
| `MessageType` | moved-lazy | `gateway.platforms.base` |
| `MessageType` | moved-lazy | `gateway.platforms.event` |
| `SessionSource` | moved-lazy | `gateway.session` |
| `base_url_host_matches` | moved-lazy | `utils` |
| `build_session_key` | moved-lazy | `gateway.session` |
@@ -2547,7 +2547,7 @@ to the public equivalent or the new module. Test monkeypatch seams are likewise
|---|---|---|
| `DINGTALK_TYPE_MAPPING` | moved-lazy | `plugins.platforms.dingtalk.inbound` |
| `EXT_MAP` | restored-def | `(deleted; BASE body restored)` |
| `MessageType` | moved-lazy | `gateway.platforms.base` |
| `MessageType` | moved-lazy | `gateway.platforms.event` |
### `plugins.platforms.discord.adapter`
@@ -2602,7 +2602,7 @@ to the public equivalent or the new module. Test monkeypatch seams are likewise
| name | kind | new location |
|---|---|---|
| `ProcessingOutcome` | moved-lazy | `gateway.platforms.base` |
| `ProcessingOutcome` | moved-lazy | `gateway.platforms.event` |
| `resolve_sidecar_dir` | moved-lazy | `plugins.platforms.photon.sidecar_paths` |
### `plugins.platforms.photon.auth`
+3 -3
View File
@@ -2646,7 +2646,7 @@
"facade": "gateway.slash_commands",
"name": "MessageType",
"kind": "moved-lazy",
"target": "gateway.platforms.base"
"target": "gateway.platforms.event"
},
{
"facade": "gateway.slash_commands",
@@ -8262,7 +8262,7 @@
"facade": "plugins.platforms.dingtalk.adapter",
"name": "MessageType",
"kind": "moved-lazy",
"target": "gateway.platforms.base"
"target": "gateway.platforms.event"
},
{
"facade": "plugins.platforms.discord.adapter",
@@ -8340,7 +8340,7 @@
"facade": "plugins.platforms.photon.adapter",
"name": "ProcessingOutcome",
"kind": "moved-lazy",
"target": "gateway.platforms.base"
"target": "gateway.platforms.event"
},
{
"facade": "plugins.platforms.photon.adapter",
+1 -1
View File
@@ -135,7 +135,7 @@ def check_<platform>_requirements() -> bool:
- Use `self.build_source(...)` to construct `SessionSource` objects
- Call `self.handle_message(event)` to dispatch inbound messages to the gateway
- Use `MessageEvent`, `MessageType`, `SendResult` from base
- Use `MessageEvent`, `MessageType` from `gateway.platforms.event` and `SendResult` from base
- Use `cache_image_from_bytes`, `cache_audio_from_bytes`, `cache_document_from_bytes` for attachments
- Filter self-messages (prevent reply loops)
- Filter sync/echo messages if the platform has them
+2 -1
View File
@@ -1,5 +1,6 @@
"""Platform adapters for messaging integrations (receive, send, auth, media)."""
from .base import BasePlatformAdapter, MessageEvent, SendResult
from .base import BasePlatformAdapter, SendResult
from .event import MessageEvent
__all__ = ["BasePlatformAdapter", "MessageEvent", "SendResult"]
+1 -87
View File
@@ -423,15 +423,14 @@ def is_host_excluded_by_no_proxy(hostname: str, no_proxy_value: str | None = Non
import dataclasses
from dataclasses import dataclass, field
from datetime import datetime
from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional, Any, Callable, Awaitable, Tuple, Union
from enum import Enum
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import fence_state_after
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.session import SessionSource, build_session_key
from gateway.session_transcript import TranscriptReadError
from hermes_constants import get_default_hermes_root, get_hermes_dir, get_hermes_home
@@ -1505,91 +1504,6 @@ async def cache_media_bytes_async(
)
class MessageType(Enum):
"""Types of incoming messages."""
TEXT = "text"
LOCATION = "location"
PHOTO = "photo"
VIDEO = "video"
AUDIO = "audio"
VOICE = "voice"
DOCUMENT = "document"
STICKER = "sticker"
COMMAND = "command" # /command style
class ProcessingOutcome(Enum):
"""Result classification for message-processing lifecycle hooks."""
SUCCESS = "success"
FAILURE = "failure"
CANCELLED = "cancelled"
@dataclass
class MessageEvent:
"""Incoming message from a platform — the normalized shape all adapters produce."""
text: str
message_type: MessageType = MessageType.TEXT
# Author, mirrored from ``source`` for per-message prompt builders; None for non-IM sources.
user_id: Optional[str] = None
user_name: Optional[str] = None
source: SessionSource = None
raw_message: Any = None
message_id: Optional[str] = None
# Platform update id (Telegram ``update_id``): ``/restart`` records it so the new gateway
# advances past it even if PTB's shutdown ACK times out.
platform_update_id: Optional[int] = None
# Media attachments: local file paths (for vision tool access)
media_urls: List[str] = field(default_factory=list)
media_types: List[str] = field(default_factory=list)
# Per-attachment text-inlining contract; None = legacy "text/* already inlined into ``text``".
media_text_inlined: List[Optional[bool]] = field(default_factory=list)
reply_to_message_id: Optional[str] = None
reply_to_text: Optional[str] = None # Text of the replied-to message (for context injection)
reply_to_author_id: Optional[str] = None
reply_to_author_name: Optional[str] = None
reply_to_is_own_message: bool = False # True when the user replied to this bot/assistant's message
# Structured interactive-prompt reply (relay only): {prompt_id, option_id, label?,
# prompt_message_id?}; routed to the approval/slash-confirm/clarify resolvers BEFORE dispatch.
prompt_response: Optional[Dict[str, Any]] = None
# Auto-loaded skill(s) for topic/channel bindings; a single name or ordered list.
auto_skill: Optional[str | list[str]] = None
# Per-channel ephemeral system prompt; applied at API call time, never persisted to transcript.
channel_prompt: Optional[str] = None
# History-backfilled channel context (missed under require_mention); kept out of ``text`` so
# run.py's sender-prefix logic sees only the trigger message.
channel_context: Optional[str] = None
# Set for synthetic events (e.g. background-process notifications) that must bypass user authorization.
internal: bool = False
# Free-form per-event metadata (e.g. ``whatsapp_from_owner=True``); plugins must ``.get()``.
metadata: Dict[str, Any] = field(default_factory=dict)
timestamp: datetime = field(default_factory=datetime.now)
# May this event resolve gateway commands / control prompts? Proactive plugin events set False
# so untrusted payload text stays conversational. Kept last for positional compat.
allow_gateway_control: bool = True
def is_command(self) -> bool:
"""Check if this is a command message (e.g., /new, /reset)."""
return self.allow_gateway_control and (self.text or "").lstrip().startswith("/")
def get_command(self) -> Optional[str]:
"""Extract command name if this is a command message."""
if not self.is_command():
return None
raw = (self.text or "").lstrip().split(maxsplit=1)[0][1:].lower().split("@", 1)[0]
# Reject file paths: valid command names never contain /
return None if "/" in raw else raw
def get_command_args(self) -> str:
"""Get the arguments after a command."""
if not self.is_command():
return self.text
parts = (self.text or "").lstrip().split(maxsplit=1)
args = parts[1] if len(parts) > 1 else ""
# iOS auto-corrects -- to — (em dash) and - to – (en dash)
return args.replace("\u2014\u2014", "--").replace("\u2014", "--").replace("\u2013", "-")
@dataclass
class TextDebounceState:
event: MessageEvent
+4 -2
View File
@@ -19,8 +19,10 @@ import httpx
from gateway.config import Platform, PlatformConfig
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, SendResult,
cache_image_from_bytes_async, cache_audio_from_bytes_async, cache_document_from_bytes_async)
BasePlatformAdapter, SendResult,
cache_image_from_bytes_async, cache_audio_from_bytes_async, cache_document_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from .media_cache import ext_for_mime
from gateway.platforms.helpers import compile_mention_patterns, strip_markdown
from utils import TRUTHY_STRINGS
+99
View File
@@ -0,0 +1,99 @@
"""Inbound message event types shared by every gateway platform adapter.
A leaf module: adapters, helpers and the runner import it, so it must not import from
gateway.platforms.*.
"""
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional
from gateway.session import SessionSource
class MessageType(Enum):
"""Types of incoming messages."""
TEXT = "text"
LOCATION = "location"
PHOTO = "photo"
VIDEO = "video"
AUDIO = "audio"
VOICE = "voice"
DOCUMENT = "document"
STICKER = "sticker"
COMMAND = "command" # /command style
class ProcessingOutcome(Enum):
"""Result classification for message-processing lifecycle hooks."""
SUCCESS = "success"
FAILURE = "failure"
CANCELLED = "cancelled"
@dataclass
class MessageEvent:
"""Incoming message from a platform — the normalized shape all adapters produce."""
text: str
message_type: MessageType = MessageType.TEXT
# Author, mirrored from ``source`` for per-message prompt builders; None for non-IM sources.
user_id: Optional[str] = None
user_name: Optional[str] = None
# None only in isolated unit tests; production always sets it. Typing it Optional
# exposes ~60 unguarded ``.source.<attr>`` reads, so that is a separate change.
source: SessionSource = None
raw_message: Any = None
message_id: Optional[str] = None
# Platform update id (Telegram ``update_id``): ``/restart`` records it so the new gateway
# advances past it even if PTB's shutdown ACK times out.
platform_update_id: Optional[int] = None
# Media attachments: local file paths (for vision tool access)
media_urls: List[str] = field(default_factory=list)
media_types: List[str] = field(default_factory=list)
# Per-attachment text-inlining contract; None = legacy "text/* already inlined into ``text``".
media_text_inlined: List[Optional[bool]] = field(default_factory=list)
reply_to_message_id: Optional[str] = None
reply_to_text: Optional[str] = None # Text of the replied-to message (for context injection)
reply_to_author_id: Optional[str] = None
reply_to_author_name: Optional[str] = None
reply_to_is_own_message: bool = False # True when the user replied to this bot/assistant's message
# Structured interactive-prompt reply (relay only): {prompt_id, option_id, label?,
# prompt_message_id?}; routed to the approval/slash-confirm/clarify resolvers BEFORE dispatch.
prompt_response: Optional[Dict[str, Any]] = None
# Auto-loaded skill(s) for topic/channel bindings; a single name or ordered list.
auto_skill: Optional[str | list[str]] = None
# Per-channel ephemeral system prompt; applied at API call time, never persisted to transcript.
channel_prompt: Optional[str] = None
# History-backfilled channel context (missed under require_mention); kept out of ``text`` so
# run.py's sender-prefix logic sees only the trigger message.
channel_context: Optional[str] = None
# Set for synthetic events (e.g. background-process notifications) that must bypass user authorization.
internal: bool = False
# Free-form per-event metadata (e.g. ``whatsapp_from_owner=True``); plugins must ``.get()``.
metadata: Dict[str, Any] = field(default_factory=dict)
timestamp: datetime = field(default_factory=datetime.now)
# May this event resolve gateway commands / control prompts? Proactive plugin events set False
# so untrusted payload text stays conversational. Kept last for positional compat.
allow_gateway_control: bool = True
def is_command(self) -> bool:
"""Check if this is a command message (e.g., /new, /reset)."""
return self.allow_gateway_control and (self.text or "").lstrip().startswith("/")
def get_command(self) -> Optional[str]:
"""Extract command name if this is a command message."""
if not self.is_command():
return None
raw = (self.text or "").lstrip().split(maxsplit=1)[0][1:].lower().split("@", 1)[0]
# Reject file paths: valid command names never contain /
return None if "/" in raw else raw
def get_command_args(self) -> str:
"""Get the arguments after a command."""
if not self.is_command():
return self.text
parts = (self.text or "").lstrip().split(maxsplit=1)
args = parts[1] if len(parts) > 1 else ""
# iOS auto-corrects -- to — (em dash) and - to – (en dash)
return args.replace("\u2014\u2014", "--").replace("\u2014", "--").replace("\u2013", "-")
+3 -12
View File
@@ -9,8 +9,7 @@ import logging
import re
import time
from pathlib import Path
from typing import Any, Protocol
from gateway.platforms.event import MessageEvent
from utils import atomic_json_write
logger = logging.getLogger(__name__)
@@ -525,14 +524,6 @@ from typing import TYPE_CHECKING # noqa: F401,E402
import asyncio # noqa: F401,E402
import asyncio # noqa: F401,E402
class BatchableEvent(Protocol):
"""What TextBatchAggregator needs from an inbound event. gateway.platforms.base.MessageEvent
satisfies it; base imports this module at import time, so the concrete class cannot be named here."""
text: str
source: Any
class TextBatchAggregator:
"""Aggregates rapid-fire text events into single messages.
@@ -565,14 +556,14 @@ class TextBatchAggregator:
self._batch_delay = batch_delay
self._split_delay = split_delay
self._split_threshold = split_threshold
self._pending: Dict[str, BatchableEvent] = {}
self._pending: Dict[str, MessageEvent] = {}
self._pending_tasks: Dict[str, asyncio.Task] = {}
def is_enabled(self) -> bool:
"""Return True if batching is active (delay > 0)."""
return self._batch_delay > 0
def enqueue(self, event: BatchableEvent, key: str) -> None:
def enqueue(self, event: MessageEvent, key: str) -> None:
"""Add *event* to the pending batch for *key*."""
chunk_len = len(event.text or "")
existing = self._pending.get(key)
+3 -1
View File
@@ -22,7 +22,9 @@ except ImportError:
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, SendResult, is_network_accessible)
BasePlatformAdapter, SendResult, is_network_accessible,
)
from gateway.platforms.event import MessageEvent, MessageType
logger = logging.getLogger(__name__)
+4 -2
View File
@@ -39,8 +39,10 @@ except ImportError:
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult,
_ssrf_redirect_guard, cache_document_from_bytes_async, cache_image_from_bytes_async)
gateway_trust_env, BasePlatformAdapter, SendResult,
_ssrf_redirect_guard, cache_document_from_bytes_async, cache_image_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms.helpers import strip_markdown
from gateway.platforms.media_cache import ext_for_mime
+4 -2
View File
@@ -25,8 +25,10 @@ import httpx
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult, cache_image_from_bytes_async,
cache_audio_from_bytes_async, cache_document_from_bytes_async, cache_image_from_url, utf16_len)
BasePlatformAdapter, SendResult, cache_image_from_bytes_async,
cache_audio_from_bytes_async, cache_document_from_bytes_async, cache_image_from_url, utf16_len,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.platforms.helpers import redact_phone
from gateway.platforms.media_cache import mime_for_ext
from tools.audio_container import CONTAINER_TO_EXT, sniff_container
+2 -1
View File
@@ -30,7 +30,8 @@ except ImportError:
web = None # type: ignore[assignment]
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms.webhook_filters import DEFAULT_SCRIPT_TIMEOUT_SECONDS, WebhookRouteProcessor
from gateway.response_filters import is_autonomous_silence_response
+2 -1
View File
@@ -30,9 +30,10 @@ CRYPTO_AVAILABLE = Cipher is not None
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import MessageDeduplicator, greedy_pack_blocks
from gateway.platforms.base import (
_IMAGE_EXTS, _VIDEO_EXTS, gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult,
_IMAGE_EXTS, _VIDEO_EXTS, gateway_trust_env, BasePlatformAdapter, SendResult,
cache_audio_from_bytes_async, cache_document_from_bytes_async, cache_image_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from hermes_constants import get_hermes_home
from utils import atomic_json_write
from agent.secret_scope import UnscopedSecretError, get_secret
+2 -1
View File
@@ -39,7 +39,8 @@ except ImportError:
httpx = None # type: ignore[assignment]
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms.whatsapp_common import _OPTIN_TRUTHY, WhatsAppBehaviorMixin, _get_wsecret
from gateway.platforms.media_cache import ext_for_mime
from gateway import rich_sent_store
+2 -1
View File
@@ -43,9 +43,10 @@ except ImportError:
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, SendResult,
BasePlatformAdapter, SendResult,
cache_document_from_bytes_async, cache_image_from_bytes_async, cache_video_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms import helpers as _mdchunk
from gateway.platforms._shared import get_scoped_secret as _yb_secret
from gateway.platforms.helpers import MessageDeduplicator
+2 -1
View File
@@ -22,8 +22,9 @@ from typing import Any, Callable, Dict, Optional, Tuple, Union
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult,
BasePlatformAdapter, SendResult,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.relay.descriptor import CapabilityDescriptor
from gateway.relay.media import RelayMediaClient
from gateway.relay.transport import RelayTransport
+1 -1
View File
@@ -11,7 +11,7 @@ from __future__ import annotations
from typing import Any, Awaitable, Callable, Dict, Optional, Protocol, runtime_checkable
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.relay.descriptor import CapabilityDescriptor
# Callback the transport invokes for each inbound normalized event.
+1 -1
View File
@@ -20,7 +20,7 @@ import uuid
from dataclasses import dataclass
from typing import Any, Awaitable, Callable, Dict, List, Optional
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
from gateway.relay.descriptor import CapabilityDescriptor
from gateway.relay.transport import InboundHandler
+2 -3
View File
@@ -38,8 +38,8 @@ from agent.conversation_compression import (
from agent.conversation_loop import INTERRUPT_WAITING_FOR_MODEL_PREFIX
from agent.interrupt_compat import request_hard_interrupt
from agent.turn_context import compression_made_progress
from hermes_cli.config import _is_ssh_remote_tilde_cwd, cfg_get
from agent.session_activity import ActivityProvenance
from hermes_cli.config import _is_ssh_remote_tilde_cwd, cfg_get
from hermes_cli.fallback_config import get_fallback_chain
# Per-session AIAgent cache bounds (agents are heavy); see _enforce_agent_cache_cap/_session_housekeeping_watcher.
@@ -2063,10 +2063,9 @@ from gateway.run_goals import GatewayGoalsMixin
from gateway.run_agent_cache import GatewayAgentCacheMixin
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
_reply_anchor_for_event,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.restart import (
DEFAULT_GATEWAY_CRON_DRAIN_TIMEOUT,
DEFAULT_GATEWAY_RESTART_AFTER_TURN_TIMEOUT,
+2 -1
View File
@@ -17,7 +17,8 @@ import time
from agent.i18n import t
from agent.session_activity import format_iteration_progress
from gateway.config import Platform
from gateway.platforms.base import EphemeralReply, MessageEvent, MessageType
from gateway.platforms.base import EphemeralReply
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
from typing import Any, Dict, Optional, Union
+1 -1
View File
@@ -13,7 +13,7 @@ import time
from contextlib import suppress
from typing import TYPE_CHECKING, Any
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
if TYPE_CHECKING: # string annotations only; never imported at runtime (cycle)
from gateway.run import GatewayRunner # noqa: F401
+2 -1
View File
@@ -18,7 +18,8 @@ import re
import time
from contextlib import suppress
from gateway.config import Platform
from gateway.platforms.base import EphemeralReply, MessageEvent, MessageType
from gateway.platforms.base import EphemeralReply
from gateway.platforms.event import MessageEvent, MessageType
from gateway.run_common import _UNSET
from gateway.session import (
SessionSource, is_shared_multi_user_session, neutralize_untrusted_inline_text
+1 -1
View File
@@ -17,7 +17,7 @@ from pathlib import Path
from typing import Any, Dict, Optional, cast
from gateway.config import Platform, _BUILTIN_PLATFORM_VALUES
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionEntry, SessionSource
from gateway.run_shutdown import _log_suppressed, _notice_target_key, _send_error, _send_failed
+2 -1
View File
@@ -18,7 +18,8 @@ from contextlib import suppress
from datetime import datetime
from gateway.config import Platform
from gateway.delivery import looks_like_telegram_private_chat_id
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType
from gateway.platforms.base import BasePlatformAdapter
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
from gateway.restart import (
DEFAULT_GATEWAY_CRON_DRAIN_TIMEOUT, GATEWAY_FATAL_CONFIG_EXIT_CODE, is_global_startup_conflict
+2 -1
View File
@@ -16,7 +16,8 @@ from typing import TYPE_CHECKING, Optional, Tuple
from agent.compaction_display import project_compaction_message_for_display
from agent.i18n import t
from gateway.config import Platform
from gateway.platforms.base import MessageEvent, _prefix_within_utf16_limit, utf16_len
from gateway.platforms.base import _prefix_within_utf16_limit, utf16_len
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
from utils import is_truthy_value
+2 -1
View File
@@ -21,7 +21,8 @@ from contextlib import nullcontext, suppress
from contextvars import copy_context
from gateway.config import Platform
from gateway.media_repair import repair_explicit_computer_use_media_paths
from gateway.platforms.base import BasePlatformAdapter, MessageEvent
from gateway.platforms.base import BasePlatformAdapter
from gateway.platforms.event import MessageEvent
from gateway.session import (
SessionSource, _session_key_namespace, build_channel_continuity_note,
build_session_context,
+2 -1
View File
@@ -18,7 +18,8 @@ from types import SimpleNamespace
from typing import Dict, List, Optional
from gateway.config import Platform
from gateway.platforms.base import MessageEvent, MessageType, build_auto_tts_output_path
from gateway.platforms.base import build_auto_tts_output_path
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
logger = logging.getLogger("gateway.run") # log-record parity with the origin module
+3 -2
View File
@@ -21,7 +21,8 @@ from typing import Optional, Union
from agent.i18n import t
from gateway.config import HomeChannel, Platform, PlatformConfig, persist_home_channel
from gateway.platforms.base import EphemeralReply, MessageEvent
from gateway.platforms.base import EphemeralReply
from gateway.platforms.event import MessageEvent
from gateway.session import AsyncSessionStore
from gateway.session_transcript import TranscriptReadError
from gateway.slash_commands_goals import GatewayGoalCommandsMixin
@@ -1252,7 +1253,7 @@ import hashlib # noqa: F401,E402
_PLUGIN_COMPAT_LAZY = {
'HISTORY_UNREADABLE': ('gateway.slash_commands_status', 'HISTORY_UNREADABLE'),
'MessageType': ('gateway.platforms.base', 'MessageType'),
'MessageType': ('gateway.platforms.event', 'MessageType'),
'SessionSource': ('gateway.session', 'SessionSource'),
'base_url_host_matches': ('utils', 'base_url_host_matches'),
'build_session_key': ('gateway.session', 'build_session_key'),
+1 -1
View File
@@ -6,7 +6,7 @@ from __future__ import annotations
import logging
from agent.i18n import t
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
# Log-record parity with gateway/run.py and the origin module.
logger = logging.getLogger("gateway.run")
+1 -1
View File
@@ -15,7 +15,7 @@ import logging
from typing import Any, Optional
from agent.i18n import t
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from hermes_cli.config import atomic_config_write, clear_model_endpoint_credentials
from utils import base_url_host_matches
+2 -1
View File
@@ -17,7 +17,8 @@ from typing import Optional, Union
from agent.i18n import t
from agent.turn_context import extract_api_content_sidecar
from gateway.config import Platform
from gateway.platforms.base import EphemeralReply, MessageEvent, MessageType
from gateway.platforms.base import EphemeralReply
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key, is_shared_multi_user_session
from gateway.session_transcript import TranscriptReadError
from gateway.slash_commands_status import HISTORY_UNREADABLE
+1 -1
View File
@@ -14,7 +14,7 @@ from typing import Any
from agent.account_usage import fetch_account_usage, render_account_usage_lines
from agent.i18n import t
from gateway.config import Platform
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session_transcript import TranscriptReadError
# Log-record parity with gateway/run.py and the origin module.
+1 -1
View File
@@ -43,7 +43,7 @@ async def deliver_wake(adapter: Any, *, text: str, session_id: str = "", source:
if adapter_supports_push(adapter):
if source is None:
raise ValueError("deliver_wake: push-capable adapter requires a SessionSource")
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
synth_event = MessageEvent(text=text, message_type=MessageType.TEXT, source=source, internal=True)
await adapter.handle_message(synth_event)
return
+2 -1
View File
@@ -23,7 +23,8 @@ from concurrent.futures import TimeoutError as FuturesTimeout
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from typing import Any, Dict, Optional
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.config import Platform
from gateway.platforms._shared import coerce_port as _to_int, profile_scoped as _profile_scoped
+2 -1
View File
@@ -187,8 +187,9 @@ def _scoped_platform_setting(env_name, extra, key):
logger = logging.getLogger(__name__)
from gateway.platforms.base import (
BasePlatformAdapter, CachedMedia, SendResult, MessageEvent, MessageType, cache_media_bytes_async,
BasePlatformAdapter, CachedMedia, SendResult, cache_media_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.config import Platform
+3 -2
View File
@@ -48,7 +48,8 @@ except Exception:
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import MessageDeduplicator, compile_mention_patterns
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
from plugins.platforms.dingtalk.inbound import collect_download_codes, extract_media, extract_text
@@ -764,7 +765,7 @@ EXT_MAP = {
_PLUGIN_COMPAT_LAZY = {
'DINGTALK_TYPE_MAPPING': ('plugins.platforms.dingtalk.inbound', 'DINGTALK_TYPE_MAPPING'),
'MessageType': ('gateway.platforms.base', 'MessageType'),
'MessageType': ('gateway.platforms.event', 'MessageType'),
}
+1 -1
View File
@@ -3,7 +3,7 @@
import json
from typing import Any, List, Optional, Tuple
from gateway.platforms.base import MessageType
from gateway.platforms.event import MessageType
# DingTalk rich-text item type → runtime content type
DINGTALK_TYPE_MAPPING = {"picture": "image", "voice": "audio"}
+2 -1
View File
@@ -261,11 +261,12 @@ from gateway.platforms.helpers import (
)
from utils import atomic_json_write, env_float
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult,
BasePlatformAdapter, SendResult,
cache_image_from_url, cache_image_from_bytes_async, cache_audio_from_url, cache_audio_from_bytes_async,
cache_document_from_bytes_async, SUPPORTED_DOCUMENT_TYPES, _TEXT_INJECT_EXTENSIONS,
_prefix_within_utf16_limit, utf16_len, validate_inbound_media_size,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from tools.url_safety import is_safe_url
from gateway.platforms._shared import profile_scoped as _profile_scoped_config_load
+5 -2
View File
@@ -21,8 +21,11 @@ from email import encoders
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
from gateway.platforms.base import (BasePlatformAdapter, MessageEvent, MessageType, SendResult,
cache_document_from_bytes, cache_image_from_bytes)
from gateway.platforms.base import (
BasePlatformAdapter, SendResult,
cache_document_from_bytes, cache_image_from_bytes,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.config import Platform, PlatformConfig
from utils import is_truthy_value
from gateway.platforms._shared import get_scoped_secret as _get_secret, coerce_port
+2 -1
View File
@@ -82,10 +82,11 @@ FEISHU_WEBHOOK_AVAILABLE = aiohttp is not None
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult,
BasePlatformAdapter, SendResult,
SUPPORTED_DOCUMENT_TYPES, cache_document_from_bytes_async, cache_image_from_url,
cache_audio_from_bytes_async, cache_image_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.status import acquire_scoped_lock, release_scoped_lock
from hermes_constants import get_hermes_home
from utils import atomic_json_write, env_float, env_int
@@ -9,7 +9,7 @@ from dataclasses import dataclass
from types import SimpleNamespace
from typing import Any, Dict, Optional
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
logger = logging.getLogger(__name__)
+2 -1
View File
@@ -124,10 +124,11 @@ from gateway.config import Platform, PlatformConfig
Platform("google_chat")
from gateway.platforms.helpers import MessageDeduplicator
from gateway.platforms.base import (
gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult,
gateway_trust_env, BasePlatformAdapter, SendResult,
cache_audio_from_bytes_async, cache_document_from_bytes_async, cache_image_from_bytes_async,
cache_video_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
# Pinned to the legacy module path so operator log filters keep matching.
logger = logging.getLogger("gateway.platforms.google_chat")
+2 -1
View File
@@ -20,7 +20,8 @@ except ImportError:
aiohttp = None # type: ignore[assignment]
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
logger = logging.getLogger(__name__)
+2 -1
View File
@@ -16,7 +16,8 @@ import time
from typing import Any, Dict, List, Optional
from gateway.platforms._shared import coerce_port, get_scoped_secret as _get_scoped_secret
from gateway.platforms.base import BasePlatformAdapter, SendResult, MessageEvent, MessageType
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.config import Platform
+4 -2
View File
@@ -35,9 +35,11 @@ from urllib.parse import quote as _urlquote
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
from gateway.platforms.base import (
gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult,
gateway_trust_env, BasePlatformAdapter, SendResult,
cache_audio_from_bytes_async, cache_document_from_bytes_async, cache_image_from_bytes_async,
cache_video_from_bytes_async)
cache_video_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.config import Platform
logger = logging.getLogger(__name__)
+4 -2
View File
@@ -58,8 +58,10 @@ except ImportError:
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome,
SendResult, resolve_proxy_url, proxy_kwargs_for_aiohttp, _ssrf_redirect_guard)
gateway_trust_env, BasePlatformAdapter,
SendResult, resolve_proxy_url, proxy_kwargs_for_aiohttp, _ssrf_redirect_guard,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.platforms.helpers import ThreadParticipationTracker
logger = logging.getLogger(__name__)
+2 -1
View File
@@ -22,7 +22,8 @@ from typing import Any, Dict, List, Optional, Tuple
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import MessageDeduplicator
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret, profile_scoped as _profile_scoped_config_load
logger = logging.getLogger(__name__)
+2 -1
View File
@@ -25,7 +25,8 @@ except ImportError:
httpx = None # type: ignore[assignment]
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
logger = logging.getLogger(__name__)
+3 -2
View File
@@ -38,7 +38,8 @@ else:
from gateway.config import Platform, PlatformConfig
from gateway.platforms._shared import coerce_port as _coerce_port
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms.helpers import compile_mention_patterns, strip_markdown
from .auth import load_project_credentials
@@ -1623,7 +1624,7 @@ def register(ctx) -> None:
_PLUGIN_COMPAT_LAZY = {
'ProcessingOutcome': ('gateway.platforms.base', 'ProcessingOutcome'),
'ProcessingOutcome': ('gateway.platforms.event', 'ProcessingOutcome'),
'resolve_sidecar_dir': ('plugins.platforms.photon.sidecar_paths', 'resolve_sidecar_dir'),
}
+2 -1
View File
@@ -37,7 +37,8 @@ except ImportError:
sys.path.insert(0, str(_Path(__file__).resolve().parents[3]))
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult, merge_pending_message_event
from gateway.platforms.base import BasePlatformAdapter, SendResult, merge_pending_message_event
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import build_session_key
from gateway.platforms._shared import coerce_port, profile_scoped as _profile_scoped
+2 -1
View File
@@ -26,7 +26,8 @@ from urllib.parse import unquote
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult, cache_image_from_url
from gateway.platforms.base import BasePlatformAdapter, SendResult, cache_image_from_url
from gateway.platforms.event import MessageEvent, MessageType
logger = logging.getLogger(__name__)
+4 -2
View File
@@ -36,10 +36,12 @@ from agent.secret_scope import UnscopedSecretError, get_secret
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import MessageDeduplicator
from gateway.platforms.base import (
gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome,
gateway_trust_env, BasePlatformAdapter,
SendResult, SUPPORTED_DOCUMENT_TYPES, SUPPORTED_VIDEO_TYPES, _TEXT_INJECT_EXTENSIONS,
is_host_excluded_by_no_proxy, resolve_proxy_url, safe_url_for_log, _ssrf_redirect_guard,
cache_document_from_bytes_async, cache_video_from_bytes_async)
cache_document_from_bytes_async, cache_video_from_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
try: # sibling module; support both package and flat plugin-dir import
from .block_kit import render_blocks, sanitize_blocks
+2 -1
View File
@@ -55,8 +55,9 @@ HttpMethod = str # type: ignore[assignment,misc]
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import MessageDeduplicator
from gateway.platforms.base import (
gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult, cache_image_from_url, cache_media_bytes_async,
gateway_trust_env, BasePlatformAdapter, SendResult, cache_image_from_url, cache_media_bytes_async,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms._shared import coerce_port, get_scoped_secret as _get_scoped_secret
logger = logging.getLogger(__name__)
+4 -2
View File
@@ -142,9 +142,11 @@ sys.path.insert(0, str(_Path(__file__).resolve().parents[3]))
from gateway.authz_mixin import _coerce_allow_set
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult, classify_send_error,
BasePlatformAdapter, SendResult, classify_send_error,
cache_image_from_bytes_async, cache_audio_from_bytes_async, cache_video_from_bytes_async, resolve_proxy_url, SUPPORTED_VIDEO_TYPES,
SUPPORTED_DOCUMENT_TYPES, SUPPORTED_IMAGE_DOCUMENT_TYPES, _TEXT_INJECT_EXTENSIONS, utf16_len)
SUPPORTED_DOCUMENT_TYPES, SUPPORTED_IMAGE_DOCUMENT_TYPES, _TEXT_INJECT_EXTENSIONS, utf16_len,
)
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from plugins.platforms.telegram.telegram_ids import normalize_telegram_chat_id
from plugins.platforms.telegram.telegram_network import (
SEED_FALLBACK_IPS, TelegramFallbackTransport, discover_fallback_ips, parse_fallback_ip_env, tcp_keepalive_socket_options)
+2 -1
View File
@@ -28,7 +28,8 @@ HTTPX_AVAILABLE = httpx is not None
from gateway.config import Platform, PlatformConfig
from gateway.platforms.helpers import MessageDeduplicator
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from utils import env_float
from gateway.platforms._shared import get_scoped_secret as _get_scoped_secret
+2 -1
View File
@@ -32,7 +32,8 @@ except ImportError:
HTTPX_AVAILABLE = False
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from plugins.platforms.wecom.wecom_crypto import WXBizMsgCrypt, WeComCryptoError
logger = logging.getLogger(__name__)
+2 -1
View File
@@ -173,8 +173,9 @@ from gateway.config import Platform, PlatformConfig
from gateway.platforms.whatsapp_common import WhatsAppBehaviorMixin
from gateway.whatsapp_identity import to_whatsapp_jid
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, SendResult, SUPPORTED_DOCUMENT_TYPES, cache_image_from_url, cache_audio_from_url,
BasePlatformAdapter, SendResult, SUPPORTED_DOCUMENT_TYPES, cache_image_from_url, cache_audio_from_url,
)
from gateway.platforms.event import MessageEvent, MessageType
from utils import env_int
+2 -1
View File
@@ -23,7 +23,8 @@ if TYPE_CHECKING:
from gateway.run import GatewayRunner
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, SendResult
from gateway.platforms.base import SendResult
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource, build_session_key
E2E_MESSAGE_SETTLE_DELAY = 0.3
+1 -1
View File
@@ -15,7 +15,7 @@ from __future__ import annotations
from typing import Any, Dict, List, Optional
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.relay.descriptor import CapabilityDescriptor
from gateway.relay.transport import InboundHandler
+4 -4
View File
@@ -109,7 +109,7 @@ class _CaptureTransport:
def _make_event(chat_id="chan-1", scope_id="scope-9"):
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
src = SessionSource(
@@ -123,7 +123,7 @@ def _make_event(chat_id="chan-1", scope_id="scope-9"):
def _make_dm_event(chat_id="dm-1", user_id="user-42"):
"""An inbound DM: no scope_id, carries the authentic author user_id."""
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
src = SessionSource(
@@ -144,7 +144,7 @@ def _make_scoped_event_with_author(
guild scope_id and an author). Used to prove the adapter re-attaches BOTH
discriminators so the connector can fall back author-first when the guild
has no route row (managed agents join guilds dynamically)."""
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
src = SessionSource(
@@ -226,7 +226,7 @@ async def test_send_typing_tags_egress_platform():
"""Phase 1.5: a multi-platform gateway must egress typing through the
platform the chat lives on, exactly like send() — the underlying platform
learned from the inbound event tags the frame."""
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
t = _CaptureTransport()
@@ -18,7 +18,8 @@ import asyncio
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, SessionSource
from gateway.platforms.base import SessionSource
from gateway.platforms.event import MessageEvent
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
from tests.gateway.relay.stub_connector import StubConnector
@@ -25,7 +25,7 @@ from typing import Any, Dict, Optional
import pytest
from gateway.config import PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType, ProcessingOutcome
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
from gateway.session import SessionSource
+1 -1
View File
@@ -136,7 +136,7 @@ async def test_op_gating_falls_back_when_not_advertised(tmp_path: Path):
def _make_event(media_urls):
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
return MessageEvent(
@@ -100,7 +100,7 @@ def test_self_provision_loops_per_platform(monkeypatch):
async def test_adapter_stamps_per_frame_platform_from_inbound(monkeypatch):
"""An inbound from a concrete platform makes the reply egress tagged for it."""
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
from gateway.session import SessionSource
@@ -27,7 +27,7 @@ from typing import Any, Dict, List, Optional
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
from gateway.session import SessionSource
+1 -1
View File
@@ -15,7 +15,7 @@ from __future__ import annotations
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
@@ -22,7 +22,7 @@ from __future__ import annotations
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
@@ -24,7 +24,7 @@ from __future__ import annotations
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
from gateway.session import SessionSource
@@ -28,7 +28,7 @@ from __future__ import annotations
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.relay.adapter import RelayAdapter
from gateway.relay.descriptor import CONTRACT_VERSION, CapabilityDescriptor
from gateway.session import SessionSource
@@ -61,7 +61,7 @@ def _slack_adapter(extra):
def _mark_slack_chat(a, chat_id="chan-1"):
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
src = SessionSource(
@@ -128,7 +128,7 @@ class TestSendStampsUnfurl:
async def test_non_slack_chat_never_stamped(self):
a = _slack_adapter({"slack": {"unfurl_links": False}})
# A chat mapped to discord, not slack, must not carry the hint.
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
src = SessionSource(
+2 -2
View File
@@ -20,7 +20,7 @@ Pure unit tests: no socket, no websockets dependency.
from __future__ import annotations
from gateway.platforms.base import MessageType
from gateway.platforms.event import MessageType
from gateway.relay.ws_transport import _event_from_wire
@@ -329,7 +329,7 @@ class TestParallelArrayLengthInvariant:
with the short list passed through."""
import asyncio
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.relay.adapter import RelayAdapter
ev = MessageEvent(text="", message_type=MessageType.PHOTO)
@@ -29,7 +29,7 @@ import yaml
import pytest
from gateway.config import Platform
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.run import GatewayRunner
from gateway.session import SessionSource
@@ -22,7 +22,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource, build_session_key
@@ -23,7 +23,7 @@ import pytest
import gateway.run as gateway_run
from gateway.config import GatewayConfig, Platform
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource
from gateway.session_transcript import TranscriptReadError
@@ -33,10 +33,9 @@ import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
SendResult,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.run import GatewayRunner, _collect_auto_append_media_tags, _collect_history_media_paths
from gateway.session import SessionSource, build_session_key
@@ -32,10 +32,9 @@ sys.modules.setdefault("telegram.ext", types.ModuleType("telegram.ext"))
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
SendResult,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
+1 -1
View File
@@ -8,7 +8,7 @@ import yaml
import gateway.run as gateway_run
from gateway.config import Platform
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
+1 -1
View File
@@ -17,7 +17,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
@@ -7,7 +7,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from gateway.config import Platform
from gateway.platforms.base import MessageEvent, MessageType
from gateway.platforms.event import MessageEvent, MessageType
from gateway.run import GatewayRunner
from gateway.session import SessionSource
+1 -1
View File
@@ -10,7 +10,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from gateway.config import Platform
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
@@ -19,11 +19,10 @@ import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
SendResult,
build_auto_tts_output_path,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
from tools.tts_tool import OPUS_VOICE_PLATFORMS
+2 -1
View File
@@ -8,7 +8,8 @@ from unittest.mock import AsyncMock, patch
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType, ProcessingOutcome, SendResult
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType, ProcessingOutcome
from gateway.session import SessionSource, build_session_key
@@ -18,7 +18,8 @@ from __future__ import annotations
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType
from gateway.platforms.base import BasePlatformAdapter
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
+1 -1
View File
@@ -28,7 +28,7 @@ from __future__ import annotations
import pytest
from gateway.config import GatewayConfig, Platform
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource, SessionStore, build_session_key
from hermes_state import AsyncSessionDB, SessionDB
+1 -1
View File
@@ -18,7 +18,7 @@ from unittest.mock import AsyncMock, MagicMock
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
+2 -1
View File
@@ -4,7 +4,8 @@ import pytest
import gateway.run as gateway_run
from gateway.config import Platform
from gateway.platforms.base import EphemeralReply, MessageEvent
from gateway.platforms.base import EphemeralReply
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
+1 -2
View File
@@ -25,12 +25,11 @@ sys.modules.setdefault("telegram.constants", _tg.constants)
sys.modules.setdefault("telegram.ext", types.ModuleType("telegram.ext"))
from gateway.platforms.base import (
MessageEvent,
MessageType,
Platform,
SessionSource,
build_session_key,
)
from gateway.platforms.event import MessageEvent, MessageType
# ---------------------------------------------------------------------------
@@ -26,11 +26,10 @@ sys.modules.setdefault("telegram.constants", _tg.constants)
sys.modules.setdefault("telegram.ext", types.ModuleType("telegram.ext"))
from gateway.platforms.base import (
MessageEvent,
MessageType,
SessionSource,
build_session_key,
)
from gateway.platforms.event import MessageEvent, MessageType
# ---------------------------------------------------------------------------
+3 -2
View File
@@ -10,9 +10,10 @@ from types import SimpleNamespace
import pytest
from unittest.mock import AsyncMock, MagicMock
from gateway.platforms.base import CachedMedia, MessageType
from gateway.platforms.base import CachedMedia
from gateway.platforms.event import MessageType
from tests.gateway._plugin_adapter_loader import load_plugin_adapter
from gateway.platforms.base import MessageType
from gateway.platforms.event import MessageType
# Load plugins/platforms/buzz/adapter.py under a unique module name
# (plugin_adapter_buzz) so it cannot collide with other plugin adapters
@@ -14,7 +14,8 @@ from unittest.mock import AsyncMock
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType
from gateway.platforms.base import BasePlatformAdapter
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
+2 -1
View File
@@ -15,7 +15,8 @@ import yaml
import gateway.run as gateway_run
from gateway.config import Platform
from gateway.platforms.base import MessageEvent, SendResult
from gateway.platforms.base import SendResult
from gateway.platforms.event import MessageEvent
from gateway.session import SessionSource
@@ -8,10 +8,9 @@ import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
SendResult,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
@@ -26,10 +26,9 @@ import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
SendResult,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource
@@ -17,7 +17,8 @@ import asyncio
import pytest
from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageType
from gateway.platforms.base import BasePlatformAdapter
from gateway.platforms.event import MessageEvent, MessageType
from gateway.session import SessionSource, build_session_key
+1 -1
View File
@@ -8,7 +8,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource, build_session_key
+1 -1
View File
@@ -6,7 +6,7 @@ from unittest.mock import MagicMock, patch
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource, build_session_key
+1 -1
View File
@@ -22,7 +22,7 @@ import pytest
from agent.context_engine import ContextEngine
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource, build_session_key
+1 -1
View File
@@ -12,7 +12,7 @@ from unittest.mock import MagicMock
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.session import SessionEntry, SessionSource, build_session_key
@@ -28,12 +28,11 @@ sys.modules.setdefault("telegram", _tg)
sys.modules.setdefault("telegram.constants", _tg.constants)
sys.modules.setdefault("telegram.ext", types.ModuleType("telegram.ext"))
from gateway.platforms.base import ( # noqa: E402
MessageEvent,
MessageType,
from gateway.platforms.base import (
SessionSource,
build_session_key,
)
from gateway.platforms.event import MessageEvent, MessageType
from gateway.run import GatewayRunner, _AGENT_PENDING_SENTINEL # noqa: E402
@@ -25,7 +25,7 @@ import pytest
import gateway.run as gateway_run
from agent.context_references import ContextReferenceResult
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.platforms.base import MessageEvent
from gateway.platforms.event import MessageEvent
from gateway.run import GatewayRunner
from gateway.session import SessionSource

Some files were not shown because too many files have changed in this diff Show More