Commit Graph
30 Commits
Author SHA1 Message Date
chengyongruandGitHub 88c38e9b38 fix(restart): deliver completion after channel reconnects (#4931) 2026-07-15 01:08:39 +08:00
chengyongruandXubin Ren c579551bb1 fix(dingtalk): stop stream task on shutdown 2026-07-04 21:19:25 +08:00
5283ceae85 Add optional Nanobot plugin controls (#4396)
* feat: add optional nanobot features

* test: update azure install hint expectation

* fix: validate optional feature extras

maintainer edit: verify requested dependency extras before treating optional features as installed, propagate restart state from feature enablement, and align docs with the new plugins enable command.

* fix: bound optional feature installs

maintainer edit: make optional feature installs time out as a normal install failure instead of leaving the WebUI or CLI action waiting indefinitely.

* feat: slim optional channel dependencies

* fix: log optional install commands

* fix(webui): gate remote feature installs

* docs: clarify webhook plugin example

* fix(webui): harden optional feature installs

* fix: install optional deps without package fallback

* fix(cli): refine plugin feature controls

* fix(webui): count enabled nanobot features

* fix(webui): allow slow feature install routes

* fix(webui): allow disabling websocket channel

* fix(plugins): simplify optional feature controls

* fix(webui): polish apps catalog states

* fix(webui): confirm nanobot support installs

* fix(webui): polish nanobot install dialog

* fix(webui): suppress empty websocket handshakes

* fix(webui): clarify apps plugin summary

* fix(webui): localize workspace access copy

* fix(plugins): polish optional feature controls (#4691)

---------

Co-authored-by: Xubin Ren <52506698+Re-bin@users.noreply.github.com>
2026-07-03 18:17:52 +08:00
Max HsuandXubin Ren 638af123ba fix(dingtalk): preserve richText formatting and set HTTP client timeout
richText messages only kept rich_text_list items whose type was
"text", so bold/italic/inlineCode/pre segments were silently dropped;
a message made entirely of formatted segments produced empty content
and fell through to the "unsupported message type: richText" warning.
Now any item carrying text is kept (matching the SDK's own
get_text_list, which keys off the "text" field) and its type is mapped
to Markdown so the formatting survives into the agent's context.

Text and downloadCode within a rich-text item are handled
independently (the SDK treats them as separate via get_text_list /
get_image_list), so an item carrying both a caption and an attachment
no longer drops the file.

The shared httpx.AsyncClient was created without a timeout, so all
requests (including large file/image downloads) used httpx's 5s
default and hit ConnectTimeout/ReadTimeout on uploads. Set an explicit
httpx.Timeout (connect=10s, read/write=30s).

Adds regression tests for formatted-segment preservation, the
all-formatted no-drop case, the text+downloadCode item, and the client
timeout configuration.

Closes #4497
2026-06-25 22:52:45 +08:00
李明振andXubin Ren da0aafcfbd feat(dingtalk): add group_user_isolation to separate sessions per user in group chats
Add a new config option group_user_isolation (default: false) to the
DingTalk channel. When enabled, each user in a group chat gets their own
session while bot replies are still routed to the shared group chat.
2026-06-01 23:01:19 +08:00
chengyongruandXubin Ren 05e0106592 refactor(logging): preserve tracebacks and add channel context
- Preserve tracebacks: logger.error in except blocks → logger.exception
- Channel context: BaseChannel injects self.logger = logger.bind(channel=name)
- Third-party bridge: redirect_lib_logging() replaces ad-hoc stdlib-to-loguru bridges
- Log levels: network timeouts downgraded from ERROR → WARNING
- Fix --verbose flag to actually work with loguru (set handler to DEBUG)
2026-05-06 21:17:45 +08:00
hinotoi-agentandXubin Ren ad952e0da2 fix(dingtalk): block SSRF in outbound media fetches 2026-05-01 19:31:45 +08:00
bahtyaandXubin Ren fa98524944 fix(channels): prevent retry amplification and silent message loss across channels
Audited all channel implementations for overly broad exception handling
that causes retry amplification or silent message loss during network
errors. This is the same class of bug as #3050 (Telegram _send_text).

Fixes by channel:

Telegram (send_delta):
- _stream_end path used except Exception for HTML edit fallback
- Network errors (TimedOut, NetworkError) triggered redundant plain
  text edit, doubling connection demand during pool exhaustion
- Changed to except BadRequest, matching the _send_text fix

Discord:
- send() caught all exceptions without re-raising
- ChannelManager._send_with_retry() saw successful return, never retried
- Messages silently dropped on any send failure
- Added raise after error logging

DingTalk:
- _send_batch_message() returned False on all exceptions including
  network errors — no retry, fallback text sent unnecessarily
- _read_media_bytes() and _upload_media() swallowed transport errors,
  causing _send_media_ref() to cascade through doomed fallback attempts
- Added except httpx.TransportError handlers that re-raise immediately

WeChat:
- Media send failure triggered text fallback even for network errors
- During network issues: 3×(media + text) = 6 API calls per message
- Added specific catches: TimeoutException/TransportError re-raise,
  5xx HTTPStatusError re-raises, 4xx falls back to text

QQ:
- _send_media() returned False on all exceptions
- Network errors triggered fallback text instead of retry
- Added except (aiohttp.ClientError, OSError) that re-raises

Tests: 331 passed (283 existing + 48 new across 5 channel test files)

Fixes: #3054
Related: #3050, #3053
2026-04-13 00:30:45 +08:00
Rohit_Dayanand123andXubin Ren 3cc2ebeef7 Added bug fix to Dingtalk by zipping html to prevent raw failure 2026-04-09 10:49:00 +08:00
Meng YuhangandXubin Ren f9ba6197de fix: save DingTalk downloaded files to media dir instead of /tmp 2026-03-15 23:21:22 +08:00
Meng YuhangandXubin Ren 34358eabc9 feat: support file/image/richText message receiving for DingTalk 2026-03-15 23:21:22 +08:00
Xubin RenandXubin Ren dbdb43faff feat: channel plugin architecture with decoupled configs
- Add plugin discovery via Python entry_points (group: nanobot.channels)
- Move 11 channel Config classes from schema.py into their own channel modules
- ChannelsConfig now only keeps send_progress + send_tool_hints (extra=allow)
- Each built-in channel parses dict->Pydantic in __init__, zero internal changes
- All channels implement default_config() for onboard auto-population
- nanobot onboard injects defaults for all discovered channels (built-in + plugins)
- Add nanobot plugins list CLI command
- Add Channel Plugin Guide (docs/CHANNEL_PLUGIN_GUIDE.md)
- Fully backward compatible: existing config.json and sessions work as-is
- 340 tests pass, zero regressions
2026-03-14 16:13:38 +08:00
Re-bin 254cfd48ba refactor: auto-discover channels via pkgutil, eliminate hardcoded registry 2026-03-11 14:23:19 +00:00
dingyanyi2019 35d811c997 feat: support retrieving DingTalk voice recognition text 2026-03-11 10:19:43 +08:00
Re-bin 4e25ac5c82 test(dingtalk): cover group reply routing 2026-03-07 16:07:57 +00:00
shawn_wxn 73991779b3 fix(dingtalk): use msg_key variable instead of hardcoded 2026-03-08 00:01:08 +08:00
shawn_wxn caa2aa596d fix(dingtalk): correct msgKey parameter for group messages 2026-03-08 00:01:08 +08:00
shawn_wxn 26670d3e80 feat(dingtalk): add support for group chat messages 2026-03-08 00:01:08 +08:00
Jack LuandGitHub 3ee061b879 Merge branch 'main' into main 2026-03-01 13:35:24 +08:00
Re-bin 73a708770e refactor: compress DingTalk helpers 2026-02-28 16:23:43 +00:00
JK_Lu 977ca725f2 style: unify code formatting and import order
- Remove trailing whitespace and normalize blank lines
- Unify string quotes and line breaks for long lines
- Sort imports alphabetically across modules
2026-02-28 20:55:43 +08:00
siyuan.qsy cfc55d626a feat(dingtalk): send images as image messages, keep files as attachments 2026-02-28 20:34:23 +08:00
Nikolas de Hor f19baa8fc4 fix: convert remaining f-string logger calls to loguru native format
Follow-up to #864. Three f-string logger calls in base.py and dingtalk.py
were missed in the original sweep. These can cause KeyError if interpolated
values contain curly braces, since loguru interprets them as format placeholders.
2026-02-20 10:01:38 -03:00
Re-bin 73fdd0dd45 fix: complete ensure_ascii=False and UTF-8 encoding migration 2026-02-20 07:59:32 +00:00
Re-bin 37252a4226 fix: complete loguru native formatting migration across all files 2026-02-20 07:55:34 +00:00
Nikolas de Hor 53b83a38e2 fix: use loguru native formatting to prevent KeyError on messages containing curly braces
Closes #857
2026-02-19 17:19:36 -03:00
chtangwin a2379a08ac Fix: Ensure UTF-8 encoding and ensure_ascii=False for remaining file/JSON operations 2026-02-18 18:37:17 -08:00
Re-bin b429bf9381 fix: improve long-running stability for various channels 2026-02-12 01:20:57 +00:00
Re-bin b6ec6a8a76 fix(dingtalk): security and resource fixes for DingTalk channel 2026-02-08 18:06:07 +00:00
w0x7ce 240db894b4 feat(channels): add DingTalk channel support and documentation 2026-02-08 11:58:49 +08:00