mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-27 00:17:53 +00:00
fix(wechat): validate timing configuration (#4280)
This commit is contained in:
parent
5994fdf38c
commit
f8bef42a04
@ -427,7 +427,10 @@ channels:
|
||||
ilink_bot_id: $WECHAT_ILINK_BOT_ID
|
||||
qrcode_login_enabled: true # optional: allow first-time QR bootstrap when bot_token is absent
|
||||
allowed_users: [] # empty = allow all
|
||||
polling_timeout: 35
|
||||
polling_timeout: 35 # timing values must be positive finite seconds
|
||||
polling_retry_delay: 5
|
||||
qrcode_poll_interval: 2
|
||||
qrcode_poll_timeout: 180
|
||||
state_dir: ./.deer-flow/wechat/state
|
||||
max_inbound_image_bytes: 20971520
|
||||
max_outbound_image_bytes: 20971520
|
||||
|
||||
@ -546,6 +546,7 @@ The cached value is reused for both the blocking (`runs.wait`) and streaming (`_
|
||||
- Disabled by default. It is a user-binding layer on top of the existing `channels.*` runtime config, not a replacement for provider bot credentials.
|
||||
- No public IP, OAuth callback URL, or provider webhook route is required by the current implementation.
|
||||
- Telegram uses a deep-link `/start <code>` flow over the existing long-polling worker. Slack, Discord, Feishu/Lark, DingTalk, WeChat, and WeCom use `/connect <code>` over their existing outbound channel workers.
|
||||
- WeChat timing settings (`polling_timeout`, `polling_retry_delay`, `qrcode_poll_interval`, `qrcode_poll_timeout`) accept only positive finite seconds; invalid values fall back to their defaults so polling cannot enter a hot loop or sleep forever.
|
||||
- Frontend APIs: `GET /api/channels/providers`, `GET /api/channels/connections`, `POST /api/channels/{provider}/connect`, and `DELETE /api/channels/connections/{connection_id}`.
|
||||
- Browser APIs remain protected by normal Gateway auth/CSRF. Provider messages arrive through the already-configured channel workers.
|
||||
- Provider-level `connection_status` reflects the user's newest connection row. With no binding it is `not_connected`, except in auth-disabled local mode where a configured running channel reports `connected` because all channel messages already route to the default user.
|
||||
|
||||
@ -8,6 +8,7 @@ import binascii
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import mimetypes
|
||||
import secrets
|
||||
import tempfile
|
||||
@ -1456,9 +1457,10 @@ class WechatChannel(Channel):
|
||||
@staticmethod
|
||||
def _coerce_float(value: Any, default: float) -> float:
|
||||
try:
|
||||
return float(value)
|
||||
except (TypeError, ValueError):
|
||||
parsed = float(value)
|
||||
except (OverflowError, TypeError, ValueError):
|
||||
return default
|
||||
return parsed if math.isfinite(parsed) and parsed > 0 else default
|
||||
|
||||
@staticmethod
|
||||
def _coerce_int(value: Any, default: int) -> int:
|
||||
|
||||
@ -84,6 +84,33 @@ class _MockAsyncClient:
|
||||
return None
|
||||
|
||||
|
||||
def test_timing_config_requires_positive_finite_values():
|
||||
from app.channels.wechat import WechatChannel
|
||||
|
||||
timing_defaults = {
|
||||
"polling_timeout": WechatChannel.DEFAULT_POLLING_TIMEOUT,
|
||||
"polling_retry_delay": WechatChannel.DEFAULT_RETRY_DELAY,
|
||||
"qrcode_poll_interval": WechatChannel.DEFAULT_QRCODE_POLL_INTERVAL,
|
||||
"qrcode_poll_timeout": WechatChannel.DEFAULT_QRCODE_POLL_TIMEOUT,
|
||||
}
|
||||
attributes = {
|
||||
"polling_timeout": "_polling_timeout",
|
||||
"polling_retry_delay": "_retry_delay",
|
||||
"qrcode_poll_interval": "_qrcode_poll_interval",
|
||||
"qrcode_poll_timeout": "_qrcode_poll_timeout",
|
||||
}
|
||||
|
||||
for invalid in (0, -1, float("nan"), float("inf"), float("-inf"), 10**1000):
|
||||
channel = WechatChannel(
|
||||
bus=MessageBus(),
|
||||
config={"bot_token": "test-token", **dict.fromkeys(timing_defaults, invalid)},
|
||||
)
|
||||
assert {key: getattr(channel, attributes[key]) for key in timing_defaults} == timing_defaults
|
||||
|
||||
channel = WechatChannel(bus=MessageBus(), config={"bot_token": "test-token", "polling_retry_delay": "0.25"})
|
||||
assert channel._retry_delay == 0.25
|
||||
|
||||
|
||||
def test_handle_update_publishes_private_chat_message():
|
||||
from app.channels.wechat import WechatChannel
|
||||
|
||||
|
||||
@ -1856,11 +1856,12 @@ run_ownership:
|
||||
# # Optional: sent as SKRouteTag header when provided
|
||||
# route_tag: ""
|
||||
# allowed_users: [] # empty = allow all
|
||||
# # Optional: long-polling timeout in seconds
|
||||
# # Optional: timing values must be positive finite seconds
|
||||
# polling_timeout: 35
|
||||
# # Optional: QR poll interval in seconds when qrcode_login_enabled is true
|
||||
# polling_retry_delay: 5
|
||||
# # QR poll interval when qrcode_login_enabled is true
|
||||
# qrcode_poll_interval: 2
|
||||
# # Optional: QR bootstrap timeout in seconds
|
||||
# # QR bootstrap timeout
|
||||
# qrcode_poll_timeout: 180
|
||||
# # Optional: persist getupdates cursor under the gateway container volume
|
||||
# state_dir: ./.deer-flow/wechat/state
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user