Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
97d182d
Fix: included IMPORT_KB_ON_START as default to be 0 for autotests
blackhammer116 Jun 10, 2026
23aa068
Chore: kept entrypoint and import-knowledge script separate, added a …
blackhammer116 Jun 10, 2026
5906729
Fix: fixed some typo errors
blackhammer116 Jun 10, 2026
2b66c73
chore: moved import-kb script into scripts folder
blackhammer116 Jun 10, 2026
93cb43a
Fix: fixed some typo error
blackhammer116 Jun 10, 2026
a3cc4d2
Chore: cleaned up the code , added comments and improved README
blackhammer116 Jun 11, 2026
e1dba09
Fix: moved EMBEDDING_PROVIDER def into entrypoint because it couldn't…
blackhammer116 Jun 11, 2026
391cd64
chore: removed white space
blackhammer116 Jun 11, 2026
98416fa
chore: removed whitespace
blackhammer116 Jun 11, 2026
65a54a2
Feat: added options inside omegaclaw script
blackhammer116 Jun 11, 2026
1844865
Fix: fixed some typo in README and made import-kb prompt more readable
blackhammer116 Jun 11, 2026
02abd55
Remove embeddingprovider environment variable
vsbogd Jun 11, 2026
f157c37
refactor(channels): introduce BaseChannel and channels registry for D…
Bereket-Eshete Jun 20, 2026
80a6a30
refactor(channels.metta): simplify channel config and dispatch via ch…
Bereket-Eshete Jun 20, 2026
1218e86
Merge remote-tracking branch 'core/main' into feat/comm-API
blackhammer116 Jun 22, 2026
8b86b9b
fix(channels): preserve proxy-based auth after channel refactor
Bereket-Eshete Jun 24, 2026
2176049
fix: restore auth gate and fix proxy token order
Bereket-Eshete Jun 25, 2026
041bc50
Merge pull request #34 from Bereket-Eshete/feat/channel-refactor
blackhammer116 Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions channels/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import abc
import threading

import auth


class BaseChannel(abc.ABC):
def __init__(self):
self._last_message = ""
self._msg_lock = threading.Lock()

self._authenticated_id = None
self._auth_lock = threading.Lock()

self._running = False
self._connected = False
self._thread = None

def _set_last(self, msg: str) -> None:
with self._msg_lock:
if self._last_message == "":
self._last_message = msg
else:
self._last_message = self._last_message + " | " + msg

def getLastMessage(self) -> str:
with self._msg_lock:
tmp = self._last_message
self._last_message = ""
return tmp

@staticmethod
def _parse_auth_candidate(msg: str) -> str:
text = msg.strip()
lower = text.lower()
if lower.startswith("auth "):
return text[5:].strip()
if lower.startswith("/auth "):
return text[6:].strip()
return text

@staticmethod
def _is_auth_command(msg: str) -> bool:
lower = msg.strip().lower()
return lower.startswith("auth ") or lower.startswith("/auth ")

def _is_allowed_message(self, sender_id: str, msg: str) -> str:
with self._auth_lock:
if not auth.is_auth_enabled():
return "allow"
if self._authenticated_id is not None:
return "allow" if sender_id == self._authenticated_id else "ignore"
if not self._is_auth_command(msg):
return "ignore"
candidate = self._parse_auth_candidate(msg)
if auth.verify_token(candidate):
self._authenticated_id = sender_id
return "auth_bound"
return "ignore"

def start(self) -> threading.Thread:
self._running = True
self._connected = False
self._thread = threading.Thread(target=self._run_loop, daemon=True)
self._thread.start()
return self._thread

def stop(self) -> None:
self._running = False

@abc.abstractmethod
def _run_loop(self) -> None: ...

@abc.abstractmethod
def send_message(self, text: str) -> None: ...
66 changes: 66 additions & 0 deletions channels/channels_registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import importlib
import os

_REGISTRY = {
"irc": (
"channels.irc", "start_irc",
lambda token, channel_id, poll_interval, server_url: (
channel_id or "##omegaclaw",
server_url or "irc.quakenet.org",
int(os.environ.get("IRC_PORT", "6667")),
os.environ.get("IRC_USER", "omegaclaw"),
),
),
"telegram": (
"channels.telegram", "start_telegram",
lambda token, channel_id, poll_interval, server_url: (
token or os.environ.get("TG_BOT_TOKEN", ""),
channel_id,
poll_interval,
),
),
"slack": (
"channels.slack", "start_slack",
lambda token, channel_id, poll_interval, server_url: (
token or os.environ.get("SL_BOT_TOKEN", ""),
channel_id,
poll_interval,
),
),
"mattermost": (
"channels.mattermost", "start_mattermost",
lambda token, channel_id, poll_interval, server_url: (
server_url or "https://chat.singularitynet.io",
channel_id or "8fjrmabjx7gupy7e5kjznpt5qh",
token or os.environ.get("MM_BOT_TOKEN", ""),
),
),
"mock": (
"channels.mock", "start_mock",
lambda token, channel_id, poll_interval, server_url: (),
),
}

_active_module = None


def start(channel_name: str, token="", channel_id="", poll_interval=20, server_url=""):
global _active_module
channel_name = str(channel_name)
entry = _REGISTRY.get(channel_name)
if not entry:
raise ValueError(f"Unknown channel: {channel_name}")
module_path, start_fn, args_fn = entry
args = args_fn(str(token), str(channel_id), int(poll_interval), str(server_url))
mod = importlib.import_module(module_path)
_active_module = mod
return getattr(mod, start_fn)(*args)


def getLastMessage() -> str:
return _active_module.getLastMessage() if _active_module else ""


def send_message(text: str) -> None:
if _active_module:
_active_module.send_message(text)
Loading
Loading