Chuyển tới nội dung chính

Nội bộ cổng

Cổng nhắn tin là một quy trình dài hạn kết nối Hermes với hơn 20 nền tảng nhắn tin bên ngoài thông qua một kiến trúc thống nhất.

Tệp chính

Tập tinMục đích
`gateway/run.py
`
`GatewayRunner
  • vòng lặp chính, lệnh gạch chéo, gửi tin nhắn (tệp lớn; kiểm tra git để tìm LỘC hiện tại) | | gateway/session.py | SessionStore — tính bền vững của cuộc trò chuyện và xây dựng khóa phiên | | gateway/delivery.py | Gửi tin nhắn đi tới các nền tảng/kênh mục tiêu | | gateway/pairing.py | Luồng ghép nối DM để ủy quyền người dùng | | gateway/channel_directory.py | Ánh xạ ID trò chuyện thành tên mà con người có thể đọc được để phân phối định kỳ | | gateway/hooks.py | Khám phá móc, tải và gửi sự kiện trong vòng đời | | gateway/mirror.py | Phản chiếu tin nhắn giữa các phiên cho send_message | | gateway/status.py | Quản lý khóa mã thông báo cho các phiên bản cổng có phạm vi hồ sơ | | gateway/builtin_hooks/ | Điểm mở rộng cho các móc luôn được đăng ký (không được vận chuyển) | | gateway/platforms/ | Bộ điều hợp nền tảng (một bộ điều hợp cho mỗi nền tảng nhắn tin) |

Tổng quan về kiến trúc

┌─────────────────────────────────────────────────┐
│ GatewayRunner │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Telegram │ │ Discord │ │ Slack │ │
│ │ Adapter │ │ Adapter │ │ Adapter │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └─────────────┼─────────────┘ │
│ ▼ │
│ _handle_message() │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ Slash command AIAgent Queue/BG │
│ dispatch creation sessions │
│ │ │
│ ▼ │
│ SessionStore │
│ (SQLite persistence) │
└───────┴─────────────┴─────────────┴─────────────┘

`

## Luồng tin nhắn

Khi có tin nhắn đến từ bất kỳ nền tảng nào:
1. **Bộ điều hợp nền tảng** nhận sự kiện thô, chuẩn hóa nó thành
`MessageEvent

`
2. **Bộ điều hợp cơ sở** kiểm tra bảo vệ phiên hoạt động:
- Nếu tác nhân đang chạy trong phiên này → thông báo xếp hàng, hãy đặt sự kiện ngắt
- Nếu

/approve

,

/deny

,

/stop
` → bỏ qua bảo vệ (gửi nội tuyến)
3. **GatewayRunner._handle_message()** nhận được sự kiện:
- Giải quyết khóa phiên thông qua
`_session_key_for_source()
` (định dạng:
`agent:main:\{platform}:\{chat_type}:\{chat_id}

)
- Kiểm tra ủy quyền (xem Ủy quyền bên dưới)
- Kiểm tra xem đó có phải là lệnh gạch chéo không → gửi đến trình xử lý lệnh
- Kiểm tra xem tác nhân đã chạy chưa → chặn các lệnh như

/stop

,

/status

- Ngược lại → tạo phiên bản
`AIAgent
` và chạy hội thoại
4. **Phản hồi** được gửi lại thông qua bộ chuyển đổi nền tảng

### Định dạng khóa phiên

Khóa phiên mã hóa bối cảnh định tuyến đầy đủ:

`
agent:main:\{platform}:\{chat_type}:\{chat_id}

`
``Ví dụ:
`agent:main:Telegram:private:123456789
``Các nền tảng nhận biết luồng (chủ đề diễn đàn Telegram, luồng Discord, luồng Slack) có thể bao gồm ID luồng trong phần chat_id. **Không bao giờ tạo khóa phiên theo cách thủ công** — luôn sử dụng
`build_session_key()
` từ
`gateway/session.py

.

### Bảo vệ tin nhắn hai cấp

Khi một tác nhân đang hoạt động tích cực, các tin nhắn đến sẽ đi qua hai bộ bảo vệ tuần tự:
1. **Cấp 1 — Bộ điều hợp cơ sở** (
`gateway/platforms/base.py

): Kiểm tra
`_active_sessions

. Nếu phiên đang hoạt động, hãy xếp hàng tin nhắn trong
`_pending_messages
` và đặt sự kiện ngắt. Điều này sẽ bắt các tin nhắn *trước khi* chúng đến được người chạy cổng.
2. **Cấp 2 — Cổng chạy** (
`gateway/run.py

): Kiểm tra
`_running_agents

. Chặn các lệnh cụ thể (

/stop

,

/new

,

/queue

,

/status

,

/approve

,

/deny

) và định tuyến chúng một cách thích hợp. Mọi thứ khác đều kích hoạt
`running_agent.interrupt()

.

Các lệnh phải đến được người chạy trong khi tác nhân bị chặn (như

/approve

) được gửi **nội tuyến** thông qua
`await self._message_handler(event)
` — chúng bỏ qua hệ thống tác vụ nền để tránh các điều kiện chạy đua.

## Ủy quyền

Cổng sử dụng kiểm tra ủy quyền nhiều lớp, được đánh giá theo thứ tự:
1. **Cờ cho phép tất cả trên mỗi nền tảng** (ví dụ:
`Telegram_ALLOW_ALL_USERS

) — nếu được đặt, tất cả người dùng trên nền tảng đó đều được ủy quyền
2. **Danh sách cho phép nền tảng** (ví dụ:
`Telegram_ALLOWED_USERS

) — ID người dùng được phân tách bằng dấu phẩy
3. **Ghép nối DM** — người dùng đã xác thực có thể ghép nối người dùng mới thông qua mã ghép nối
4. **Cho phép tất cả toàn cầu** (
`GATEWAY_ALLOW_ALL_USERS

) — nếu được đặt, tất cả người dùng trên tất cả các nền tảng đều được ủy quyền
5. **Mặc định: từ chối** — người dùng trái phép sẽ bị từ chối

### Luồng ghép nối DM

``` text
Admin: /pair
Gateway: "Pairing code: ABC123. Share with the user."
New user: ABC123
Gateway: "Paired! You're now authoriZed."

`
``Trạng thái ghép nối vẫn được duy trì trong
`gateway/pairing.py
` và vẫn tồn tại sau khi khởi động lại.

## Gửi lệnh gạch chéo

Tất cả các lệnh gạch chéo trong cổng đều đi qua cùng một đường dẫn phân giải:
1.
`resolve_command()
` từ
`Hermes_CLI/commands.py
` ánh xạ đầu vào thành tên chuẩn (xử lý bí danh, khớp tiền tố)

2. Tên chuẩn được kiểm tra theo
`GATEWAY_KNOWN_COMMANDS

3. Trình xử lý trong các công văn
`_handle_message()
` dựa trên tên chuẩn
4. Một số lệnh được kiểm soát trên config (
`gateway_config_gate
` trên
`CommandDef

)

### Người bảo vệ đặc vụ đang chạy

Các lệnh KHÔNG được thực thi trong khi tác nhân đang xử lý sẽ bị từ chối sớm:

``` python
if _quick_key in self._running_agents:
if canonical == "model":
return "⏳ Agent is running — wait for it to finish or /stop first."

`
`Các lệnh bỏ qua (

/stop

,

/new

,

/approve

,

/deny

,

/queue

,

/status

) có cách xử lý đặc biệt.

## Nguồn cấu hình

Cổng đọc cấu hình từ nhiều nguồn:

| Nguồn | Nó cung cấp những gì |
|--------|-------------------|
|

~/.Hermes/.env
` | Khóa API, mã thông báo bot, thông tin xác thực nền tảng |
|

~/.Hermes/config.yaml
` | Cài đặt mô hình, cấu hình công cụ, tùy chọn hiển thị |
| Biến môi trường | Ghi đè bất kỳ mục nào ở trên |

Không giống như CLI (sử dụng
`load_CLI_config()
` với các giá trị mặc định được mã hóa cứng), cổng đọc
`config.yaml
` trực tiếp thông qua trình tải YAML. Điều này có nghĩa là các khóa cấu hình tồn tại trong lệnh mặc định của CLI nhưng không có trong tệp cấu hình của người dùng có thể hoạt động khác nhau giữa CLI và cổng.

## Bộ điều hợp nền tảng

Mỗi nền tảng nhắn tin có một bộ chuyển đổi trong
`gateway/platforms/

:

`text
gateway/platforms/
├── base.py # BaseAdapter — shared logic for all platforms
├── Telegram.py # Telegram Bot API (long polling or webhook)
├── Discord.py # Discord bot via Discord.py
├── Slack.py # Slack Socket Mode
├── WhatsApp.py # WhatsApp Business Cloud API
├── Signal.py # Signal via Signal-CLI REST API
├── Matrix.py # Matrix via mautrix (optional E2EE)
├── Mattermost.py # Mattermost WebSocket API
├── email.py # Email via IMAP/SMTP
├── sms.py # SMS via Twilio
├── DingTalk.py # DingTalk WebSocket
├── Feishu.py # Feishu/Lark WebSocket or webhook
├── WeCom.py # WeCom (WeChat Work) callback
├── weixin.py # Weixin (personal WeChat) via iLink Bot API
├── BlueBubbles.py # Apple iMessage via BlueBubbles macOS server
├── qqbot/ # QQ Bot (Tencent QQ) via Official API v2 (sub-package: adapter.py, crypto.py, keyboards.py, …)
├── yuanbao.py # Yuanbao (Tencent) DM/group adapter
├── Feishu_comment.py # Feishu document/drive comment-reply handler
├── msgraph_webhook.py # Microsoft Graph change-notification webhook (Teams, Outlook, etc.)
├── webhook.py # Inbound/outbound webhook adapter
├── API_server.py # REST API server adapter
└── homeassistant.py # Home Assistant conversation integration

`
``Bộ điều hợp thực hiện một giao diện chung:

-
`connect()
` /
`disconnect()
` — quản lý vòng đời
-
`send_message()

- gửi tin nhắn đi
-
`on_message()
` — chuẩn hóa tin nhắn gửi đến →
`MessageEvent

### Khóa mã thông báo

Bộ điều hợp kết nối với thông tin xác thực duy nhất gọi
`acquire_scoped_lock()
` trong
`connect()
` và
`release_scoped_lock()
` trong
`disconnect()

. Điều này ngăn hai hồ sơ sử dụng cùng một mã thông báo bot.

## Đường dẫn giao hàng

Việc giao hàng đi (
`gateway/delivery.py

) xử lý:
- **Trả lời trực tiếp** — gửi phản hồi trở lại cuộc trò chuyện ban đầu
- **Phân phối kênh gia đình** — định tuyến kết quả công việc định kỳ và kết quả nền tới kênh chính đã được định cấu hình
- **Phân phối mục tiêu rõ ràng** — Công cụ
`send_message
` chỉ định
`Telegram:-1001234567890
` hoặc [XPROTECTX78XPROTECTX CLI](/docs/guides/pipe-script-output) gói cùng một công cụ cho tập lệnh shell
- **Phân phối đa nền tảng** — phân phối tới một nền tảng khác với tin nhắn ban đầu

Việc phân phối công việc định kỳ KHÔNG được phản ánh vào lịch sử phiên cổng - chúng chỉ tồn tại trong phiên định kỳ của riêng chúng. Đây là sự lựa chọn thiết kế có chủ ý để tránh vi phạm việc luân phiên thông báo.

## Móc

Móc cổng là các mô-đun Python phản hồi các sự kiện trong vòng đời:

### Sự kiện móc cổng

| Sự kiện | Khi bị sa thải |
|-------|----------|
|
`gateway:startup
` | Quá trình cổng bắt đầu |
|
`session:start
` | Phiên trò chuyện mới bắt đầu |
|
`session:end
` | Phiên hoàn thành hoặc hết thời gian |
|
`session:reset
` | Người dùng đặt lại phiên với

/new
` |
|
`agent:start
` | Đại lý bắt đầu xử lý tin nhắn |
|
`agent:step
` | Đại lý hoàn thành một lần lặp gọi công cụ |
|
`agent:end
` | Đại lý kết thúc và trả lời phản hồi |
|
`command:*
` | Bất kỳ lệnh gạch chéo nào đều được thực thi |

Các móc nối được phát hiện từ
`gateway/builtin_hooks/
` (một điểm mở rộng — hiện trống trong bản phân phối được vận chuyển;
`_register_builtin_hooks()
` là một bản sơ khai không hoạt động) và

~/.Hermes/hooks/
` (do người dùng cài đặt). Mỗi hook là một thư mục có tệp kê khai
`HOOK.YAML
` và
`handler.py

.

## Tích hợp nhà cung cấp bộ nhớ

Khi plugin nhà cung cấp bộ nhớ (ví dụ: Honcho) được bật:
1. Cổng tạo
`AIAgent
` cho mỗi tin nhắn có ID phiên
2.
`MemoryManager
` khởi tạo nhà cung cấp với ngữ cảnh phiên
3. Các công cụ của nhà cung cấp (ví dụ:
`Honcho_profile

,
`viking_search

) được định tuyến thông qua:

``` text
AIAgent._invoke_tool()
→ self._memory_manager.handle_tool_call(name, args)
→ provider.handle_tool_call(name, args)

`

4. Khi kết thúc/đặt lại phiên,
`on_session_end()
` sẽ kích hoạt để dọn dẹp và xóa dữ liệu cuối cùng

### Vòng đời xóa bộ nhớ

Khi một phiên được đặt lại, tiếp tục hoặc hết hạn:

1. Bộ nhớ tích hợp được xóa vào đĩa
2. Móc
`on_session_end()
` của nhà cung cấp bộ nhớ kích hoạt
3.
`AIAgent
` tạm thời chạy lượt hội thoại chỉ trong bộ nhớ
4. Ngữ cảnh sau đó sẽ bị loại bỏ hoặc lưu trữ

## Bảo trì nền

Cổng này chạy bảo trì định kỳ cùng với việc xử lý tin nhắn:
- **Cron tích tắc** — kiểm tra lịch trình công việc và sa thải công việc đến hạn
- **Phiên hết hạn** — dọn sạch các phiên bị bỏ rơi sau khi hết thời gian chờ
- **Xóa bộ nhớ** — chủ động xóa bộ nhớ trước khi hết phiên
- **Làm mới bộ đệm** — làm mới danh sách mô hình và trạng thái nhà cung cấp

## Quản lý quy trình

Cổng hoạt động như một quy trình lâu dài, được quản lý thông qua:
-
`Hermes gateway start
` /
`Hermes gateway stop
` — điều khiển bằng tay
-
`systemctl
` (Linux) hoặc
`launchctl
` (macOS) — quản lý dịch vụ
- Tệp PID tại

~/.Hermes/gateway.pid

- theo dõi quy trình trong phạm vi hồ sơ**Trong phạm vi hồ sơ so với toàn cầu**:
`start_gateway()
` sử dụng các tệp PID trong phạm vi hồ sơ.
`Hermes gateway stop
` chỉ dừng cổng của cấu hình hiện tại.
`Hermes gateway stop --all
` sử dụng tính năng quét
`ps aux
` toàn cầu để loại bỏ tất cả các quy trình cổng (được sử dụng trong quá trình cập nhật).

## Tài liệu liên quan
- [Session Storage](./session-storage.md)
- [Cron Internals](./cron-internals.md)
- [ACP Internals](./ACP-internals.md)
- [Agent Loop Internals](./agent-loop.md)
- [Messaging Gateway (User Guide)](/docs/user-guide/messaging)