feat: implement channel runtime connectors
This commit is contained in:
@ -0,0 +1,138 @@
|
||||
"""Shared helpers for platform channel adapters."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from beaver.foundation.events import ChannelIdentity, InboundMessage, OutboundMessage
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class OutboundTarget:
|
||||
peer_id: str | None
|
||||
thread_id: str | None = None
|
||||
peer_type: str = "unknown"
|
||||
user_id: str | None = None
|
||||
|
||||
|
||||
class PlatformDeliveryError(RuntimeError):
|
||||
"""Raised when a platform client rejects a delivery."""
|
||||
|
||||
|
||||
def config_bool(config: dict[str, Any], key: str, *, default: bool = False) -> bool:
|
||||
value = config.get(key)
|
||||
if value is None:
|
||||
return default
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
if isinstance(value, (int, float)):
|
||||
return bool(value)
|
||||
text = str(value).strip().lower()
|
||||
if text in {"1", "true", "yes", "on"}:
|
||||
return True
|
||||
if text in {"0", "false", "no", "off"}:
|
||||
return False
|
||||
return default
|
||||
|
||||
|
||||
def config_list(config: dict[str, Any], key: str) -> list[str]:
|
||||
value = config.get(key)
|
||||
if value is None:
|
||||
return []
|
||||
if isinstance(value, str):
|
||||
return [part.strip() for part in value.split(",") if part.strip()]
|
||||
if isinstance(value, (list, tuple, set)):
|
||||
return [str(item).strip() for item in value if str(item).strip()]
|
||||
text = str(value).strip()
|
||||
return [text] if text else []
|
||||
|
||||
|
||||
def chunk_text(text: str, *, max_chars: int) -> list[str]:
|
||||
if max_chars <= 0:
|
||||
raise ValueError("max_chars must be positive")
|
||||
if not text:
|
||||
return [""]
|
||||
return [text[index : index + max_chars] for index in range(0, len(text), max_chars)]
|
||||
|
||||
|
||||
def compact_media_summary(media_type: str, *, file_name: str | None = None) -> str:
|
||||
label = str(media_type or "attachment").strip() or "attachment"
|
||||
if file_name:
|
||||
return f"[{label}: {file_name}]"
|
||||
return f"[{label}]"
|
||||
|
||||
|
||||
def target_from_session_id(session_id: str | None) -> OutboundTarget:
|
||||
if not session_id:
|
||||
return OutboundTarget(peer_id=None)
|
||||
parts = str(session_id).split(":")
|
||||
if len(parts) < 3:
|
||||
return OutboundTarget(peer_id=None)
|
||||
thread_id = parts[3] if len(parts) > 3 and parts[3] else None
|
||||
return OutboundTarget(peer_id=parts[2] or None, thread_id=thread_id)
|
||||
|
||||
|
||||
def outbound_target(message: OutboundMessage) -> OutboundTarget:
|
||||
identity = message.channel_identity
|
||||
if identity is None:
|
||||
return target_from_session_id(message.session_id)
|
||||
return OutboundTarget(
|
||||
peer_id=identity.peer_id,
|
||||
thread_id=identity.thread_id,
|
||||
peer_type=identity.peer_type,
|
||||
user_id=identity.user_id,
|
||||
)
|
||||
|
||||
|
||||
def mark_unclaimed(message: OutboundMessage) -> None:
|
||||
message.metadata["delivery_status"] = "unclaimed"
|
||||
|
||||
|
||||
def build_inbound_message(
|
||||
*,
|
||||
channel_id: str,
|
||||
kind: str,
|
||||
account_id: str,
|
||||
peer_id: str,
|
||||
content: str,
|
||||
message_id: str | None,
|
||||
peer_type: str,
|
||||
user_id: str | None = None,
|
||||
thread_id: str | None = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
) -> InboundMessage:
|
||||
identity = ChannelIdentity(
|
||||
channel_id=channel_id,
|
||||
kind=kind,
|
||||
account_id=account_id,
|
||||
peer_id=peer_id,
|
||||
thread_id=thread_id,
|
||||
peer_type=peer_type,
|
||||
user_id=user_id,
|
||||
message_id=message_id,
|
||||
)
|
||||
return InboundMessage(
|
||||
channel=channel_id,
|
||||
content=content,
|
||||
session_id=identity.session_id(),
|
||||
user_id=user_id,
|
||||
message_id=message_id or "",
|
||||
channel_identity=identity,
|
||||
metadata=metadata or {},
|
||||
)
|
||||
|
||||
|
||||
def allowed_by_policy(
|
||||
*,
|
||||
policy: str | None,
|
||||
identifier: str | None,
|
||||
allowlist: list[str],
|
||||
default: str = "open",
|
||||
) -> bool:
|
||||
effective = (policy or default).strip().lower()
|
||||
if effective == "disabled":
|
||||
return False
|
||||
if effective == "allowlist":
|
||||
return bool(identifier and identifier in allowlist)
|
||||
return True
|
||||
Reference in New Issue
Block a user