4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
89 lines
4.0 KiB
Markdown
89 lines
4.0 KiB
Markdown
|
|
## Architecture Notes By Vincent (June 30th 2026)
|
|
- Target initial support for Telegram and Slack.
|
|
- Issues: Headless agent lacks full integration initialization; current target path may not be optimal.
|
|
- Treat the messaging gateway as a distinct surface area.
|
|
- Goal: Fully decouple the gateway from other packages --> if this is true then it means that the gateway is configurable through dependency injection to call other agents.
|
|
|
|
**Key Problem Right Now**
|
|
- The critical problem however, right now is that we need to be able to spin up an agent and load integrations from it.
|
|
|
|
# OpenSRE Messaging Gateway
|
|
|
|
Standalone inbound messaging gateway for chat platforms. v1 ships Telegram DM text chat via long polling.
|
|
|
|
## How the pieces fit (surfaces, gateway, integrations)
|
|
|
|
Three things that are easy to mix up:
|
|
|
|
- **Surface** — a way a person talks *to* the agent (message in, answer out). Today
|
|
there are three: the interactive shell (`surfaces/interactive_shell`, you type in
|
|
a terminal), the CLI one-shot (`surfaces/cli`, one command → one answer), and the
|
|
**gateway** (`gateway/`, you chat with the agent from a chat app).
|
|
- **Gateway** — one specific surface: the always-on process that connects a chat app
|
|
to the agent. Right now it speaks **Telegram only**.
|
|
- **Integrations + tools** — the *outbound* side: the agent sending a message *out*
|
|
to a channel. `integrations/telegram` and `integrations/slack` deliver messages;
|
|
the agent calls the `telegram_send_message` / `slack_send_message` tools to do it.
|
|
|
|
So the two platforms are not symmetric today:
|
|
|
|
| | Inbound (person → agent) | Outbound (agent → channel) |
|
|
|---|---|---|
|
|
| **Telegram** | Yes — the gateway | Yes — integration + tool |
|
|
| **Slack** | Not yet — `surfaces/slack_app` is an empty stub | Yes — integration + tool |
|
|
|
|
A person can already receive messages the agent *sends* to Slack, but cannot yet
|
|
*chat to* the agent from Slack.
|
|
|
|
**One core for every surface.** Shell, CLI, and the Telegram gateway all hand the
|
|
message to the same place: a `HeadlessAgent` (`agent.dispatch(message)`). They differ
|
|
only in *how they receive input and send output* — never in how the agent thinks.
|
|
|
|
## Quick start
|
|
|
|
```bash
|
|
# Allow your Telegram user id (from @userinfobot)
|
|
uv run opensre messaging allow -p telegram -u 123456789
|
|
|
|
# Start the gateway daemon (web app + Telegram chat + task scheduler)
|
|
uv run opensre gateway start
|
|
```
|
|
|
|
DM your bot from Telegram.
|
|
|
|
|
|
## Environment variables
|
|
|
|
| Variable | Purpose |
|
|
|----------|---------|
|
|
| `TELEGRAM_BOT_TOKEN` | Bot token |
|
|
| `TELEGRAM_ALLOWED_USERS` | Comma-separated Telegram user ids |
|
|
| `TELEGRAM_GATEWAY_MAX_CONCURRENT` | Parallel turns across chats (default 4) |
|
|
|
|
Pairing via `opensre messaging pair` uses the same integration-store policy as the gateway.
|
|
|
|
## Adding a chat platform (e.g. Slack inbound)
|
|
|
|
The message handler is already **transport-agnostic** — it takes
|
|
`(text, session, sink, logger)` and knows nothing about Telegram. So to add Slack
|
|
inbound you do **not** touch the agent, prompts, or tools. You add three small
|
|
pieces, the same shape Telegram already has:
|
|
|
|
1. **A listener** (like `start_telegram_worker` in `gateway/telegram_gateway.py`):
|
|
receives incoming Slack messages (Slack Events API or Socket Mode) and calls the
|
|
shared handler with `(text, session, sink, logger)`.
|
|
2. **An output sink** (implement `GatewayOutputSink` from
|
|
`gateway/gateway_output_sink.py`): its `stream()` / `finalize()` send text back to
|
|
the Slack channel via `integrations/slack/delivery.py`.
|
|
3. **A session resolver** (like `gateway/storage/session/resolver.py`): map a Slack
|
|
user + channel to a `Session`.
|
|
|
|
Then wire it in the composition root (`GatewayManager` in `gateway/manager.py`):
|
|
start the Slack listener next to (or instead of) Telegram. Reuse the handler from
|
|
`GatewayTurnHandler(...)` as-is.
|
|
|
|
**What you never change:** `GatewayTurnHandler`, `Agent`, prompts, tools.
|
|
Keeping the handler transport-agnostic is exactly what makes a new platform a small,
|
|
self-contained add.
|