文件最后提交记录最后更新时间
feat(gateway): add LINE Messaging API platform plugin (#23197) * feat(gateway): add LINE Messaging API platform plugin Adds LINE as a bundled platform plugin under plugins/platforms/line/, synthesized from the strongest pieces of seven open community PRs. The adapter requires zero core edits — Platform("line") is auto-discovered via the bundled-plugin scan in gateway/config.py, and all hooks (setup, env-enablement, cron delivery, standalone send) are wired through register_platform() kwargs the way IRC and Teams do it. Highlights merged into one plugin: - **Reply token preferred, Push fallback.** Try the free reply token first (single-use, ~60s TTL); fall back to metered Push when the token is absent, expired, or rejected. (PR #21023) - **Slow-LLM Template Buttons postback.** When the LLM is still running past LINE_SLOW_RESPONSE_THRESHOLD (default 45s), the adapter burns the original reply token to send a "Get answer" button bubble. The user taps it to fetch the cached answer via a fresh reply token — also free. State machine: PENDING → READY → DELIVERED, ERROR for cancelled runs (orphan resolves to LINE_INTERRUPTED_TEXT after /stop). Set threshold to 0 to disable. (PR #18153) - **Three-allowlist gating** — separate user / group / room allowlists with LINE_ALLOW_ALL_USERS=true dev-only escape hatch. (PR #18153) - **Markdown URL preservation.** Strip bold/italic/code-fence/heading markers (LINE renders them literally) but keep [label](url)label (url) so URLs stay tappable. (PR #18153) - **System-message bypass** for ⚡ Interrupting, ⏳ Queued, etc. — busy-acks reach the user as visible bubbles instead of being swallowed into the postback cache. (PR #18153) - **Media via public HTTPS URLs.** LINE doesn't accept binary uploads; images/audio/video must be HTTPS-reachable. The adapter serves registered tempfiles under /line/media/<token>/<filename> from the same aiohttp app. Allowed-roots traversal guard covers tempfile.gettempdir(), /tmp (→ /private/tmp on macOS), and HERMES_HOME. LINE_PUBLIC_URL overrides URL construction for setups behind tunnels/proxies. (PR #8398) - **5-message-per-call batching.** LINE rejects >5 messages per Reply/Push; smart-chunker caps text at 4500 chars per bubble. - **Inbound dedup** via webhookEventId LRU. (PR #21023) - **Self-message filter** via /v2/bot/info userId lookup. (PR #21023) - **Loading-animation indicator** wired to LINE's chat/loading/start endpoint, DM-only (LINE rejects it for groups/rooms). (PR #21023) - **Out-of-process cron delivery** via _standalone_send, so deliver: line cron jobs work even when cron runs detached from the gateway. - **Webhook hardening** — 1 MiB body cap, constant-time HMAC-SHA256 signature verification, dedup, scoped lock so two profiles can't bind the same channel. Validation ---------- - scripts/run_tests.sh tests/gateway/test_line_plugin.py → 73 passed in 1.05s - `scripts/run_tests.sh tests/gateway/test_line_plugin.py tests/gateway/test_irc_adapter.py tests/gateway/test_plugin_platform_interface.py tests/gateway/test_platform_registry.py tests/gateway/test_config.py` → 193 passed, 7 skipped - E2E import + register + signature roundtrip + Platform("line") bundled-plugin discovery verified against current origin/main. Closes the seven open LINE PRs (#18153, #16832, #6676, #21023, #14942, #14988, #8398) by superseding them with a single plugin-form implementation that takes the best idea from each. Co-authored-by: pwlee <32443648+leepoweii@users.noreply.github.com> Co-authored-by: Jetha Chan <jetha@google.com> Co-authored-by: Cattia <openclaw@liyangchen.me> Co-authored-by: perng <charles@perng.com> Co-authored-by: Soichiro Yoshimura <soichiro0111.dev@gmail.com> Co-authored-by: David Zhou <77736378+David-0x221Eight@users.noreply.github.com> Co-authored-by: Yu-ga <74749461+yuga-hashimoto@users.noreply.github.com> * docs(platforms): document platform-specific slow-LLM UX pattern Add a 'Platform-Specific Slow-LLM UX' section to the platform-adapter developer guide covering the _keep_typing override pattern that LINE uses for its Template Buttons postback flow. Three subsections: - Pattern: subclass _keep_typing to layer mid-flight UX (with code) - Pattern: subclass send to route through a cache instead of sending - When this pattern is appropriate (vs. always-Push fallback) Plus a short pointer in gateway/platforms/ADDING_A_PLATFORM.md so tree-readers find the prose walkthrough on the docsite. Filed because the LINE plugin (PR #23197) was the first bundled adapter to need this pattern — every prior plugin (irc, teams, google_chat) handles slow responses with the default typing-loop and a regular send_text. Documenting now while the rationale is fresh. --------- Co-authored-by: pwlee <32443648+leepoweii@users.noreply.github.com> Co-authored-by: Jetha Chan <jetha@google.com> Co-authored-by: Cattia <openclaw@liyangchen.me> Co-authored-by: perng <charles@perng.com> Co-authored-by: Soichiro Yoshimura <soichiro0111.dev@gmail.com> Co-authored-by: David Zhou <77736378+David-0x221Eight@users.noreply.github.com> Co-authored-by: Yu-ga <74749461+yuga-hashimoto@users.noreply.github.com>26 天前
chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) Six days after #23937 (608 fixes) the codebase had accumulated 241 new PLR6201 violations. Same mechanical x in (...)x in {...} fix, same zero-risk profile: set lookup is O(1) vs O(n) for tuple and the two are semantically equivalent for hashable scalar membership tests. All 241 instances fixed via `ruff check --select PLR6201 --fix --unsafe-fixes`, zero remaining. Every changed value is a hashable scalar (str/int/None/enum/signal); no risk of unhashable runtime errors. No behavior change. Test plan: - 119 files changed, +244/-244 (net zero) — exactly one-line edits - ruff check clean afterward - Compile checks pass on the largest touched files (cli.py, run_agent.py, gateway/run.py, gateway/platforms/discord.py, model_tools.py) - Subset broad test run on tests/gateway/ tests/hermes_cli/ tests/agent/ tests/tools/: 18187 passed, 59 pre-existing failures (verified against origin/main with the same shape — identical failure count, identical category — all xdist test-order flakes unrelated to this change) Follows the same template as PR #23937 ([tracker: #23972](https://github.com/NousResearch/hermes-agent/issues/23972)).19 天前
feat(gateway): add LINE Messaging API platform plugin (#23197) * feat(gateway): add LINE Messaging API platform plugin Adds LINE as a bundled platform plugin under plugins/platforms/line/, synthesized from the strongest pieces of seven open community PRs. The adapter requires zero core edits — Platform("line") is auto-discovered via the bundled-plugin scan in gateway/config.py, and all hooks (setup, env-enablement, cron delivery, standalone send) are wired through register_platform() kwargs the way IRC and Teams do it. Highlights merged into one plugin: - **Reply token preferred, Push fallback.** Try the free reply token first (single-use, ~60s TTL); fall back to metered Push when the token is absent, expired, or rejected. (PR #21023) - **Slow-LLM Template Buttons postback.** When the LLM is still running past LINE_SLOW_RESPONSE_THRESHOLD (default 45s), the adapter burns the original reply token to send a "Get answer" button bubble. The user taps it to fetch the cached answer via a fresh reply token — also free. State machine: PENDING → READY → DELIVERED, ERROR for cancelled runs (orphan resolves to LINE_INTERRUPTED_TEXT after /stop). Set threshold to 0 to disable. (PR #18153) - **Three-allowlist gating** — separate user / group / room allowlists with LINE_ALLOW_ALL_USERS=true dev-only escape hatch. (PR #18153) - **Markdown URL preservation.** Strip bold/italic/code-fence/heading markers (LINE renders them literally) but keep [label](url)label (url) so URLs stay tappable. (PR #18153) - **System-message bypass** for ⚡ Interrupting, ⏳ Queued, etc. — busy-acks reach the user as visible bubbles instead of being swallowed into the postback cache. (PR #18153) - **Media via public HTTPS URLs.** LINE doesn't accept binary uploads; images/audio/video must be HTTPS-reachable. The adapter serves registered tempfiles under /line/media/<token>/<filename> from the same aiohttp app. Allowed-roots traversal guard covers tempfile.gettempdir(), /tmp (→ /private/tmp on macOS), and HERMES_HOME. LINE_PUBLIC_URL overrides URL construction for setups behind tunnels/proxies. (PR #8398) - **5-message-per-call batching.** LINE rejects >5 messages per Reply/Push; smart-chunker caps text at 4500 chars per bubble. - **Inbound dedup** via webhookEventId LRU. (PR #21023) - **Self-message filter** via /v2/bot/info userId lookup. (PR #21023) - **Loading-animation indicator** wired to LINE's chat/loading/start endpoint, DM-only (LINE rejects it for groups/rooms). (PR #21023) - **Out-of-process cron delivery** via _standalone_send, so deliver: line cron jobs work even when cron runs detached from the gateway. - **Webhook hardening** — 1 MiB body cap, constant-time HMAC-SHA256 signature verification, dedup, scoped lock so two profiles can't bind the same channel. Validation ---------- - scripts/run_tests.sh tests/gateway/test_line_plugin.py → 73 passed in 1.05s - `scripts/run_tests.sh tests/gateway/test_line_plugin.py tests/gateway/test_irc_adapter.py tests/gateway/test_plugin_platform_interface.py tests/gateway/test_platform_registry.py tests/gateway/test_config.py` → 193 passed, 7 skipped - E2E import + register + signature roundtrip + Platform("line") bundled-plugin discovery verified against current origin/main. Closes the seven open LINE PRs (#18153, #16832, #6676, #21023, #14942, #14988, #8398) by superseding them with a single plugin-form implementation that takes the best idea from each. Co-authored-by: pwlee <32443648+leepoweii@users.noreply.github.com> Co-authored-by: Jetha Chan <jetha@google.com> Co-authored-by: Cattia <openclaw@liyangchen.me> Co-authored-by: perng <charles@perng.com> Co-authored-by: Soichiro Yoshimura <soichiro0111.dev@gmail.com> Co-authored-by: David Zhou <77736378+David-0x221Eight@users.noreply.github.com> Co-authored-by: Yu-ga <74749461+yuga-hashimoto@users.noreply.github.com> * docs(platforms): document platform-specific slow-LLM UX pattern Add a 'Platform-Specific Slow-LLM UX' section to the platform-adapter developer guide covering the _keep_typing override pattern that LINE uses for its Template Buttons postback flow. Three subsections: - Pattern: subclass _keep_typing to layer mid-flight UX (with code) - Pattern: subclass send to route through a cache instead of sending - When this pattern is appropriate (vs. always-Push fallback) Plus a short pointer in gateway/platforms/ADDING_A_PLATFORM.md so tree-readers find the prose walkthrough on the docsite. Filed because the LINE plugin (PR #23197) was the first bundled adapter to need this pattern — every prior plugin (irc, teams, google_chat) handles slow responses with the default typing-loop and a regular send_text. Documenting now while the rationale is fresh. --------- Co-authored-by: pwlee <32443648+leepoweii@users.noreply.github.com> Co-authored-by: Jetha Chan <jetha@google.com> Co-authored-by: Cattia <openclaw@liyangchen.me> Co-authored-by: perng <charles@perng.com> Co-authored-by: Soichiro Yoshimura <soichiro0111.dev@gmail.com> Co-authored-by: David Zhou <77736378+David-0x221Eight@users.noreply.github.com> Co-authored-by: Yu-ga <74749461+yuga-hashimoto@users.noreply.github.com>26 天前