Files
d8271d9198 feat(line): Native Event-Based Agent (EBA) LINE Platform Adapter (#2736)
* feat(line): EBA LINE adapter skeleton (WO-LINE-01-SKELETON-1018)

- pkg/platform/adapters/line/ 9 files (LineAdapter hybrid inheritance +
  Capability + event namespace + config env load, zero hardcoded secrets)
- LINE SDK calls all stub (NotImplementedError) pending WO-LINE-00/02/03
- Verified: compileall 7/7 + ruff 0 + import chain green against
  v4.11.0-hotfixed SDK (container-extracted, read-only)
- Source: handoff box WO-LINE-01-SKELETON-1018 (sha256 9/9 matched)

Co-authored-by: multica-agent <[email protected]>

* feat(line): implement WO-LINE-02 message.received loop and converter

Co-authored-by: multica-agent <[email protected]>

* feat(line): implement WO-LINE-03 streaming and send API

Co-authored-by: multica-agent <[email protected]>

* feat(line): implement WO-LINE-04 group and user event extensions

Co-authored-by: multica-agent <[email protected]>

* feat(line): implement WO-LINE-05 group and user event extensions

Co-authored-by: multica-agent <[email protected]>

* docs(line): add EBA LINE adapter architecture guide and documentation

Co-authored-by: multica-agent <[email protected]>

* feat(line): resolve Ruff warnings and manifest spec update

Co-authored-by: multica-agent <[email protected]>

* feat(line): add webhook_url config and help_links to PR_DESCRIPTION.md

Co-authored-by: multica-agent <[email protected]>

* feat(line): add webhook_url config and help_links for PR #2736

Co-authored-by: multica-agent <[email protected]>

* fix(line): ruff format, update help_links, remove nested duplicate dir

Co-authored-by: multica-agent <[email protected]>

* fix(line): resolve 12 test failures, align types, and move architecture docs to dev-docs

Co-authored-by: multica-agent <[email protected]>

* fix(line): resolve ruff lint and formatting issues for CI

Co-authored-by: multica-agent <[email protected]>

* docs(line): sanitize internal orchestration notes and standardize documentation

Co-authored-by: multica-agent <[email protected]>

* clean(line): remove internal tracking ticket references from source code

Co-authored-by: multica-agent <[email protected]>

* fix(line): resolve MessageReceivedEvent and Friend entity mapping for 100% test pass

Co-authored-by: multica-agent <[email protected]>

* fix(line): resolve E402 import order in event_converter.py

Co-authored-by: multica-agent <[email protected]>

* feat(line): implement the LINE Omni adapter on the legacy messaging flow

Replace the placeholder skeleton with a working unified-webhook adapter:

- verify X-Line-Signature with WebhookParser and acknowledge before dispatch
- build real LINE messaging clients from channel_access_token and drop
  the adapter's own messages using the account id from get_bot_info
- map message/image/voice events to message.received, unsend to
  message.deleted, membership changes to group/bot events, and the
  remaining LINE event types to platform.specific with chat identity
- send and reply through MessagingApi with LINE's five-message budget,
  a reply-token to push fallback, and honest NotSupportedError paths
- expose get_user_info, get_group_info, leave_group and the get_bot_info,
  get_profile, get_group_summary pass-through actions
- keep the legacy FriendMessage/GroupMessage listeners working
- move tests to tests/unit_tests/platform, add the adapter doc, and
  register line in OMNI_ADAPTER_NAMES

Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: multica-agent <[email protected]>
Co-authored-by: RockChinQ <[email protected]>
2026-10-30 12:58:04 +08:00

73 lines
3.6 KiB
Markdown

# LINE EBA Adapter
## Structure
LINE is migrated into `src/langbot/pkg/platform/adapters/line/` with the standard EBA adapter layout:
- `adapter.py` owns lifecycle, unified webhook handling, signature verification, listener dispatch, and outbound send/reply.
- `event_converter.py` maps LINE webhook events to `message.received`, `message.deleted`, group membership events, and `platform.specific`.
- `message_converter.py` maps common `MessageChain` components to LINE message objects and maps inbound LINE text/image/voice payloads back to EBA components.
- `api_impl.py` implements the optional common APIs against the LINE Messaging API.
- `platform_api.py` declares the safe LINE-specific pass-through actions.
- `manifest.yaml` declares `line-omni`.
The legacy `src/langbot/pkg/platform/sources/line.py` adapter is kept unchanged.
Request handling reuses the proven behaviour of the legacy adapter: `WebhookParser` verifies `X-Line-Signature`, the webhook acknowledges immediately, and each event is converted and dispatched in a background task.
## Configuration
| Field | Required | Notes |
|-------|----------|-------|
| `webhook_url` | No | Generated by LangBot. Paste it into the LINE Developers console and enable "Use webhook". |
| `channel_access_token` | Yes | Long-lived channel access token, used for all outbound calls. |
| `channel_secret` | Yes | Channel secret, used to verify `X-Line-Signature`. |
`bot_account_id` is resolved through `get_bot_info` on startup and is used to drop the adapter's own messages.
## Events
| Event | Notes |
|-------|-------|
| `message.received` | Text, image, voice, and other message types. Group and room chats are mapped to group chat identity. LINE mentions become `At` components. |
| `message.deleted` | Emitted for LINE `unsend` events. |
| `group.member_joined` | Emitted for `memberJoined`; the first listed member is the event subject. |
| `group.member_left` | Emitted for `memberLeft`. |
| `bot.invited_to_group` | Emitted when the Official Account joins a group or room (`join`). |
| `bot.removed_from_group` | Emitted when the Official Account leaves (`leave`). |
| `platform.specific` | `line.follow`, `line.unfollow`, `line.postback`, `line.beacon`, and any other LINE event type, with `chat_id` in `data`. |
Legacy pipeline bindings still receive `FriendMessage` / `GroupMessage`; the adapter converts the unified event for them.
## Common APIs
Required:
- `send_message`
- `reply_message`
Optional:
- `get_user_info`
- `get_group_info`
- `leave_group`
- `call_platform_api`
`reply_message` uses the event's reply token and falls back to `push_message` when the token is rejected or already used, so multi-message answers still arrive.
## Platform APIs
| Action | Notes |
|--------|-------|
| `get_bot_info` | Returns the Official Account profile. |
| `get_profile` | Calls `get_profile` for a user id. |
| `get_group_summary` | Calls `get_group_summary` for a group id. |
## Known Limits
- LINE has no group member listing API, so `get_group_member_list` raises `NotSupportedError`.
- Outbound images require a public URL: the Messaging API fetches `originalContentUrl`, so a base64-only `Image` component raises `NotSupportedError` instead of sending nothing.
- LINE has no message edit API; `edit_message` raises `NotSupportedError`. Streaming output is not supported.
- Requests are capped at five messages per call and 5000 characters per text message; longer chains are split into multiple requests.
- Offline coverage lives in `tests/unit_tests/platform/test_line_eba_adapter.py`. A real channel (webhook delivery, reply tokens, media download) still needs verification against a live LINE Official Account.