mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-16 14:57:15 +00:00
fix(4.11): align omni adapters and EventProcessor marketplace support
This commit is contained in:
@@ -4,17 +4,17 @@ Date: May 10, 2026
|
||||
|
||||
Scope:
|
||||
|
||||
- `telegram-eba`
|
||||
- `discord-eba`
|
||||
- `aiocqhttp-eba`
|
||||
- `dingtalk-eba`
|
||||
- `lark-eba`
|
||||
- `wecom-eba`
|
||||
- `wecombot-eba`
|
||||
- `wecomcs-eba`
|
||||
- `officialaccount-eba`
|
||||
- `qqofficial-eba`
|
||||
- `slack-eba`
|
||||
- `telegram-omni`
|
||||
- `discord-omni`
|
||||
- `aiocqhttp-omni`
|
||||
- `dingtalk-omni`
|
||||
- `lark-omni`
|
||||
- `wecom-omni`
|
||||
- `wecombot-omni`
|
||||
- `wecomcs-omni`
|
||||
- `officialaccount-omni`
|
||||
- `qqofficial-omni`
|
||||
- `slack-omni`
|
||||
|
||||
This report follows `acceptance-checklist.md`. Evidence levels are intentionally strict:
|
||||
|
||||
@@ -72,7 +72,7 @@ All four adapters deliver common SDK entities to plugins before LangBot core/plu
|
||||
| Requirement | Telegram | Discord | aiocqhttp | DingTalk | Lark / Feishu |
|
||||
|-------------|----------|---------|-----------|----------|---------------|
|
||||
| `bot_uuid` filled | plugin-e2e | plugin-e2e | plugin-e2e | plugin-e2e | live plugin-e2e pending |
|
||||
| `adapter_name` filled | `telegram` | `discord` | `aiocqhttp` | `dingtalk` | `lark-eba` in current unit/code; older live text evidence recorded `lark` before the naming fix |
|
||||
| `adapter_name` filled | `telegram` | `discord` | `aiocqhttp` | `dingtalk` | `lark-omni` in current unit/code; older live text evidence recorded `lark` before the naming fix |
|
||||
| common `MessageChain` delivered | `Plain`, group `At + Plain`, private `Image`, private `File` | `Source + Plain` | UI `Source + Plain`; protocol `Source + Plain + At + Face + Image + Voice + File + Quote + Plain` | `Source + Plain`, private `Source + Image`, private `Source + File` | live private `Source + Plain`; unit `Source + Plain + At/Image/File`; latest live image/file blocked |
|
||||
| common user/group entities | plugin-e2e | plugin-e2e | plugin-e2e | plugin-e2e private user; group not completed | live private user; unit private/group |
|
||||
| raw native object isolation | raw data stays in `source_platform_object` | raw data stays in `source_platform_object` | raw data stays in `source_platform_object` | raw data stays in `source_platform_object` | raw data stays in `source_platform_object` |
|
||||
|
||||
@@ -16,7 +16,7 @@ src/langbot/pkg/platform/adapters/aiocqhttp/
|
||||
└── onebot.svg
|
||||
```
|
||||
|
||||
The EBA adapter is registered as `aiocqhttp-eba`. The legacy adapter remains at `src/langbot/pkg/platform/sources/aiocqhttp.py`.
|
||||
The EBA adapter is registered as `aiocqhttp-omni`. The legacy adapter remains at `src/langbot/pkg/platform/sources/aiocqhttp.py`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ src/langbot/pkg/platform/adapters/discord/
|
||||
└── voice.py
|
||||
```
|
||||
|
||||
The adapter is registered as `discord-eba`.
|
||||
The adapter is registered as `discord-omni`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ src/langbot/pkg/platform/adapters/kook/
|
||||
└── types.py
|
||||
```
|
||||
|
||||
The adapter is registered as `kook-eba`.
|
||||
The adapter is registered as `kook-omni`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ The Lark/Feishu adapter now has an Event-Based Agents adapter package with:
|
||||
- `api_impl.py` for common EBA API implementations.
|
||||
- `platform_api.py` for Feishu-specific `call_platform_api` actions.
|
||||
|
||||
The legacy `lark` adapter remains available while the EBA adapter is registered separately as `lark-eba`.
|
||||
The legacy `lark` adapter remains available while the EBA adapter is registered separately as `lark-omni`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Adapter directory: `src/langbot/pkg/platform/adapters/officialaccount/`
|
||||
|
||||
Manifest name: `officialaccount-eba`
|
||||
Manifest name: `officialaccount-omni`
|
||||
|
||||
Status: partial migration. Unit/API-shape coverage is present, and private text `plugin-e2e-ui` plus safe API evidence has been verified against the `dev.rockchin.top` Official Account fixture. Proactive outbound `send_message` remains not supported by this adapter because WeChat Official Account replies must be tied to inbound webhook windows.
|
||||
|
||||
@@ -70,7 +70,7 @@ Verified UI message: `EBA officialaccount single probe 2026-05-28 16:53`
|
||||
|
||||
Observed event/API evidence:
|
||||
|
||||
- `MessageReceived`: `bot_uuid=d7c46880-a9f8-431a-9172-5d3e0d663dbc`, `adapter_name=officialaccount-eba`, `chat_type=private`, `chat_id=ovH9L7OW6hNpWZWvp_NMmypVh26w`, `message_chain=[Source, Plain]`.
|
||||
- `MessageReceived`: `bot_uuid=d7c46880-a9f8-431a-9172-5d3e0d663dbc`, `adapter_name=officialaccount-omni`, `chat_type=private`, `chat_id=ovH9L7OW6hNpWZWvp_NMmypVh26w`, `message_chain=[Source, Plain]`.
|
||||
- Common safe APIs through probe platform sweep: `get_message`, `get_user_info`, `get_friend_list`.
|
||||
- Platform APIs through `call_platform_api`: `get_mode`, `get_cached_response_status`.
|
||||
- `send_message` and outbound component sweep returned explicit `NotSupportedError: send_message:official_account_requires_inbound_webhook_reply`, as expected for this adapter.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Adapter directory: `src/langbot/pkg/platform/adapters/qqofficial/`
|
||||
|
||||
Manifest name: `qqofficial-eba`
|
||||
Manifest name: `qqofficial-omni`
|
||||
|
||||
Status: partial migration. The EBA adapter structure, manifest, converters, cache-backed safe APIs, platform API map, unit tests, and direct live probe scaffold are in place. A real QQ Official WebSocket bot on `dev.rockchin.top` received an inbound user message and drove LangBot into the normal pipeline path; the response path was blocked by the test environment model service returning `model_not_found` for `deepseek-v3`.
|
||||
|
||||
@@ -77,7 +77,7 @@ Status: partial migration. The EBA adapter structure, manifest, converters, cach
|
||||
|
||||
Test date: 2026-06-02
|
||||
|
||||
Endpoint/simulator: `dev.rockchin.top` with a real QQ Official WebSocket bot (`qqofficial-eba`, bot UUID `80a5560b-52b1-40e7-b7d6-4a2341eb4780`) and LangBot running from `/home/wgc/LangBotxg/LangBotEbaTest`.
|
||||
Endpoint/simulator: `dev.rockchin.top` with a real QQ Official WebSocket bot (`qqofficial-omni`, bot UUID `80a5560b-52b1-40e7-b7d6-4a2341eb4780`) and LangBot running from `/home/wgc/LangBotxg/LangBotEbaTest`.
|
||||
|
||||
Observed evidence:
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Slack is migrated into `src/langbot/pkg/platform/adapters/slack/` with the stand
|
||||
- `message_converter.py` maps common `MessageChain` components to Slack text fallback and maps inbound Slack text/image payloads back to EBA components.
|
||||
- `api_impl.py` provides cache-backed common read APIs.
|
||||
- `platform_api.py` declares safe Slack-specific API actions.
|
||||
- `manifest.yaml` declares `slack-eba`.
|
||||
- `manifest.yaml` declares `slack-omni`.
|
||||
|
||||
The legacy `src/langbot/pkg/platform/sources/slack.py` adapter is kept unchanged.
|
||||
|
||||
@@ -71,7 +71,7 @@ Evidence file: `/home/wgc/LangBotxg/LangBotEbaTest/data/temp/slack_eba_plugin_pr
|
||||
|
||||
Observed:
|
||||
|
||||
- Real Slack private text produced `MessageReceived` with `adapter_name=slack-eba`, `Source + Plain`, private chat type, and filled `bot_uuid`.
|
||||
- Real Slack private text produced `MessageReceived` with `adapter_name=slack-omni`, `Source + Plain`, private chat type, and filled `bot_uuid`.
|
||||
- Safe common APIs passed: `get_message`, `get_user_info`, `get_friend_list`.
|
||||
- Outbound component fallback sweep passed through `send_message`: plain/at/face, image, quote, file, and forward.
|
||||
- Declared Slack platform APIs passed: `get_mode`, `auth_test`.
|
||||
|
||||
@@ -15,7 +15,7 @@ src/langbot/pkg/platform/adapters/telegram/
|
||||
└── types.py
|
||||
```
|
||||
|
||||
The adapter is registered as `telegram-eba`.
|
||||
The adapter is registered as `telegram-omni`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ src/langbot/pkg/platform/adapters/wecom/
|
||||
└── types.py
|
||||
```
|
||||
|
||||
The adapter is registered as `wecom-eba`.
|
||||
The adapter is registered as `wecom-omni`.
|
||||
|
||||
This record covers the regular WeCom application-message adapter. WeCom AI Bot (`wecombot-eba`) uses a different protocol flow and is documented separately in `wecombot.md`. WeCom Customer Service (`wecomcs`) remains a separate follow-up migration.
|
||||
This record covers the regular WeCom application-message adapter. WeCom AI Bot (`wecombot-omni`) uses a different protocol flow and is documented separately in `wecombot.md`. WeCom Customer Service (`wecomcs`) remains a separate follow-up migration.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -102,13 +102,13 @@ uv --project /absolute/path/to/langbot-plugin-sdk run python -m langbot_plugin.c
|
||||
Evidence:
|
||||
|
||||
- JSONL: `data/temp/wecom_eba_plugin_probe.jsonl`
|
||||
- Bot: `wecom-eba`
|
||||
- Bot: `wecom-omni`
|
||||
- Client: real WeCom desktop client
|
||||
- Environment: `dev.rockchin.top` test server
|
||||
|
||||
Observed and verified:
|
||||
|
||||
- A real private WeCom user message reached the plugin as `MessageReceived` with `adapter_name=wecom-eba`, common sender/chat fields, and `Source + Plain`.
|
||||
- A real private WeCom user message reached the plugin as `MessageReceived` with `adapter_name=wecom-omni`, common sender/chat fields, and `Source + Plain`.
|
||||
- SDK API calls succeeded through the standalone runtime, including `get_langbot_version`, `get_bots`, `get_bot_info`, `send_message`, plugin/workspace storage, and manifest/list APIs.
|
||||
- Safe adapter API checks succeeded through the plugin path for cached message/user data and declared safe platform API actions.
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ src/langbot/pkg/platform/adapters/wecombot/
|
||||
└── types.py
|
||||
```
|
||||
|
||||
The adapter is registered as `wecombot-eba`.
|
||||
The adapter is registered as `wecombot-omni`.
|
||||
|
||||
This is separate from regular WeCom internal applications (`wecom-eba`). WeComBot supports WebSocket long connection mode, which does not require a webhook URL. Webhook mode remains available when `enable-webhook=true`.
|
||||
This is separate from regular WeCom internal applications (`wecom-omni`). WeComBot supports WebSocket long connection mode, which does not require a webhook URL. Webhook mode remains available when `enable-webhook=true`.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -118,13 +118,13 @@ Evidence:
|
||||
|
||||
- JSONL: `data/temp/wecombot_eba_plugin_probe.jsonl`
|
||||
- Bot UUID: `9f5d4125-7b6d-4c98-8ca2-111111111111`
|
||||
- Adapter: `wecombot-eba`
|
||||
- Adapter: `wecombot-omni`
|
||||
- Client: real WeCom desktop client, private `LangBot` BOT chat
|
||||
- Mode: WebSocket long connection (`enable-webhook=false`)
|
||||
|
||||
Observed and verified:
|
||||
|
||||
- A real user-side message reached the plugin as `MessageReceived` with `adapter_name=wecombot-eba`, common sender/chat fields, and `Source + Plain`.
|
||||
- A real user-side message reached the plugin as `MessageReceived` with `adapter_name=wecombot-omni`, common sender/chat fields, and `Source + Plain`.
|
||||
- SDK API calls succeeded through the standalone runtime: `get_langbot_version`, `get_bots`, `get_bot_info`, `send_message`, plugin/workspace storage, manifest/list APIs, and safe cached common platform APIs.
|
||||
- Outbound component sweep was visible in the WeCom client and returned `errcode=0`: plain/mention/face fallback, base64 image marker, quote fallback, file marker, and flattened forward fallback.
|
||||
- Declared WeComBot platform APIs succeeded through `plugin.call_platform_api`: `is_websocket_mode`, `get_stream_session_status`, and `send_markdown`.
|
||||
|
||||
@@ -15,7 +15,7 @@ src/langbot/pkg/platform/adapters/wecomcs/
|
||||
└── types.py
|
||||
```
|
||||
|
||||
The adapter is registered as `wecomcs-eba`. It is separate from regular WeCom application messages (`wecom-eba`) and WeCom AI Bot (`wecombot-eba`).
|
||||
The adapter is registered as `wecomcs-omni`. It is separate from regular WeCom application messages (`wecom-omni`) and WeCom AI Bot (`wecombot-omni`).
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -120,7 +120,7 @@ Evidence:
|
||||
- Server JSONL: `/home/wgc/LangBotxg/LangBotEbaTest/data/temp/wecomcs_eba_plugin_probe.jsonl`
|
||||
- Trigger text: `EBA wecomcs dedupe probe 2026-05-27`
|
||||
- `bot_uuid`: `cc810d2c-91f3-4f92-8f27-e1bf9f7b6cb4`
|
||||
- `adapter_name`: `wecomcs-eba`
|
||||
- `adapter_name`: `wecomcs-omni`
|
||||
- Observed common event: `MessageReceived`, `event.type=message.received`
|
||||
- Observed message chain: `Source + Plain`
|
||||
- Observed chat: `chat_type=private`, `chat_id=external_userid|open_kfid`
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# Legacy and Omni adapter mainline audit
|
||||
|
||||
Audit date: 2026-09-10.
|
||||
|
||||
- Destination: `dev/4.11.x`, starting at `5ba25c39af85844283f7049beddc54ea71afea76`.
|
||||
- Upstream: refreshed `origin/master`, `ce6b647fe7e620031c3dd9d16a8e8c08ba13b4b1`.
|
||||
- Scope: adapter changes since the first Omni fork in March 2026, including shared platform clients, configuration manifests, and shutdown/resource handling.
|
||||
- Existing local changes, including the Omni identifier rename, are preserved.
|
||||
|
||||
The two implementations do not inherit behavior automatically. A commit in `sources/` does not update `adapters/`. The audit compares the current legacy source with master, then checks its actual equivalent in the Omni converter, transport, client, configuration, and lifecycle code. Native interaction handling continues to use `interaction.request` and typed callbacks; old Dify runner-private state is not copied into the new event architecture.
|
||||
|
||||
## Platforms with an Omni adapter
|
||||
|
||||
| Platform | Relevant mainline work | Legacy result | Omni result |
|
||||
| --- | --- | --- | --- |
|
||||
| OneBot / aiocqhttp | JSON cards (`c75890874`, `0963fd544`), base64 (`ccc51522c`), group metadata (`cc7a13158`), listener lifecycle (`2c3e52c16`), bounded lookups (`e1ac5e0fc`), original image URLs (`463b12092`) | Already present | Added JSON-card parsing and normalization for image, voice, and file payloads. Reused the cached, timeout-bounded group/member lookup per adapter instance. Preserved native handler registration, typed events, and original image URLs. |
|
||||
| Telegram | Streaming (`0755beebc`), bounded media/state (`e1ac5e0fc`), token-bearing image URLs (`9df021eb8`) | Already present | Shares the legacy message converter; ported persistent-message streaming, throttling/size fallback, bounded state, and shutdown. Token-bearing download URLs remain absent from the public Image component. |
|
||||
| Discord | Streaming (`0755beebc`), media/resource limits (`e1ac5e0fc`), original image URLs (`463b12092`) | Already present | Added snapshot-based send/edit streaming with bounded state. Enforced the mainline media limit on Omni image, voice, and file loading. Incoming public attachment URLs are preserved. |
|
||||
| Feishu / Lark | Files (`e06fac2bb`), proactive sends (`3680a8024`), service domain (`c7cb42bd7`), tables (`1d15798e5`), nonblocking connection discovery (`48952206d`), resource bounds (`e1ac5e0fc`), final duplicate text (`5ca30133a`), feedback association (`f8010a20e`) | Applied final-text fix; retained the newer SDK cache-task cleanup | Added identical domestic/international/custom domain fields and applied the selected domain to both HTTP and WebSocket clients. Reused nonblocking connection discovery and bounded upload helpers; bounded incoming downloads and callback tasks. Added table cards and feedback-to-monitoring association. The final card contains one text element and exits streaming mode; it does not use the legacy duplicate-placeholder layout. |
|
||||
| DingTalk | Voice recognition (`de4d14fee`), files (`e06fac2bb`), interactive cards (`0755beebc`), task/card bounds (`e1ac5e0fc`), automatic layout (`8cf001550`) | Applied layout fix in the shared client | Shared client fix reaches both `create_and_card` and native interaction cards. Retained typed file/voice conversion and native callbacks, bounded normal stream cards, cleared callback/card state on shutdown, and exposed the template download. |
|
||||
| QQ Official | Optional token (`cb45807b1`), Markdown (`c87548c0b`), complete stream snapshots (`79634772d`), resource bounds (`e1ac5e0fc`), original image URLs (`463b12092`) | Applied optional-token fix | Removed the token requirement in constructor and manifest. Added Markdown configuration and sending. Stream and non-stream fallback replace full snapshots instead of appending deltas. Restored original image URLs, bounded state, and closed the owned client on shutdown. |
|
||||
| WeCom application | Media ID key (`d942bfe19`), original image URLs (`463b12092`), client lifetime (`e1ac5e0fc`) | Applied the `media_id` send fix | Media dispatch already used `media_id`; restored original image URLs and client shutdown. |
|
||||
| WeCom AI Bot | WS/files/feedback (`d9378c3a8`, `14b1e0d33`, `c7efa4dd7`, `83ccb33fd`), sandbox media (`e934f08ad`), WS loading (`e69a80f5e`) | Already present | Outbound conversion now retains media items. Replies and final stream chunks use the shared upload/reply implementation instead of `[Image]` / `[File]` placeholders. Existing native inbound file/voice/quote handling, feedback, and shared WS fixes remain active. |
|
||||
| WeCom customer service | Proactive text (`13dba887d`), `open_kfid` and unique outbound `msgid` (`cabde423a`), client limits (`e1ac5e0fc`) | Already present | Existing target parsing and generated outbound message IDs already match. Added owned-client shutdown and cache clearing; removed a shadowed obsolete image-send definition, retaining the bounded active implementation. |
|
||||
| Slack | Original image URLs (`463b12092`), shared HTTP session (`e1ac5e0fc`) | Already present | Restored original image URLs alongside downloaded data. Existing shared-client behavior remains active; bounded retained typed-event caches. |
|
||||
| KOOK | Bounded gateway decompression, HTTP responses, and shared sessions (`e1ac5e0fc`) | Already present | Reuses the bounded gateway decoder off the event loop and limited JSON response reader. Existing URL-based image conversion does not eagerly download media. |
|
||||
| WeChat Official Account | Resource/state cleanup (`e1ac5e0fc`) and outbound IP display (`bca710dbd`) | Already present | Calls the shared client's cleanup on shutdown, bounds typed-event caches, and exposes the outbound IP configuration field. |
|
||||
|
||||
All 12 Omni manifests include the corresponding legacy configuration field names and current deployment help links. The Feishu/Lark `domain` and `custom_domain` fields are structurally identical, including labels, descriptions, options, defaults, and conditional display. Display names are unchanged.
|
||||
|
||||
## Platforms with no separate Omni implementation
|
||||
|
||||
| Platform | Result |
|
||||
| --- | --- |
|
||||
| Matrix | Applied `fc1c99843` to fix the unbound logout command during re-login. Existing connection/media/resource fixes already match master. |
|
||||
| Mattermost | Added the complete mainline adapter, manifest, icon, and regression tests from `d6443b10b`. |
|
||||
| LINE | Stable source-based sessions (`777fe1f20`), mention conversion (`855ae2bdb`), and resource limits already match master. |
|
||||
| OpenClaw Weixin | Mainline adapter, outbound IP display, and resource/lifecycle changes already present. |
|
||||
| WeChatPad | Mainline media/download and resource/lifecycle changes already present. |
|
||||
| Satori | Mainline lifecycle/resource changes already present. |
|
||||
| HTTP Bot | Mainline standalone HTTP integration and workspace/resource changes already present. |
|
||||
| WebPage Bot | Delegated stream helpers and embedded-session behavior already match master. |
|
||||
| WebSocket / browser debug | Mainline session isolation, scoped history, resource bounds, and routing work already present. Retained 4.11's image-reference retention and pipeline metadata additions. |
|
||||
| Archived Gewechat, Nakuru, QQBotPy sources | Mainline source changes already present; no separate Omni counterpart exists. |
|
||||
|
||||
Documentation-link updates `1cfe87186` and `ec63978ec` were also applied to legacy manifests and matching Omni manifests.
|
||||
|
||||
## Intentional architectural differences
|
||||
|
||||
- New typed events and platform APIs remain in the Omni modules. Legacy Pipeline message/context conversion stays in the established compatibility path.
|
||||
- Native interaction delivery uses the generic interaction request/callback protocol. The current 4.11 pipeline/provider code no longer emits `_form_data` or `_resume_from_form`; copying old Dify callback internals would reconnect the wrong execution model.
|
||||
- This audit establishes parity for the mainline changes in scope, not a claim that every pre-fork legacy-only extension has a typed Omni API. For example, Discord voice-channel management still belongs to the legacy source; sending voice attachments and the post-fork streaming/resource fixes are covered here.
|
||||
- Shared platform clients retain 4.11-specific return values and additional APIs instead of being overwritten with entire master files.
|
||||
|
||||
## Verification
|
||||
|
||||
- Full backend unit suite: **3751 passed, 1 skipped**. This includes platform transport tests, Pipeline/event routing, service validation, plugin actions, workspace isolation, and resource handling.
|
||||
- Dedicated mainline-parity regression suite: **62 passed**. Coverage for configuration coverage, OneBot JSON/base64/metadata, QQ Markdown/snapshots, WeCom media replies, bounded media/gateway reads, lifecycle cleanup, streaming, and Feishu/Lark region selection.
|
||||
- Ruff formatting and checks pass on the affected Python files.
|
||||
- Restarted the local backend on port 5399; `/healthz` returns success and reports the plugin runtime connected. All 12 Omni icon endpoints and the new Mattermost icon return HTTP 200.
|
||||
- Vendor requests in automated tests are mocked. Real delivery to every external platform has not been tested. The instance contains pre-existing incomplete Feishu and WeCom AI Bot configurations; the same missing-credential errors were present before this audit.
|
||||
|
||||
Tests: `tests/unit_tests/platform/test_omni_mainline_parity.py`, the platform-specific test files, and the imported Mattermost/WeCom/Lark/DingTalk regressions.
|
||||
Reference in New Issue
Block a user