Commit Graph

34 Commits

Author SHA1 Message Date
Josh Avant 97a53a9b35 feat: audit admitted channel participant identity (#122863)
* feat: audit admitted channel participant identity

* fix: preserve Telegram identity through thread recovery

* fix: signal held gateway process groups

* fix: keep audit evidence passive in collect routing

* fix: validate copied channel participant evidence

* fix: bind channel participant evidence to host ingress

* fix: honor Telegram proof credential roles

* fix: restart held Telegram proof through gateway

* fix: repair channel identity CI regressions

* test(matrix): bind thread routing owner

* fix: preserve direct DM SDK compatibility

* fix: bind channel provenance at host runtime

* test(feishu): provide channel context builder

* fix: defer record-bound channel runtime resolution

* fix: keep channel admission evidence core-private

* fix(audit): bind channel admission to plugin lifecycle

* fix(audit): bind ingress provenance to final context

* refactor(audit): split admission scope keys

* test(queue): cover combined metadata carriers

* refactor(audit): keep lifecycle helpers private

* fix(queue): preserve combined turn authority

* test(channels): provide ingress context builders

* test(channels): align integrated CI fixtures

* test(clickclack): resolve model-loop ingress

* docs: preserve channel participant evidence invariant
2026-08-14 08:57:01 -05:00
Peter Steinberger dbe4ce9f33 fix(telegram): prevent multi-agent cache ownership startup failures (#123029)
* fix(telegram): scope runtime caches by account owner

* test(telegram): type partial owner runtime stub

* refactor(telegram): remove obsolete default owner seam

* fix(telegram): tolerate partial durable updates

* test(telegram): request raw progress detail explicitly
2026-08-13 00:33:38 -07:00
YangManBOBO c6c7d7d9de fix(telegram): retry update offset persistence
Keep accepted and committed Telegram update offsets separate, retry transient state-store failures, and preserve classic plus isolated restart dedupe.

Co-authored-by: 潘晓波0668000512 <pan.xiaobo@xydigit.com>
2026-08-04 17:37:56 +05:30
Peter Steinberger 783a5d21cf refactor(config): purge numeric tuning knobs behind built-in defaults (#111382) 2026-07-19 07:35:45 -07:00
Peter Steinberger d262cad41f refactor: burn down Matrix, Telegram, and outbound dead exports (#106153)
* refactor(matrix): remove unused internal exports

* refactor(telegram): remove unused internal exports

* refactor(matrix): remove stale thread binding imports

* refactor(outbound): remove unused internal exports

* style(outbound): format dead export cleanup
2026-07-13 04:39:58 -07:00
Vincent Koc e242c61400 refactor(deadcode): localize extension helpers (#101860) 2026-07-07 12:12:32 -07:00
Dallin Romney 792060bb63 refactor(shared): consolidate Discord Slack and Telegram lazy loaders (#99298) 2026-07-02 18:45:48 -07:00
Peter Steinberger efd1a9ace6 docs: document messaging extension sources 2026-06-04 22:03:15 -04:00
Galin Iliev b5c1199217 fix(telegram): route polling diagnostics away from errors
Route normal [telegram][diag] polling diagnostics through runtime.log while keeping non-diag Telegram warnings/errors and offset persistence failures on runtime.error.

Verification:
- node scripts/run-vitest.mjs extensions/telegram/src/monitor.test.ts (34 passed)
- git diff --check
- CI run 26378692736 passed on 979c6f31a4

Fixes #82957
2026-05-24 18:39:52 -07:00
Josh Avant fd244fd76d Fix Telegram polling ingress under event-loop stalls (#81746)
* fix telegram polling ingress under event-loop stalls

* add changelog for telegram ingress fix
2026-05-14 03:35:06 -05:00
Ayaan Zaidi 306b51011f fix(telegram): handle legacy rotated offsets 2026-05-13 10:12:31 +05:30
sxxtony cb93c0f8f5 fix(telegram): factor offset rotation handling into typed surfaces
Builds on the prior commit by introducing the typed surfaces the rest of
the plugin (and `openclaw doctor`-style consumers) can reuse:

- `inspectTelegramUpdateOffset` returns a discriminated union
  (`absent | valid | rotated`) so callers can act on the rotation event
  without re-implementing the bot-id / fingerprint comparison.
  `readTelegramUpdateOffset` is now a thin adapter over it.
- `TelegramOffsetRotationReason` is exported as a named type alias so
  downstream code can switch over it exhaustively.
- New `TelegramOffsetRotationHandler` class encapsulates the
  "log warning + delete stale file" side effect that the monitor needs at
  startup, plus a `createTelegramOffsetRotationHandler` factory and a
  pure `formatTelegramOffsetRotationMessage` helper used to keep the
  wording consistent.
- `monitor.ts` now constructs the handler once per polling startup
  instead of inlining the closure, and the new surfaces are re-exported
  through `monitor-polling.runtime.ts`.

Unit coverage:
  pnpm test extensions/telegram/src/update-offset-store.test.ts \
            extensions/telegram/src/offset-rotation-handler.test.ts \
            extensions/telegram/src/monitor.test.ts
2026-05-13 10:12:31 +05:30
sxxtony 290d3879eb fix(telegram): detect same-bot token rotation via fingerprinted offset state
Closes #80653.

Persist a non-reversible SHA-256 fingerprint of the bot token alongside the
bot id in the long-poll update offset store (version 3). On read, treat the
persisted offset as stale when the fingerprint diverges from the current
token, even when the bot id still matches. This covers the BotFather
`/revoke` case where the bot id is unchanged but the secret rotates -- the
in-process update tracker would otherwise silently skip any new updates
whose `update_id` is `<=` the restored watermark.

The legacy v2 (bot-id-only) layout still parses, and offsets are preserved
when the bot id matches so existing installs don't lose a watermark on
upgrade; the next persistence upgrades the file to v3 and enables rotation
detection going forward.

`readTelegramUpdateOffset` now reports each rotation through a new
`onRotationDetected` callback. `monitor.ts` uses it to log a clear warning
naming the previous/new bot id and the discarded offset, and to delete the
stale file rather than waiting for the first update to overwrite it.

Acceptance suites pass:
  pnpm test extensions/telegram/src/update-offset-store.test.ts \
            extensions/telegram/src/bot-update-tracker.test.ts \
            extensions/telegram/src/monitor.test.ts \
            extensions/telegram/src/bot.create-telegram-bot.test.ts \
            extensions/telegram/src/token.test.ts \
            extensions/telegram/src/polling-lease.test.ts
2026-05-13 10:12:31 +05:30
Peter Steinberger 827b0de0ce refactor: reduce plugin sdk surface 2026-05-10 12:37:10 +01:00
Ayaan Zaidi 5b94c4ce93 fix(telegram): start polling after webhook cleanup timeout (#76735)
Summary:
- The branch changes Telegram polling startup to reuse the successful probe `getMe` result as grammY `botInfo` ... es` after recoverable `deleteWebhook` failures, and updates Telegram docs, changelog, and regression tests.
- Reproducibility: yes. for the narrow PR bug: source inspection shows current main can block before polling o ... d timeout coverage that reaches `run()`. The full linked high-RTT report remains only partially reproduced.

Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: fix(telegram): start polling after webhook cleanup timeout
- Included post-review commit in the final squash: fix(telegram): extract bot info contract

Validation:
- ClawSweeper review passed for head c74bbdd1ff.
- Required merge gates passed before the squash merge.

Prepared head SHA: c74bbdd1ff
Review: https://github.com/openclaw/openclaw/pull/76735#issuecomment-4366417178

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-05-03 15:16:32 +00:00
Hemant Sudarshan db6951088a fix(telegram): keep unreachable polling sockets non-fatal
* Runtime: suppress transient network uncaught exceptions

* fix(telegram): keep unreachable polling sockets non-fatal

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-04-29 19:53:43 +01:00
Peter Steinberger 204ef7f1c4 fix(telegram): report webhook registration status 2026-04-29 15:40:44 +01:00
Peter Steinberger 4336a7f3a9 refactor(plugin-sdk): narrow config runtime imports 2026-04-27 14:58:32 +01:00
Peter Steinberger 7f3f108521 refactor(config): migrate plugin config access 2026-04-27 12:35:58 +01:00
Peter Steinberger 3169886a21 fix(telegram): guard duplicate polling leases 2026-04-25 09:38:51 +01:00
Amine Harch el korane 8c05043eca fix(telegram): tune polling stall threshold
Raise the Telegram polling watchdog default from 90s to 120s and add bounded channels.telegram.pollingStallThresholdMs overrides, including per-account config.\n\nThanks @Vitalcheffe.
2026-04-21 01:03:04 +01:00
Peter Steinberger 60fea81cf1 fix(telegram): harden polling transport liveness (#69476)
* fix(telegram): release undici dispatchers via TelegramTransport.close()

TelegramTransport now exposes an explicit close() that destroys every
owned undici dispatcher (default Agent plus lazily-created IPv4 and
IP-pinned fallback Agents) and the TCP sockets they hold. Dispatcher
constructors are also given bounded keep-alive defaults
(keepAliveTimeout, keepAliveMaxTimeout, connections, pipelining) as a
defence-in-depth layer so the pool cannot grow unbounded even if a
caller forgets to call close().

Without this, every transport that went through a fallback retry left
its fallback Agents anchored forever in a closure; long-running polling
sessions accumulated hundreds of ESTABLISHED keep-alive sockets to
api.telegram.org, saturating the per-IP quota on upstream forward
proxies and making the currently-active outbound node time out while
every other node still tested healthy.

Mock dispatchers in fetch.test.ts gain destroy() spies so the close()
chain is assertable. Call sites that built caller-owned transports from
globalThis.fetch (delivery.resolve-media, test helpers) return an async
no-op close(), matching the new required surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(telegram): dispose polling transport on shutdown and dirty rebuild

Every recoverable network error and stall-watchdog trip sets
TelegramPollingTransportState.#transportDirty so the next polling
cycle rebuilds the transport inside acquireForNextCycle(). Previously
the rebuild simply overwrote the field, leaving the old transport's
keep-alive sockets anchored in the now-unreferenced dispatcher — the
polling loop has no natural GC point for these resources, and Node's
object GC never touches OS-level sockets.

acquireForNextCycle() now closes the previous transport (fire-and-
forget so the polling cycle is not blocked by a slow destroy) before
swapping in the rebuilt one. dispose() is a new method that the owning
TelegramPollingSession calls from the finally block of runUntilAbort(),
so a single transport is always tied to a single polling session
lifetime. After dispose(), acquireForNextCycle() returns undefined to
prevent zombie rebuilds.

Under high sustained polling traffic over long-lived sessions, this is
what stops the per-gateway connection count to api.telegram.org from
growing indefinitely and saturating upstream proxy quotas.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(changelog): note Telegram undici dispatcher lifecycle fix

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(telegram): disable HTTP/2 for all Telegram polling dispatchers

Undici 8 enables HTTP/2 ALPN by default, but Telegram's long-polling
connections stall on Windows due to IPv6 + H2 multiplexing issues. The
core fetch-guard already sets allowH2:false for guarded paths, but the
Telegram extension creates its own Agent/ProxyAgent/EnvHttpProxyAgent
instances directly from undici without this flag.

Apply allowH2:false to all dispatcher constructors in the Telegram
transport layer, matching the approach used in src/infra/net/undici-runtime.ts.

Fixes #66885

* fix: avoid false telegram polling stall restarts

* fix(telegram): publish polling health liveness

---------

Co-authored-by: Ethan Chen <ethanbit@qq.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Magicray1217 <magicray1217@users.noreply.github.com>
Co-authored-by: aoao <aoao@openclaw>
2026-04-20 23:03:57 +01:00
Vincent Koc ae4fdaea82 fix(telegram): split monitor runtime types 2026-04-10 10:00:24 +01:00
Gustavo Madeira Santana 28fc5d9b5e Plugin SDK: split approval adapter seams 2026-04-07 16:06:02 -04:00
Gustavo Madeira Santana d78512b09d Refactor: centralize native approval lifecycle assembly (#62135)
Merged via squash.

Prepared head SHA: b7c20a7398
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-04-07 14:40:26 -04:00
Peter Steinberger 17f6626ffe feat(approvals): auto-enable native chat approvals 2026-04-02 17:30:40 +01:00
Vincent Koc 5b952836e3 perf(memory): trim telegram command runtime imports 2026-04-02 14:11:28 +09:00
Vincent Koc 4309dc6d5e perf(memory): lazy-load telegram monitor runtime graphs 2026-04-02 14:07:35 +09:00
Peter Steinberger 6a2c5b2b54 refactor: move telegram error formatting onto ssrf runtime 2026-03-28 02:38:02 +00:00
Peter Steinberger 0c0f1e34cb refactor: split telegram polling and sdk surfaces 2026-03-26 21:13:16 +00:00
pkuGeo e035a0d98c telegram: rebuild transport after stalled polling cycles 2026-03-26 13:11:15 -07:00
Kwest OG 8139f83175 fix(telegram): persist sticky IPv4 fallback across polling restarts (fixes #48177) (#48282)
* fix(telegram): persist sticky IPv4 fallback across polling restarts (fixes #48177)

Hoist resolveTelegramTransport() out of createTelegramBot() so the
transport (and its sticky IPv4 fallback state) persists across polling
restarts. Previously, each polling restart created a new transport with
stickyIpv4FallbackEnabled=false, causing repeated IPv6 timeouts on
hosts with unstable IPv6 connectivity.

Changes:
- bot.ts: accept optional telegramTransport in TelegramBotOptions
- monitor.ts: resolve transport once before polling loop
- polling-session.ts: pass transport through to bot creation

AI-assisted (Claude Sonnet 4). Tested: tsc --noEmit clean.

* Update extensions/telegram/src/polling-session.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* style: fix oxfmt formatting in bot.ts

* test: cover telegram transport reuse across restarts

* fix: preserve telegram sticky IPv4 fallback across polling restarts (#48282) (thanks @yassinebkr)

---------

Co-authored-by: Yassine <yassinebkr@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-17 21:56:12 +05:30
Peter Steinberger 9ebe38b6e3 refactor: untangle remaining plugin sdk boundaries 2026-03-16 21:16:32 -07:00
scoootscooob e5bca0832f refactor: move Telegram channel implementation to extensions/ (#45635)
* refactor: move Telegram channel implementation to extensions/telegram/src/

Move all Telegram channel code (123 files + 10 bot/ files + 8 channel plugin
files) from src/telegram/ and src/channels/plugins/*/telegram.ts to
extensions/telegram/src/. Leave thin re-export shims at original locations so
cross-cutting src/ imports continue to resolve.

- Fix all relative import paths in moved files (../X/ -> ../../../src/X/)
- Fix vi.mock paths in 60 test files
- Fix inline typeof import() expressions
- Update tsconfig.plugin-sdk.dts.json rootDir to "." for cross-directory DTS
- Update write-plugin-sdk-entry-dts.ts for new rootDir structure
- Move channel plugin files with correct path remapping

* fix: support keyed telegram send deps

* fix: sync telegram extension copies with latest main

* fix: correct import paths and remove misplaced files in telegram extension

* fix: sync outbound-adapter with main (add sendTelegramPayloadMessages) and fix delivery.test import path
2026-03-14 02:50:17 -07:00