低资源占用,灵活个人助手
为nanobot打分
给出您宝贵的评分:
相关产品
手机端可长按上方图片保存到相册,或点击「下载/分享」分享到微信
使用 nanobot,你可以:
nanobot 是超轻量级个人 AI 智能体,资源占用极低、部署灵活,专注轻量交互、日程管理、信息查询等个人任务,适配多平台。
用户评论 (0)
2026年02月06日
2026年02月06日
2026年03月17日
2026年02月04日
2026年04月07日
2026年02月06日
2026年02月03日
2026年08月23日
2026年08月13日
2026年07月31日
2026年07月22日
2026年07月22日
2026年07月18日
v0.3.0
2026年07月25日
🐈 nanobot v0.3.0 is here: 260 PRs merged and 38 new contributors. The agent gained agency.
The fastest way to experience the release is one command:
nanobot webuiIt prepares the local WebUI, starts the gateway, and opens the browser workbench. On a fresh install, guided setup helps you choose a provider and configure access without beginning in a JSON file. The published package already includes the WebUI, so there is no separate frontend build.
The product story is a WebUI that now feels like the front door to nanobot. Chats read as topics; documents, quoted follow-ups, multimodal tool results, file diffs, code previews, and model fallback are visible in the conversation. Model presets can be switched from the composer, native desktop hosts can open a system folder picker, settings work better across narrow screens and dark mode, and the interface now includes Brazilian Portuguese plus substantially improved Traditional Chinese.
Underneath that experience is agency with boundaries. nanobot can consult inline subagents, carry explicitly authorized work through verification, route turn state through a clearer runtime context, and switch model presets per session. Long-running behavior is deliberate: /goal opts a task into sustained execution, while ordinary conversations remain ordinary conversations.
The foundation is a runtime built for real deployment. Configuration can reload without tearing down the process, channels have clearer package boundaries, gateway restart and shutdown paths are sturdier, and Docker and Render deployment are easier to reproduce. Provider-scoped proxies, OpenCode, Kimi Coding, Grok OAuth with hosted X Search, Parallel Search, Serper, Mattermost, and the native Neonize WhatsApp channel broaden where nanobot can run and what it can reach.
Highlights
- One command to the workbench -
nanobot webuiprepares the local channel, starts the gateway, opens the browser, and leads first-time users into guided setup. - A stronger browser workbench - Topic-style chats, composer model switching, quoted follow-ups, document attachments, native folder selection, responsive settings, and clearer fallback state.
- Agent coordination without core sprawl - Inline subagents can consult inside the active task, authorized work can continue through verification, and typed runtime context keeps provider-owned state out of ad hoc loop logic.
- Explicit long-running goals - Sustained execution is gated behind
/goal, with clearer permission, cancellation, timeout, heartbeat, and local-trigger behavior. - Files and tool activity you can inspect - Syntax-highlighted previews, live file-edit diffs, better code-copy behavior, structured tool errors, richer MCP artifacts, and preserved multimodal tool output.
- A more operational runtime - Live configuration reloads, bounded session and exec state, safer restart/shutdown, cleaner cancellation ownership, more reliable scheduled work, and faster CI.
- Broader providers and search - OpenCode Zen/Go, Kimi Coding, Grok OAuth, provider-scoped proxies, Copilot Enterprise overrides, Parallel Search, Serper, and steadier authentication fallback.
- Channels as maintainable extensions - Native Neonize WhatsApp, Mattermost, improved Feishu/Telegram/Discord/Matrix/QQ behavior, optional channel dependencies, and clearer setup flows.
- Security tightened at the edges - Chained-command allowlist bypasses are blocked, SSRF checks pin validated DNS, credentials are redacted from MCP URLs, remote API binds require authentication, and attachment ingress is constrained.
- Documentation and delivery caught up - Workflow-oriented docs, an automation guide, one-click Render deployment, stronger Docker controls, community-maintained project language, and a refreshed SVG identity.
Upgrade Notes
- WhatsApp now uses Neonize instead of the old Node.js/Baileys bridge. Remove
bridgeUrlandbridgeToken, runnanobot plugins enable whatsapp, and link the account again withnanobot channels login whatsapp. The old bridge authentication data is not reused.allowFromentries should use the sender ID without a leading+. - Sustained goals are now explicit. Use
/goalwhen a task should keep working across continuation turns. Normal chats no longer inherit long-running goal behavior implicitly. - Remote exposure requires authentication. Configurations that bind the API or WebUI gateway beyond loopback must provide the corresponding API or Web token. Localhost setup continues to use the guided short-lived token flow.
Community
Thank you to everyone who shaped v0.3.0: 260 merged PRs, 38 first-time contributors, and a month of careful review across the agent core, WebUI, providers, channels, security, documentation, and deployment. The Agency Release is not about making nanobot act without limits. It is about giving a small, inspectable agent the coordination, evidence, and operational discipline to finish more of the work you intentionally hand it.
What's Changed
- docs: add v0.2.2 release news by @Re-bin in #4461
- fix: skip sendRichMessage when streaming preview exists (#4470) by @axelray-dev in #4472
- fix(providers): dedupe tool_use ids to prevent Anthropic 400s by @tedyyan in #4444
- chore: bump to node 24 by @dvejmz in #4460
- feat(providers): add OpenCode Zen and OpenCode Go providers by @zpljd258 in #4476
- fix(webui): prevent iOS Safari composer zoom by @chengyongru in #4471
- docs: document runtime environment variables by @chengyongru in #4462
- fix(gateway): handle lifecycle edge cases by @chengyongru in #4447
- fix(pairing): normalize sender IDs to str in the pairing store by @waelantar in #4433
- feat(provider): add kimi_coding provider for Kimi Coding Plan by @zpljd258 in #4464
- Fix raw tags in reasoning output by @ZhouJ-sh in #4466
- fix(config): preserve dream cron when saving config by @yorkhellen in #4478
- fix(web): pass proxy to DDGS client for DuckDuckGo search by @hyoukadev in #4484
- fix: exclude archived keys in heartbeat & fallback missing session timestamps by @HengWeiBin in #4468
- fix(webui): keep multi-file apply_patch edits by @chengyongru in #4487
- fix(webui): restore code block copy fallback by @chengyongru in #4509
- test: speed up test suite by @chengyongru in #4507
- fix: add rich_messages config to disable sendRichMessage for Telegram Web (#4488) by @axelray-dev in #4489
- fix(tools): gate MCP resource and prompt registration behind enabledTools by @michaelxer in #4436
- fix(dingtalk): preserve richText formatting and set HTTP client timeout by @maxmilian in #4501
- fix(cli): show search engines (incl. Keenable) in onboard wizard by @IlyaGusev in #4438
- fix(webui): WebM→WAV conversion for Xiaomi MiMo ASR transcription by @zpljd258 in #4493
- fix: advance dream cursor when Dream is disabled to prevent prompt bloat (#4242) by @axelray-dev in #4481
- fix: allow custom provider to configure thinking style (#4429) by @axelray-dev in #4482
- fix: make subagent fail_on_tool_error configurable (#4198) by @axelray-dev in #4485
- docs: clarify heartbeat versus cron delivery by @chengyongru in #4543
- test: harden webui and gateway checks by @chengyongru in #4535
- fix: change exec login-shell default from true to false (#4518) by @axelray-dev in #4525
- fix(session): remove message time replay prefixes by @chengyongru in #4540
- fix(agent): gate microcompaction on context pressure by @chengyongru in #4238
- refactor(whatsapp): replace bridge with neonize by @chengyongru in #4537
- fix(exec): prevent allowPatterns bypass via chained commands by @axelray-dev in #4526
- test: fix flaky test_keeps_n_most_recent due to identical mtimes by @primit1v0 in #4523
- fix: deduplicate tool call IDs in non-stream parser (#4059) by @axelray-dev in #4530
- fix: include _stream_id in stream delta coalescing key (#4063) by @axelray-dev in #4531
- fix: validate content block type in Anthropic assistant blocks (#4060) by @axelray-dev in #4532
- fix: prevent session key collision on disk (#4057) by @axelray-dev in #4533
- fix(cron): guard public APIs against unavailable store by @yorkhellen in #4564
- fix(webui): clear stuck streaming after reconnect and improve stop reliability by @axelray-dev in #4565
- feat(mcp): deliver image content from MCP tools as artifacts by @codedragoncom in #4542
- fix(session): repair corrupt legacy-stem files in list_sessions by @axelray-dev in #4566
- fix(agent): harden tool-call path against malformed relay responses by @m11y in #4569
- fix(context): make replay message cap internal by @chengyongru in #4582
- refactor(session): return RetentionResult instead of bare tuple by @axelray-dev in #4574
- feat(webui): refine prompt rail minimap by @Re-bin in #4600
- fix(streaming): skip non-file-edit tools in apply_final_call_ids to prevent id corruption by @axelray-dev in #4596
- fix(install): skip wizard without an interactive terminal by @chengyongru in #4602
- fix(restart): add explicit restart mode by @chengyongru in #4607
- feat(providers): support GitHub Copilot endpoint overrides for enterprise/GHE by @04cb in #4598
- feat(whatsapp): send read receipts (blue double-check) for incoming messages by @franciscomaestre in #4601
- feat(providers): support provider-scoped proxy config by @chengyongru in #4578
- test(exec): cover bwrap sandbox mounts by @yu-xin-c in #4577
- fix(weixin): stream LLM calls + buffer reply delivery to dodge non-stream relay bug by @m11y in #4567
- fix(mcp): redact credentials from URLs before logging by @weijun-xia in #4584
- fix(cli): allow oauth login to be/set main provider by @hamb1y in #4573
- fix(webui): keep idle compaction out of session recency by @chengyongru in #4609
- refactor(webui): derive provider model catalog kind by @chengyongru in #4613
- refactor(tools): use structured tool error results by @chengyongru in #4610
- feat(api): require api_key when binding to all interfaces (parity with WS gateway) by @dajiaohuang in #4548
- feat(webui): add dollar skill shortcuts by @chengyongru in #4284
- fix(cron): tolerate unsupported directory fsync by @chengyongru in #4617
- refactor(bus): type outbound runtime events by @chengyongru in #4590
- feat(trigger): add session-bound local triggers by @chengyongru in #4591
- fix(trigger): cap local trigger audit records by @Re-bin in #4642
- fix(exec): return early when session command exits by @chengyongru in #4643
- test(cron): cover stale instance mutation consistency by @yu-xin-c in #4633
- test: cover runner blocked tool-call finish reasons by @yu-xin-c in #4630
- fix(webui): hide subagent backfill payloads by @chengyongru in #4641
- fix(agent): avoid tool compaction echo loops by @chengyongru in #4647
- fix(trigger): keep local worker alive on turn cancel by @chengyongru in #4644
- feat(memory): add workspace Dream prompt override by @chengyongru in #4491
- fix(providers): update Anthropic default model to claude-sonnet-4-6 by @bingqilinweimaotai in #4687
- fix: omit temperature for sonnet 5 by @hamb1y in #4685
- Add optional Nanobot plugin controls by @chengyongru in #4396
- feat(cli): add safe WebUI first-run launcher by @Re-bin in #4688
- fix(config): serialize model presets as camelCase by @Yuxin-Lou in #4692
- fix(mcp): contain malformed tool results by @Yuxin-Lou in #4666
- fix(copilot): guard token refresh with asyncio.Lock to prevent race condition by @axelray-dev in #4684
- fix(pairing): restore durable atomic writes by @yorkhellen in #4653
- fix(dingtalk): stop stream task on shutdown by @chengyongru in #4646
- fix(gateway): handle Windows stop fallback by @Raccoon-njuse in #4690
- fix(providers): standardize oauth_cli_kit error messages across CLI and WebUI by @axelray-dev in #4698
- fix: normalize text tool call markup by @hamb1y in #4662
- fix: isolate matrix stream buffers by @hamb1y in #4659
- fix: resolve builtin skill reads by @hamb1y in #4658
- fix(exec): default Windows commands to PowerShell and allow shell parameter by @dajiaohuang in #4545
- feat(web-search): add Serper.dev (Google Search API) provider by @franciscomaestre in #4406
- fix: limit long MCP-derived tool names by @thomya in #4700
- fix(webui): keep chat viewport and composer inside narrow viewports, fixes #4693 by @hata33 in #4694
- fix(dream): ground memory audit records in the real git diff by @goodtiding5 in #4673
- feat: support canonical opencode provider by @hamb1y in #4686
- feat(feishu): add new session divider by @chengyongru in #4763
- feat: add Mattermost channel support by @goodtiding5 in #4459
- fix(cli): print response text when streaming fails in interactive mode by @goodtiding5 in #4654
- fix(gateway): self-heal state file PID on server startup by @dajiaohuang in #4547
- fix(gateway): resolve config path for state refresh by @Re-bin in #4770
- fix: pin validated dns for ssrf checks by @hamb1y in #4671
- feat(cli): support multiline input via Alt+Enter by @m11y in #4614
- chore: remove unused dead code by @chengyongru in #4824
- fix(webui): show generic tool arguments in activity by @chengyongru in #4821
- refactor(webui): drive slash commands from lifecycle metadata by @chengyongru in #4766
- fix: require api key for serve by @hamb1y in #4669
- Fix missing aiohttp slack dependency in pyproject.toml by @alekwo in #4830
- fix(webui): keep prompt rail out of narrow chat columns by @chengyongru in #4831
- Feature: non-interactive config refresh with 'nanobot onboard --refresh' by @alekwo in #4852
- docs: improve search entry pages by @chengyongru in #4850
- fix(webui): gate bootstrap API token issuance by @chengyongru in #4849
- refactor(agent): extract turn hook assembly by @chengyongru in #4848
- fix(webui): restore localhost bootstrap API tokens by @chengyongru in #4856
- feat(webui): add file edit diff progress view by @chengyongru in #4828
- fix(matrix): preserve mxc markdown image sources by @chengyongru in #4859
- Add Dockerfile arg to override optional Python dependencies to install at build time by @dvejmz in #4857
- refactor(agent): establish turn/runtime context foundation by @chengyongru in #4868
- docs: add automation guide by @chengyongru in #4865
- fix(webui): sync package-lock.json to resolve docker build failure by @SIDD-KIDD in #4863
- fix(sandbox): add Red Hat certificate path support for Node by @luojiaaoo in #4845
- fix(cli): handle CSI-u Shift+Enter instead of dumping raw escapes by @m11y in #4832
- fix(webui): bind landing first message to created chat by @sidkang in #4836
- fix(shell): reap zombie processes on all subprocess exit paths by @macroadster in #4840
- feat(webui): highlight file previews and diffs by @chengyongru in #4877
- feat(webui): guide queued prompt with second Enter by @chengyongru in #4876
- fix(tools): enforce exact edit_file line hints by @chengyongru in #4635
- fix(dream): skip no-op periodic commit attempts by @alekwo in #4873
- fix(mcp): keep transport cleanup in owner tasks by @flyzstu in #4843
- refactor(agent): gate sustained goals behind explicit /goal by @chengyongru in #4844
- fix(webui): allow remote workspace access reduction by @Re-bin in #4892
- fix(heartbeat): rewrite prompt to execute tasks instead of reporting by @wzrayyy in #4896
- fix(discord): route unauthorized DMs to pairing by @chengyongru in #4899
- fix(memory): prune encoded Dream sessions by @chengyongru in #4900
- feat(webui): add guided setup flows by @Re-bin in #4855
- fix(cli): restore enter before webui prompts by @Re-bin in #4903
- fix(gateway): harden health endpoint exposure by @Re-bin in #4906
- fix: align optional dependency contracts by @chengyongru in #4907
- fix(dream): filter non-Dream history commits by @chengyongru in #4905
- fix(codex): align OAuth defaults and setup docs by @chengyongru in #4910
- docs: remove broken Star History embed by @chengyongru in #4912
- docs: update recent changes through July 12 by @chengyongru in #4913
- feat(webui): add Brazilian Portuguese (pt-BR) locale by @bill-kopp-ai-dev in #4914
- fix(dream): ignore line-ending-only memory diffs by @bingqilinweimaotai in #4909
- fix(telegram): HTML parse_mode for stream overflow chunks by @asif786ka in #4839
- fix(shell): decode UTF-16 process output on Windows by @adabarbulescu in #4917
- docs: reorganize documentation around user workflows by @chengyongru in #4916
- feat(webui): support document attachments with ingress safeguards by @chengyongru in #4771
- refactor(webui): centralize native runtime access by @chengyongru in #4769
- fix(agent): add wall-clock timeout for streaming LLM requests by @wingkwong in #4902
- fix: catch asyncio CancelledError in close_mcp shutdown by @bjoshuanoah in #4842
- fix: install timezone data on Windows by @chengyongru in #4921
- chore(codex): identify failing request stage by @chengyongru in #4929
- feat(webui): add copy action to user messages by @chengyongru in #4930
- fix(webui): sync package-lock.json for qrcode dependency by @3L1AS in #4927
- fix: standardize --config help text across CLI commands by @rbankole in #4932
- test: speed up CI and harden the suite by @chengyongru in #4936
- feat(webui): highlight slash commands and app mentions by @chengyongru in #4933
- fix(restart): deliver completion after channel reconnects by @chengyongru in #4931
- fix(heartbeat): make response evaluation more configurable by @wzrayyy in #4915
- fix(cli): point onboarding to the WebUI launcher by @chengyongru in #4938
- fix(webui): validate inferred file paths before preview by @chengyongru in #4935
- fix(webui): correct activity timer duration by @chengyongru in #4649
- fix(providers): honor Codex proxy config consistently by @chengyongru in #4943
- fix(gateway): stop channels before draining tasks by @chengyongru in #4944
- docs(readme): reflect community maintenance by @Re-bin in #4950
- feat(webui): support native folder picker bridges by @Re-bin in #4953
- fix(providers): omit temperature for Moonshot Kimi K2.5/K2.6 by @bingqilinweimaotai in #4967
- Improve zh-TW Traditional Chinese locale by @PeterDaveHello in #4958
- fix(utils): handle empty commit messages in CommitInfo.format by @santhreal in #4973
- fix(utils): coerce Tavily usage counters to int by @santhreal in #4972
- fix(utils): avoid hang in split_message when max_len <= 0 by @santhreal in #4971
- fix(exec): isolate exec session managers by @yu-xin-c in #4862
- fix: preserve real cancellation in MCP paths by @adabarbulescu in #4960
- fix(session): bound the in-memory session cache by @KDB-Wind in #4957
- (fix docker) Harden default Docker Compose security by @Yuxin-Lou in #4955
- feat: add Kimi K3 support by @bingqilinweimaotai in #4966
- fix(cron): dual-case keys when loading jobs.json by @santhreal in #4974
- feat: add one-click deploy to render support by @Ho1yShif in #4937
- fix(agent): guide recovery from oversized tool results by @chengyongru in #4925
- fix(triggers): coerce null ms fields when loading local triggers by @santhreal in #4986
- fix(gitstore): resolve staged paths relative to workspace by @kuchazi-yy in #4979
- fix(cli-apps): decode subprocess output as UTF-8 by @kuchazi-yy in #4976
- fix(providers): fail over across provider failure domains by @chengyongru in #4904
- fix(whatsapp): allow group ids in allowFrom by @chengyongru in #4834
- fix(triggers): reject deliveries to disabled channels by @kuchazi-yy in #4990
- refactor(channels): make built-in channels self-contained by @chengyongru in #4908
- fix(webui): resolve Windows package manager shims by @chengyongru in #4994
- fix(webui): show copy action on every assistant message by @chengyongru in #5001
- style(webui): simplify Markdown code blocks by @chengyongru in #5002
- fix(channels): complete dependency manifest migration by @chengyongru in #4995
- docs(ollama): document tool prompt cache diagnostics by @chengyongru in #4998
- fix(qq): add exponential backoff to WebSocket reconnect loop by @gola in #4768
- refactor(agent): unify internal turn lifecycle by @chengyongru in #4993
- fix(session): tolerate unsupported directory fsync by @amplifierplus in #5004
- fix: stop masking runtime failures by @chengyongru in #5011
- fix(cron): coerce null runHistory ms fields from jobs.json by @santhreal in #4985
- fix(runner): narrow BaseException catch to Exception in tool execution by @axelray-dev in #4816
- fix(session): cap messages at persistence boundary by @KDB-Wind in #4956
- fix(exec): terminate active session process trees on shutdown by @KDB-Wind in #4978
- fix(security): validate each shell segment against exec.allowPatterns by @michaelxer in #4562
- fix(files): reject oversized reads before loading by @amplifierplus in #5014
- fix(webui): keep Markdown table diffs inline by @chengyongru in #5015
- fix(webui): prioritize skill names in autocomplete by @chengyongru in #5016
- fix(config): write config.json atomically via temp+replace by @santhreal in #4984
- fix(transcription): resolve ${VAR} env refs in transcription api_key/api_base by @benlenarts in #4989
- feat(providers): support Codex fast mode by @chengyongru in #5019
- fix(cron): coerce string schedule/state ms fields from jobs.json by @santhreal in #4983
- fix(providers): sanitize UTF-16 surrogates at provider request boundary by @Krislu1221 in #4952
- feat(webui): highlight skill references in sent messages by @chengyongru in #5020
- Feat/modelscope provider support by @yrk111222 in #4965
- docs(security): recommend env-var references over plaintext API keys by @cms19859230182-lang in #5010
- fix: quarantine invalid tool results by @hamb1y in #4663
- fix(providers): add Qwen model-level thinking style mapping by @cms19859230182-lang in #5023
- feat(webui): show pin indicators for pinned chats by @chengyongru in #5025
- feat(config): watch runtime configuration changes by @chengyongru in #5026
- fix(webui): detect Chrome voice recording support by @chengyongru in #5027
- style(webui): clarify surface hierarchy by @chengyongru in #5029
- fix(webui): improve mobile composer layout by @chengyongru in #5030
- fix(subagent): cascade exec session termination on /stop by @yorkhellen in #5021
- fix(webui): avoid mobile welcome composer overlap by @chengyongru in #5031
- fix(agent): preserve agent-owned state in project workspaces by @chengyongru in #4945
- feat(webui): polish agent output and app discovery by @Re-bin in #4963
- fix(webui): deliver late subagent results as new turns by @chengyongru in #4992
- feat(agent): make model presets session-scoped by @chengyongru in #4866
- feat(providers): add xAI Grok OAuth with capability-gated X Search by @chengyongru in #5035
- feat(image): apply generation settings live by @Re-bin in #4964
- fix(agent): deliver non-streamed finalization responses by @chengyongru in #5049
- docs: explain slow optional dependency installs by @chengyongru in #5048
- feat(xai): surface hosted X Search activity by @chengyongru in #5050
- fix(feishu): keep fenced markdown tables out of card tables by @santhreal in #5046
- fix(slack): keep fenced markdown tables intact in _to_mrkdwn by @santhreal in #5045
- fix(pairing): treat null approved channel lists as empty by @santhreal in #5044
- fix(cron): skip null runHistory elements when loading jobs.json by @santhreal in #5043
- fix: add one second to retry after delays by @wzrayyy in #4959
- fix(telegram): expose proxy setup in WebUI by @chengyongru in #5033
- fix(providers): fall back on authentication errors by @chengyongru in #5052
- fix(session): fall back to legacy paths in metadata reads by @axelray-dev in #4941
- chore: pin migration TODOs to v0.2.4 by @chengyongru in #5053
- feat(webui): indicate per-turn model fallback by @chengyongru in #5017
- fix(documents): preserve DOCX table content by @Re-bin in #5039
- style(webui): unify settings and dark mode surfaces by @chengyongru in #5058
- fix(webui): polish responsive layouts and settings search by @chengyongru in #5060
- fix(webui): keep composer model badge in sync by @Re-bin in #5067
- fix(session): tolerate files removed during listing by @KDB-Wind in #5068
- fix(exec): retain stale sessions after cleanup failure by @KDB-Wind in #5066
- fix(telegram): advance markdown split on long single-line fences by @santhreal in #5055
- fix(exec): extract absolute paths after equals sign in shell guard by @axelray-dev in #4594
- fix(webui): allow media directory access when restrictToWorkspace is enabled by @cms19859230182-lang in #5065
- feat(webui): simplify model preset settings by @chengyongru in #5061
- test(agent): use python3 in ExecTool workspace scope tests by @flyzstu in #5064
- feat(webui): present chats as topics by @chengyongru in #5070
- feat(webui): add Parallel Search MCP preset by @georgeatparallel in #5047
- fix: preserve pending message runtime context by @hamb1y in #4665
- fix(webui): show quoted context after follow-up send by @chengyongru in #5071
- Revert "fix: preserve pending message runtime context" by @chengyongru in #5072
- feat(webui): switch model presets from the composer by @chengyongru in #5077
- fix(webui): honor custom gateway port with Vite by @chengyongru in #5076
- fix(providers): preserve multimodal tool outputs by @Re-bin in #5073
- feat(agent): support inline subagent consultation by @Re-bin in #5074
- feat(agent): carry authorized tasks through verification by @Re-bin in #5075
- feat: launch first-time setup in webui by @chengyongru in #5078
- Add nanobot logo (SVG) by @d1ago in #5079
- feat(brand): migrate README and WebUI assets to SVG by @chengyongru in #5080
- chore(release): prepare v0.3.0 by @Re-bin in #5081
New Contributors
- @tedyyan made their first contribution in #4444
- @dvejmz made their first contribution in #4460
- @ZhouJ-sh made their first contribution in #4466
- @hyoukadev made their first contribution in #4484
- @maxmilian made their first contribution in #4501
- @codedragoncom made their first contribution in #4542
- @m11y made their first contribution in #4569
- @weijun-xia made their first contribution in #4584
- @dajiaohuang made their first contribution in #4548
- @bingqilinweimaotai made their first contribution in #4687
- @Raccoon-njuse made their first contribution in #4690
- @thomya made their first contribution in #4700
- @hata33 made their first contribution in #4694
- @goodtiding5 made their first contribution in #4673
- @SIDD-KIDD made their first contribution in #4863
- @luojiaaoo made their first contribution in #4845
- @sidkang made their first contribution in #4836
- @flyzstu made their first contribution in #4843
- @wzrayyy made their first contribution in #4896
- @bill-kopp-ai-dev made their first contribution in #4914
- @asif786ka made their first contribution in #4839
- @adabarbulescu made their first contribution in #4917
- @wingkwong made their first contribution in #4902
- @bjoshuanoah made their first contribution in #4842
- @3L1AS made their first contribution in #4927
- @rbankole made their first contribution in #4932
- @PeterDaveHello made their first contribution in #4958
- @santhreal made their first contribution in #4973
- @KDB-Wind made their first contribution in #4957
- @Ho1yShif made their first contribution in #4937
- @kuchazi-yy made their first contribution in #4979
- @gola made their first contribution in #4768
- @amplifierplus made their first contribution in #5004
- @Krislu1221 made their first contribution in #4952
- @yrk111222 made their first contribution in #4965
- @cms19859230182-lang made their first contribution in #5010
- @georgeatparallel made their first contribution in #5047
- @d1ago made their first contribution in #5079
Full Changelog: v0.2.2...v0.3.0
详细ChangeLogv0.2.2
2026年06月23日
🐈 nanobot v0.2.2 is here — 140 PRs merged, 21 new contributors. The agent got sturdier!
The headline is durability. WebUI conversations now survive more of real life: transcripts are segmented instead of living in one fragile file, forked chats preserve replies more reliably, active turns scroll and replay more predictably, startup paths block less, and gateway shutdown is much calmer. Long sessions, stale providers, slow routes, broken config files, malformed history, stream stalls, and empty provider responses all got less likely to derail the work.
The second story is nanobot becoming a real Python runtime. The SDK is no longer just a thin convenience layer around the agent loop: concurrent run() calls are isolated, hooks are cleaner, MCP lifecycle handling is safer, runtime controls are broader, and the docs now teach the SDK from first principles. If you want to embed nanobot inside your own application, v0.2.2 is the first release where that path feels intentional.
The third story is the workbench getting broader and easier to live in. The WebUI gained automation management, prompt navigation, token usage visibility, mobile polish, better update checks, richer activity timing, and a faster settings surface. The ecosystem expanded with Firecrawl as a keyless Web Data app, Exa / Bocha / Keenable / Volcengine search, more transcription providers, custom image generation, better Mistral and Kimi handling, and many channel fixes across Telegram, Feishu, WhatsApp, Slack, Email, QQ, DingTalk, and more.
Highlights
-
More durable WebUI sessions — Segmented transcript storage keeps large conversations readable without throwing away old turns, fork/replay paths preserve assistant replies more reliably, session deletion cleans up legacy files, refreshes no longer revive stale content, and active turns stay anchored while the model works. The WebUI also got prompt navigation, better mobile layout, clearer activity durations, token usage rendering, safer startup fetches, and on-demand version checks.
-
Python SDK as a first-class runtime — The SDK now has safer concurrent
run()behavior, explicit runtime controls, cleaner per-run hook handling, better MCP cleanup, improved facade lifecycle behavior, and more beginner-friendly documentation. This makes nanobot easier to embed in scripts, services, evaluations, and custom agent products. -
Gateway and onboarding polish — The gateway gained background/service controls, cleaner foreground shutdown, safer Ctrl+C behavior, and better MCP stdio cleanup. The onboarding flow was simplified around provider-first Quick Start, more neutral provider selection, safer WebUI setup, rollback on WebSocket failure, and better keyboard navigation.
-
Search, speech, and provider coverage — Web search now covers Firecrawl, Exa, Bocha, Keenable, and Volcengine paths; transcription expanded with shared voice input plus OpenRouter, StepFun, SiliconFlow, Xiaomi MiMo, and AssemblyAI support. Providers got better Mistral reasoning handling, Kimi K2.7 thinking, OpenAI-compatible query/body controls, custom image generation, OpenAI image edits, safer Anthropic tool IDs, and stronger retry/fallback behavior.
-
Reliability hardening across the agent core — Recent-history context is token-capped, idle auto-compact is on by default, Dream explains empty runs, malformed history is skipped, history cursors stay monotonic, tool schema estimates are cached, unknown builtin tool parameters are rejected, provider fallback logs the primary error, and stream stalls can retry or fall back without returning a truncated answer.
-
Channels that behave more like real apps — Telegram gained richer message support with safer fallback detection; Feishu got streaming recovery, WebSocket card reading, table extraction, lazy SDK loading, and QR login; WhatsApp got read receipts, forwarded-message handling, and LID mapping; Slack allowlisted channels can require mentions; Email gained attachments and IMAP post-actions; QQ / Napcat, DingTalk, Weixin, Matrix, and others received targeted fixes.
-
Security and workspace boundaries — Unsafe MCP HTTP URLs are rejected before probing, local provider endpoints bypass env proxies while cloud endpoints still respect them, workspace write policy is clearer, git commands work from workspace subdirectories without relaxing path guards, bwrap gets a sane
HOME, and stripped image inputs no longer leak misleading local paths.
Community
Huge thanks to everyone who shipped v0.2.2 — 140 PRs, 21 first-time contributors, and a lot of careful review work. This release is less about one big switch and more about making nanobot dependable enough to keep open every day: steadier sessions, cleaner extension points, broader providers, and fewer sharp edges when real work gets long.
What's Changed
- Refactor WebUI runtime state onto event bus by @chengyongru in #4135
- feat(dingtalk): add group_user_isolation to separate sessions per use… by @lmzopq in #4016
- feat(search): add Volcengine web search provider by @Re-bin in #4141
- fix(webui): sort Chats group among projects by recency by @chengyongru in #4151
- Fix WebUI refresh location routing by @chengyongru in #4150
- fix: Support fallback copy for WebUI replies by @chengyongru in #4149
- fix(memory): serialize cursor allocation in append_history (#4081) by @04cb in #4147
- feat(channels): Add Napcat (QQ) channel by @chengyongru in #4146
- feat(webui): add prompt rail and polish links by @Re-bin in #4156
- fix(runner): prevent read_file offload loop by @jiehaoZ in #4155
- refactor: split WebUI gateway dependencies by @chengyongru in #4115
- fix(webui): bound startup fetch waits by @chengyongru in #4157
- feat(email): add file attachment support to email channel by @chengyongru in #4162
- refactor(dream): replace two-phase Dream class with simple cron + process_direct by @chengyongru in #3990
- fix(session): reset out-of-range last_consolidated to recover hidden history (#4066) by @04cb in #4169
- fix(email): skip progress messages to prevent empty emails after tool calls by @nblondiau in #4165
- fix: restore top-level import order by @chengyongru in #4174
- fix(qq): send pairing codes for unauthorized C2C users by @yorkhellen in #4180
- fix(mcp): reconnect terminated sessions by @chengyongru in #4171
- feat(webui): add new chat keyboard shortcut by @chengyongru in #4185
- test: improve deterministic unit test coverage by @chengyongru in #4189
- fix(cli): fall back to uv pip when pip is unavailable by @axelray-dev in #4164
- Add run-level agent hook lifecycle by @chengyongru in #4176
- feat(provider): Add support for Azure AAD based Auth for Azure OpenAI provider by @kunalk16 in #4126
- fix(feishu): strip leading bot mention before commands by @Re-bin in #4184
- feat(image): support custom image generation provider by @axelray-dev in #4187
- Fix DM pairing for Weixin and Telegram by @chengyongru in #4197
- fix(webui): persist user messages for refresh by @chengyongru in #4201
- feat(command): add /skill slash command to list enabled skills by @Endeavour-Yuan in #3968
- fix(sdk): close MCP connections from Nanobot facade by @axelray-dev in #4216
- fix(providers): allow dropping default OpenAI image params via null extraBody by @04cb in #4209
- feat(desktop): polish desktop shell and shared WebUI surfaces by @Re-bin in #4195
- fix(whatsapp): handle LID group mentions by @danielphang in #2663
- fix: preserve empty-string reasoning_content instead of coercing to None by @michaelxer in #4227
- Fix token usage heatmap rendering by @chengyongru in #4248
- docs: remove nightly branch guidance by @chengyongru in #4245
- fix(mcp): reject unsafe HTTP URLs before probe by @yu-xin-c in #4123
- feat(transcription): add shared voice input support by @Re-bin in #4232
- feat(providers): add extra_query config for OpenAI-compatible providers by @axelray-dev in #4217
- feat(transcription): configurable STT model + OpenRouter transcription provider by @breitburg in #4113
- feat(transcription): add Xiaomi MiMo ASR provider (mimo-v2.5-asr) by @zpljd258 in #4175
- feat(transcription): add AssemblyAI as transcription provider by @franciscomaestre in #4224
- Improve tool call validation strictness by @chengyongru in #4190
- fix(webui): render TeX math delimiters by @chengyongru in #4252
- feat(email): add configurable IMAP post-actions for processed messages by @chengyongru in #4258
- docs: make onboarding friendlier for beginners by @chengyongru in #4177
- feat(webui): add assistant reply fork-from-here by @Bayern4ever-dot in #4208
- fix(tools): keep apply_patch additions line-separated by @yu-xin-c in #4266
- fix(providers): use max_completion_tokens for GPT-5/o-series models (#4261) by @04cb in #4268
- fix(agent): finalize max-iteration turns without tools by @chengyongru in #4269
- Add Exa web search provider by @erikmackinnon in #4213
- feat(asr): add StepFun ASR SSE transcription provider by @morandot in #4260
- fix(sandbox): set HOME inside bwrap by @primit1v0 in #4239
- search: add Bocha web search provider by @morandot in #4182
- fix(websocket): Fix bug in webui where session content is dropped by @Syoc in #4267
- fix(feishu): lazy-load lark SDK during gateway startup by @chengyongru in #4277
- Fail fast on invalid config files by @chengyongru in #4275
- Scope prompt recent history by session by @chengyongru in #4274
- feat(exec): add pathPrepend config by @chengyongru in #4273
- fix(providers): allow retry and fallback on stream stalled timeout by @aiguozhi123456 in #4272
- refactor(webui): on-demand version check in Settings > About by @JiajunBernoulli in #4255
- feat(webui): segment transcript storage by @Re-bin in #4278
- feat(transcription): add SiliconFlow as transcription provider by @morandot in #4281
- fix(utils): make split_message fenced-code-block-aware by @axelray-dev in #4257
- feat(slack): add groupRequireMention to scope allowlist channels to @mentions by @brendanlevy in #4289
- feat: support multiple custom OpenAI-compatible providers by @JagoWang in #3239
- fix(session): prevent orphaned tool results from being persisted to history (#4006) by @tangtaizong666 in #4306
- feat(bridge): WhatsApp forwarded message detection, startup guard, and contact handling by @franciscomaestre in #4226
- feat(cron): bind scheduled automations to sessions by @chengyongru in #4299
- chore(repo): remove desktop app from core repo by @Re-bin in #4294
- Break tool config schema import cycle by @chengyongru in #4314
- Fix WebUI startup blocking on slow gateway routes by @chengyongru in #4327
- fix(memory): summarize full session tail during idle compaction (#4264) by @tangtaizong666 in #4326
- fix(cli): use configured bot_icon in agent interactive banner (#4262) by @04cb in #4335
- fix(providers): widen omit_temperature to cover opus-4-8 and fable by @axelray-dev in #4334
- Fix Codex image SSE handling by @cypggs in #4332
- docs: add Kimi and MiniMax partner links by @oriengy in #4295
- docs(readme): link Kimi partner banner by @Re-bin in #4338
- fix(webui): localize update check copy by @chengyongru in #4331
- docs(readme): add themed cover image by @Re-bin in #4341
- Improve WebUI mobile responsiveness by @chengyongru in #4339
- Add tools.file.enable to toggle built-in filesystem tools by @niradler in #4138
- fix(runner): ignore empty injected payloads by @yu-xin-c in #4337
- fix(memory): ignore malformed history entries by @yu-xin-c in #4315
- fix(api): forward real LLM usage in /v1/chat/completions response by @michaelxer in #4310
- fix(session): keep auto compact suffix on user turn by @chengyongru in #4348
- fix(agent): refresh goal continuation context by @chengyongru in #4359
- fix(webui): override wsUrl with local LAN IP when on dev server port 5173 by @HengWeiBin in #4364
- chore: ignore bridge/node_modules by @franciscomaestre in #4355
- fix(providers): enable thinking for Kimi K2.7 models by @Re-bin in #4361
- fix(api): avoid duplicate user turn on empty-response retry (#4079) by @04cb in #4358
- fix(providers): validate stream idle timeout config by @yu-xin-c in #4363
- fix(context): cap recent-history digest by tokens, not characters by @waelantar in #4352
- Explain empty Dream runs by @chengyongru in #4369
- Enable idle auto-compact by default by @chengyongru in #4370
- Fix macOS installer for externally managed Python by @chengyongru in #4368
- docs: use pipe pattern for curl installer commands by @HaisamAbbas in #4365
- feat(webui): add automation management view by @chengyongru in #4330
- fix: silence unroutable cli progress noise by @chengyongru in #4386
- fix: log primary model error before fallback by @chengyongru in #4385
- fix: recover failed Feishu streaming updates by @chengyongru in #4381
- fix: allow git commands in workspace subdirectories by @HaisamAbbas in #4380
- fix(providers): disable proxy for local endpoints, respect env proxy for cloud by @michaelxer in #4367
- fix(anthropic): sanitize tool_use/tool_result IDs to API pattern by @franciscomaestre in #4356
- Fix my tool model preset switching by @chengyongru in #4347
- fix(webui): correct activity duration display by @chengyongru in #4283
- fix(session): preserve user turns in replay-window history by @Re-bin in #4349
- Clarify filesystem workspace write policy by @chengyongru in #4202
- feat(bridge): send read receipts (blue ticks) for incoming WhatsApp messages by @franciscomaestre in #4354
- feat(providers): better Mistral support by @La-Volpe in #4351
- feat(web): add Keenable search provider by @IlyaGusev in #4350
- feat(feishu): add QR scan-to-create bot CLI login feishu command by @bllackhu in #4391
- ci: skip docs-only changes by @chengyongru in #4400
- feat(webui): make Firecrawl a keyless Web Data app by @Re-bin in #4403
- fix(fallback): treat empty API choices as fallbackable error, 将 API 返回空 choices 视为可 fallback 的错误 (#4287) by @yonghuname in #4288
- [codex] fix MCP malformed progress notifications by @yu-xin-c in #4372
- fix(providers): use non-descriptive placeholder when stripping images by @michaelxer in #4401
- fix(feishu): support reading WebSocket rendered card content by @JiajunBernoulli in #4342
- fix: support OpenAI image reference edits by @sbyinin in #4394
- fix(session): delete_session also removes legacy path files to prevent history revival by @yorkhellen in #4246
- fix: set httpx timeout for streamableHttp transport by @lucndm in #4230
- feat(whatsapp): seed LID->phone mappings on startup by @franciscomaestre in #4407
- fix(memory): keep history cursor monotonic by @yu-xin-c in #4256
- perf(tokens): cache tool schema estimates by @yu-xin-c in #4428
- fix(telegram): narrow rich capability error detection and fix misleading log by @zpljd258 in #4423
- fix(tools): reject unknown builtin parameters by @yu-xin-c in #4343
- feat(web): allow Keenable search without an API key by @IlyaGusev in #4405
- fix(sdk): isolate per-run hooks for concurrent run() calls by @michaelxer in #4425
- feat(sdk): expand Python SDK runtime controls by @Re-bin in #4296
- docs(readme): update news through 2026-06-20 by @Re-bin in #4432
- Improve onboard wizard setup flow by @chengyongru in #4395
- feat(gateway): add background and service controls by @xcosmosbox in #1854
- fix(webui): avoid slow settings route refreshes by @chengyongru in #4398
- chore(config): default context window to 200k by @chengyongru in #4448
- fix: close MCP stdio transports from agent task by @Re-bin in #4450
- fix(webui): stabilize sent turn layout and dev reloads by @Re-bin in #4451
- chore(release): prepare v0.2.2 by @Re-bin in #4445
- fix(webui): follow active turn output after send by @Re-bin in #4453
- fix: stabilize gateway shutdown and webui fork replay by @Re-bin in #4454
- fix(gateway): tolerate cancelled channel tasks during shutdown by @Re-bin in #4456
New Contributors
- @lmzopq made their first contribution in #4016
- @nblondiau made their first contribution in #4165
- @michaelxer made their first contribution in #4227
- @breitburg made their first contribution in #4113
- @zpljd258 made their first contribution in #4175
- @Bayern4ever-dot made their first contribution in #4208
- @erikmackinnon made their first contribution in #4213
- @primit1v0 made their first contribution in #4239
- @Syoc made their first contribution in #4267
- @brendanlevy made their first contribution in #4289
- @JagoWang made their first contribution in #3239
- @tangtaizong666 made their first contribution in #4306
- @oriengy made their first contribution in #4295
- @niradler made their first contribution in #4138
- @waelantar made their first contribution in #4352
- @La-Volpe made their first contribution in #4351
- @IlyaGusev made their first contribution in #4350
- @bllackhu made their first contribution in #4391
- @yonghuname made their first contribution in #4288
- @sbyinin made their first contribution in #4394
- @lucndm made their first contribution in #4230
Full Changelog: v0.2.1...v0.2.2
详细ChangeLogv0.2.1
2026年06月01日
🐈 nanobot v0.2.1 is here — 84 PRs merged, 17 new contributors. The agent got a real workbench.
The headline is the WebUI becoming the place where work actually happens. The chat surface is smoother, faster, and easier to trust: live file edits show up as activity, tool traces render more cleanly, source links get readable favicons, markdown and code blocks behave better, new chats survive refreshes, and Thought / response ordering now matches the model's real turn structure. Settings, sidebar controls, model switching, context-window control, slash commands, project workspaces, and access modes all moved closer to a single coherent control surface.
The second story is long-running work getting more durable. Sustained goals no longer trip the runner, goal iteration budget is higher, session locks prevent overlapping turns from stepping on each other, AutoCompact and consolidation races were fixed, heartbeat moved onto cron, and session archive retention got several data-loss fixes. In practice, this means fewer mysterious interruptions, fewer duplicate archives, and a much better chance that a long agent workflow keeps its thread of intent.
The third story is nanobot becoming easier to plug into real stacks. CLI Apps and MCP now share a more unified extension path; preset setup and capability mentions make tools easier to discover; the extension registry gives integrations a first-class home. Provider coverage expanded across Ant Ling, Skywork, Novita, Step Plan, StepFun, Zhipu image generation, OpenAI/Codex image generation, Ollama image generation, and richer OpenAI-compatible configuration. Channels also grew with Signal, Telegram webhook mode, Discord model slash commands, Matrix verification fixes, and safer Weixin / Teams / Matrix behavior.
Highlights
-
WebUI as a daily workbench — The WebUI is no longer just a packaged chat surface. It now has better activity rendering, live file edit visibility, cleaner source links, stronger markdown/code rendering, improved sidebar performance, project workspaces, access controls, context-window settings, model controls, slash command actions, and a more polished native-host feel. The final Thought / response ordering fix makes streamed agent work read in the order it actually happened. (#3877, #3899, #3906, #3951, #3953, #3987, #4007, #4045, #4108, #4121, #4137)
-
Long-running agent stability — Goal mode and multi-turn work got sturdier: sustained goals keep the runner alive, goal iteration budget is extended,
process_directnow has per-session locking, streaming/session concurrency bugs were tightened, AutoCompact and consolidator races were fixed, and archive retention now avoids duplicate archives and message loss. (#3881, #3999, #4041, #4104, #4127, #4129) -
CLI Apps, MCP, and extension workflows — CLI Apps landed as a way to connect CLI-native tools, then got unified with MCP concepts through preset setup, capability mentions, stale install recovery, registry logos, and an extension registry source. The result is a clearer path from "I have a useful local tool" to "nanobot can invoke it in a workflow." (#3963, #3979, #3991, #4046)
-
More providers, richer model routing — The provider surface widened with Ant Ling, Skywork, Novita, Step Plan, OpenAI API type selection,
extraBody, and multiple image-generation providers including StepFun, OpenAI/Codex, Ollama, and Zhipu. Several follow-up fixes preserve tool-call IDs, improve quota/billing errors, handle provider transport edge cases, and keep thinking/reasoning controls honest across OpenAI-compatible routes. (#3900, #3910, #3916, #3927, #3946, #3954, #3971, #3974, #3984, #3988, #4048) -
Channels and deployment polish — Signal support, Telegram webhook mode, Discord model slash commands, Docker/WebUI deployment fixes, and clearer secret/deployment docs make nanobot easier to run outside a local terminal. Gateway cold start also dropped dramatically, from seconds to sub-second territory. (#3872, #3918, #3935, #3996, #4031)
-
Security and reliability hardening — WebSocket token issuance now requires auth, redirect targets are validated before web fetches, IPv6-mapped IPv4 addresses are normalized in SSRF checks, Teams replies trust service URLs, Matrix inbound media downloads are bounded, and shell/exec behavior was tightened on Windows and URL-heavy commands. (#3928, #3933, #4051, #4086, #4103, #4106, #4047)
-
Internationalization and docs — The WebUI locale set was filled out across zh-TW, ja, and remaining keys, the README positioning and news section were refreshed, multi-language doc links were surfaced, local provider setup is easier to find, and
AGENTS.mdgives coding agents a clearer way into the repo. (#3930, #3962, #3964, #4131)
Community
Huge thanks to everyone who shipped v0.2.1 — 84 PRs, 29 contributors, and a warm welcome to 17 first-time contributors. This release feels less like one big feature drop and more like nanobot becoming something you can keep open all day: steadier, clearer, and much easier to extend.
What's Changed
- fix(providers): recognize Chinese rate-limit marker '访问量过大' as transient error by @chengyongru in #3864
- fix docker build and webui by @huanglei214 in #3872
- docs(configuration): expand secrets section with more examples by @olgagaga in #3866
- docs(deployment): match docker run gateway example to docker-compose.yml (refs #3873) by @voidborne-d in #3874
- fix(agent): resolve race between AutoCompact and Consolidator by @chengyongru in #3881
- fix(cli): buffer reasoning tokens to avoid one-token-per-line display by @li-yazhou in #3878
- feat(webui+agent): optimize streaming, activity rendering, and runtime sync by @Re-bin in #3877
- fix(webui): preserve single newlines in markdown rendering by @chengyongru in #3889
- feat(cli): add Model Preset wizard to onboard by @chengyongru in #3890
- feat(webui): add live file edit activity by @Re-bin in #3899
- feat(providers): add Ant Ling support by @Re-bin in #3900
- refactor(image-generation): introduce provider registry by @chengyongru in #3893
- docs: surface local provider setup in README by @yanalialiuk in #3912
- feat(webui): upgrade settings and sidebar controls by @Re-bin in #3906
- fix(webui): accept end/error phases in tool trace rendering by @HengWeiBin in #3894
- feat(image-generation): add StepFun (阶跃星辰) provider support by @morandot in #3910
- feat(providers): add Skywork first-level support by @Re-bin in #3916
- perf: optimize gateway cold start from ~4.6s to ~480ms by @chengyongru in #3918
- fix(exec): detach stdin for shell commands by @Re-bin in #3922
- fix(providers): update Skywork APIFree agent endpoint by @morandot in #3917
- docs(readme): add multi-language doc site links by @chengyongru in #3930
- feat(signal): add Signal channel support by @chengyongru in #3935
- fix(provider): deduplicate streaming tool_call_ids for parallel calls by @chengyongru in #3943
- fix(webui): keep new chat during session refresh by @boogieLing in #3944
- fix(weixin): prevent silent message drops from poll exceptions, expired tokens, and ret=-2 by @chengyongru in #3684
- fix(providers): inject OpenRouter
reasoning.effortfor thinking models (follow-up to #3851) by @olgagaga in #3867 - Fix shell guard false positives on URL commands by @HaisamAbbas in #3933
- feat(tools): optimize coding workflows by @Re-bin in #3923
- feat: add Novita AI provider by @Alex-yang00 in #3927
- feat(webui): refine collapsible sidebar by @Re-bin in #3951
- feat(webui): improve sidebar performance by @Re-bin in #3953
- fix: drop redundant reasoning_effort for Kimi thinking models by @agbocsardi in #3940
- fix(webui): avoid misleading file edit counters by @Re-bin in #3957
- refactor(apply_patch): remove deprecated patch mode, keep edits-only by @chengyongru in #3960
- feat(image-generation): add OpenAI and Codex provider support by @ZegWe in #3954
- Add Ollama image generation support by @HaisamAbbas in #3946
- fix: dedupe Responses replay item ids by @Yuxin-Lou in #3961
- Unify image provider HTTP handling and document Gemini image base URLs by @HaisamAbbas in #3929
- chore: fill zh-TW and ja locale keys by @yu-xin-c in #3962
- [security] fix(web): validate redirect targets before fetching by @Hinotoi-agent in #3928
- chore: fill remaining WebUI locale keys by @yu-xin-c in #3964
- feat(cli): add CLI Apps for CLI-Anything integrations by @Re-bin in #3963
- test(cli): cover CLI Apps on Windows CI by @Re-bin in #3965
- feat: Add Zhipu (智谱) image generation provider by @JiajunBernoulli in #3971
- fix: uncap exec config timeout and normalize transcription apiBase (#3595, #3637) by @04cb in #3967
- docs: use xiaomi_mimo provider for MiMo token plan by @honjiaxuan in #3972
- feat(spawn): allow per-subagent sampling temperature (#3969) by @04cb in #3975
- feat(mcp): add preset setup and capability mentions by @Re-bin in #3979
- fix(provider): preserve OpenAI-compatible tool call ids by @Yuxin-Lou in #3984
- feat(webui): improve slash command actions by @Re-bin in #3987
- feat(providers): add OpenAI API type and extra body configuration by @outlook84 in #3974
- fix(agent): propagate maxConcurrentSubagents config to SubagentManager by @Felix8568 in #3978
- feat(providers): add Step Plan support by @morandot in #3988
- feat(apps): unify CLI apps and MCP by @Re-bin in #3991
- fix(agent): prevent runner from exiting while sustained goal is active by @chengyongru in #3999
- fix(web): update Kagi search API integration by @agbocsardi in #4004
- feat(telegram): add webhook mode by @outlook84 in #3996
- chore: enable WebUI ESLint by @yu-xin-c in #3981
- fix(provider): handle blank Codex transport errors by @ehs208 in #4009
- fix(provider): honor NANOBOT_STREAM_IDLE_TIMEOUT_S in Codex provider by @yeounhyeok in #4018
- feature: Add Discord model slash command by @hamb1y in #4031
- refactor(heartbeat): migrate heartbeat service to cron-based auto-registration by @chengyongru in #4023
- Fix session, goal, streaming, and context-budget bugs by @hamb1y in #4041
- feat(webui): add project workspaces and access controls by @Re-bin in #4007
- feat(webui): add context window setting by @Re-bin in #4045
- feat(channels): add document extraction toggle by @boogieLing in #4049
- fix(providers): surface clear arrearage warning to user on quota/billing errors (#3006) by @04cb in #4048
- [security] fix(msteams): trust service URLs before replies by @Hinotoi-agent in #4047
- feat(apps): add nanobot extension registry by @Re-bin in #4046
- fix(exec): bypass cmd.exe for multi-line python -c commands on Windows by @chengyongru in #4051
- [security] fix(matrix): bound inbound media downloads by @Hinotoi-agent in #4106
- fix(security): normalize IPv6-mapped IPv4 addresses in SSRF checks by @yorkhellen in #4086
- fix: coerce typeless Anthropic content blocks + add Dream enable toggle (#3993, #3885) by @04cb in #4054
- feat(webui): refine output timeline and model controls by @Re-bin in #4108
- fix(agent): acquire per-session lock in process_direct (#4080) by @04cb in #4104
- fix(matrix): handle SAS device verification by @mytechdream in #4110
- fix(heartbeat): skip empty HEARTBEAT.md and fail closed on delivery (#4111) by @04cb in #4114
- Require auth for WebSocket token issuance by @hamb1y in #4103
- fix(webui): handle undefined language in code blocks by @Flinn-X in #4117
- feat(webui): polish chat rendering and host runtime by @Re-bin in #4121
- fix(agent): extend sustained goal iteration budget by @Re-bin in #4127
- fix(webui): preserve Thought/response ordering by @Re-bin in #4137
- docs: add AGENTS.md for Codex by @jiehaoZ in #4131
- fix(session): prevent duplicate archive and message loss in enforce_file_cap by @yorkhellen in #4129
New Contributors
- @huanglei214 made their first contribution in #3872
- @voidborne-d made their first contribution in #3874
- @li-yazhou made their first contribution in #3878
- @HengWeiBin made their first contribution in #3894
- @HaisamAbbas made their first contribution in #3933
- @Alex-yang00 made their first contribution in #3927
- @agbocsardi made their first contribution in #3940
- @ZegWe made their first contribution in #3954
- @Yuxin-Lou made their first contribution in #3961
- @yu-xin-c made their first contribution in #3962
- @outlook84 made their first contribution in #3974
- @Felix8568 made their first contribution in #3978
- @ehs208 made their first contribution in #4009
- @yeounhyeok made their first contribution in #4018
- @hamb1y made their first contribution in #4031
- @mytechdream made their first contribution in #4110
- @jiehaoZ made their first contribution in #4131
Full Changelog: v0.2.0...v0.2.1
详细ChangeLogv0.2.0
2026年05月16日
🐈 nanobot v0.2.0 is here 🎉 — 105 PRs merged, 20 new contributors. The agent learned to hold a goal.
The headline is /goal. Mark a thread as a sustained objective with long_task, and the active goal stays pinned in Runtime Context every turn — surviving compaction, surviving long tool chains, surviving the model's own forgetfulness — until you call complete_goal. The wall-clock timeout widens automatically while a goal is active; streaming requests fall back to an idle timeout instead of a hard wall, so a model that's still thinking doesn't get killed mid-thought.
The second story is the WebUI growing up. After several releases as a source-only preview, it now ships inside the wheel — pip install nanobot-ai and you have it. Settings and BYOK got a full redesign, the slash palette is localized, LAN access is gated by a token, reasoning streams live to the chat, and a brand-new image-generation tool turns "draw me X" into an inline preview without leaving the conversation.
The third story is the engine room. The agent loop got a real refactor — AgentLoop.from_config() for clean embedding, _process_message rewritten as a functional state machine, archived summary moved into the system prompt for KV cache stability, tools converted to a self-describing plugin architecture, ask_user and GlobTool retired in favor of cleaner replacements. Five new providers (AWS Bedrock Converse, NVIDIA NIM, LongCat, Atomic Chat, MiMo) join the lineup with fallback_models as a safety net so a single flaky endpoint can't take a turn down. Plus four [security] fixes — SSRF, media path confinement, softer workspace boundaries — and chat-native pairing so DM approvals finally happen in the chat instead of in a config file.
Highlights
-
/goaland long-running tasks — agent with a memory of why — The newlong_tasktool, paired with/goalandcomplete_goal, marks a thread as a sustained objective. The active goal is mirrored in Runtime Context every turn so the agent stays anchored even after compaction, the WebUI surfaces the goal in the chat header, and the LLM wall timeout is automatically widened while a goal is active so longer reasoning passes don't get killed mid-thought. Core agents and subagents both honor the longer budget; streaming requests fall back to an idle timeout instead of a hard wall clock so a model that's still emitting tokens won't be prematurely cut off. (#3788, #3855) -
Image generation, end to end — A new image-generation tool plus a WebUI image mode let you go from prompt to picture without leaving the chat. Generated images render inline with rounded previews; replay-window and dedup paths were tightened so images don't double-deliver across long sessions, and the consolidation pass now respects the replay window when hiding history. (#3695, #3687)
-
WebUI shipped in the wheel + a year's worth of polish —
pip install nanobot-ainow bundles the WebUI: enable the WebSocket channel, runnanobot gateway, open the browser. Nocd webui && bun run buildrequired. After several releases under a "preview" label, the WebUI is now a packaged surface. Inside it: redesigned settings and BYOK flow (including BYOK web search), localized slash palette, model preset badge that stays in sync across slash commands and config reloads, streamed reasoning rendered live, image previews, LAN access gated bytokenIssueSecret, default-to-new-chat on load, scroll preservation on settings return, acrypto.randomUUIDshim for non-secure-context LAN use, and dropped eager markdown preload to cut first-paint cost. (#3653, #3661, #3703, #3709, #3656, #3658, #3733, #3759, #3782) -
Five new providers and a fallback safety net — Native AWS Bedrock Converse lands as a first-class provider (#3574), with a follow-up that preserves Bedrock tool config across history (#3758). NVIDIA NIM (#3707), LongCat via OpenAI-compatible routing (#3114), Atomic Chat as a local OpenAI-compatible target (#3750), and MiMo with proper thinking-control wiring (#3734, #3851) round out the lineup. On top of the wider stack,
fallback_modelslets you list secondary models that take over when the primary fails (#3756), DeepSeek reasoning history is back-filled instead of dropped (#3616, #3560), Codex prompt cache keys stabilized (#3793), and Anthropic auto-falls back to streaming on long-request errors (#3579). -
Model presets and runtime switching —
ModelPresetConfiglets you name model + provider bundles in config and swap between them at runtime via/model(or the WebUI badge). Presets sync across slash commands, config reloads, and settings changes, so the model badge always matches what the next turn will hit. (#3714) -
Core refactor — a cleaner agent loop, a smaller surface —
AgentLoop.from_config()centralizes loop assembly so embedders stop reaching into private internals (#3708)._process_messagewas rewritten as a functional state machine with explicit transitions instead of nested branches (#3715). The archived conversation summary moved into the system prompt to keep KV caches stable across compactions (#3711). Tools became a self-describing plugin architecture (#3729).ask_userwas removed in favor of structuredmessage-tool choices (#3757), andGlobToolwas retired in favor ofread_fileglob support (#3841). Vulture- and coverage-verified dead code was excised (#3755, #3719). Logging now preserves tracebacks and carries channel context (#3651, #3678). RuffFrules are fully enforced in CI (#3672), and the agent test suite was expanded and restructured (#3766). NewCLAUDE.mdand.agent/guides give AI contributors a stable on-ramp (#3534, #3860). -
Pairing, DM approvals, and security hardening — Chat-native pairing (#3774) lets you approve DMs from inside chat instead of editing config. On the safety front: SSRF blocked in DingTalk outbound media (#3569), Feishu downloaded-media filenames confined to safe paths (#3789), local media attachments confined for the message tool (#3842), SSRF guard recovery softened so a transient miss doesn't poison subsequent turns (#3635), and workspace boundary violations get a retry-throttled soft warning instead of crashing the loop (#3614). Telegram silently ignores unauthorized senders instead of leaking error responses (#3629).
-
Memory, dream, and session durability — Cron
jobs.jsongained atomic writes with corrupt-store detection (#3606). Dream cursor only advances on completed batches (#3631) and restores correctly with memory state on resume (#3660). Replay-window hidden history is now properly consolidated (#3687). Workspace and tool-state changes survive restarts more reliably end-to-end. -
Channel and platform fixes — Feishu group threads honor reply chains and topic isolation (#3547, #3704, #3747, #3775), Matrix skips pre-startup events and stops the sync loop on irrecoverable auth (#3575, #3578), WhatsApp voice messages download cleanly (#3607), Wecom preserves real filenames (#3751), Telegram quiets unauthorized senders (#3629), and Weixin raises on send failures so messages don't silently drop (#3659). On Windows: UNC path support in shell extraction (#3764). On the CLI: surrogate code points sanitized before the message bus (#3697), retry-wait messages no longer garble interactive output (#3705, #3609), and
nanobot provider logoutlands as a proper command (#3612). -
Smaller things you'll feel — Configurable
bot_name/bot_icon(#3730), configurabletoolHintMaxLength(#3641), real SSE streaming restored on the OpenAI-compatible API (#3677), Whisper transcription retries on transient failures (#3646), sequential MCP server connects to stop CPU spin (#3640), MCP HTTP probe before connect (#3740), Brave search backoff under rate limits (#3840),sender_idin Runtime Context for user-aware responses (#3549), runtime context appended after user content for cache stability (#3844),origin_message_idoutbound deduplication (#3561), and a Python SDKRunResultthat finally exposestools_usedandmessages(#3620).
Community
Heartfelt thanks to everyone who shipped v0.2.0 — 105 PRs, 33 contributors, and a huge welcome to 20 first-time contributors. Every review, patch, and bug report helped; this release is a shared win. 🎉
What's Changed
- fix(feishu): streaming card and tool hint respect reply_to_message in groups by @04cb in #3543
- Revert "fix(feishu): streaming card and tool hint respect reply_to_message in groups" by @Re-bin in #3548
- fix(feishu): respect reply_to_message for group threads by @boogieLing in #3547
- fix(agent): respect configured max iterations for subagents by @boogieLing in #3532
- feat(provider): add native AWS Bedrock Converse support by @Re-bin in #3574
- feat(skill): add nanobot upgrade wizard skill by @chengyongru in #3539
- bugfix(#3751): ReadFileTool says "File unchanged since last read:" across different sessions by @LZDQ in #3576
- refactor: replace try-except blocks with contextlib.suppress for cleaner error handling across multiple files by @JackLuguibin in #3566
- fix(matrix): skip events received before bot startup by @coldxiangyu163 in #3575
- fix(matrix): don't send empty room messages from blank progress callbacks by @halldorjanetzko in #3573
- [security] fix(dingtalk): block SSRF in outbound media fetches by @Hinotoi-agent in #3569
- fix(matrix): correct allow_room_mentions default type by @spinvettle in #3563
- fix: API stream lifecycle for tool-backed requests by @boogieLing in #3555
- feat(context): Add sender_id to LLM runtime context for user-aware responses by @yorkhellen in #3549
- fix: origin_message_id support and outbound deduplication by @tongtianli03-code in #3561
- fix: adjust DeepSeek reasoning mode check condition by @JiajunBernoulli in #3560
- fix(web_fetch): sanitize URL to strip markdown backticks and quotes before validation by @XJPeng12 in #3528
- fix: strip partial think tags in streaming output by @hongshunanhai in #3577
- fix(matrix): stop sync loop on irrecoverable auth errors by @coldxiangyu163 in #3578
- fix(anthropic): auto-fallback to stream on long-request error by @coldxiangyu163 in #3579
- fix(helpers): restore tiktoken fallback in estimate_prompt_tokens_chain by @yorkhellen in #3582
- feat(provider): add LongCat via OpenAI-compatible backend by @morandot in #3114
- fix: allow_patterns take priority over deny_patterns in ExecTool by @chengyongru in #3594
- Improve beta WebUI turn completion and chat isolation by @ramonpaolo in #3583
- fix(cli): stop provider retry messages garbling interactive output by @04cb in #3609
- fix(cron): atomic write for jobs.json + don't silently overwrite corrupt store by @hussein1362 in #3606
- fix(runner): soft workspace boundary with retry throttle by @Re-bin in #3614
- fix(agent): prevent safety guard false positives and streamed message drop by @chengyongru in #3613
- fix(bridge): support WhatsApp voice message download by @yorkhellen in #3607
- feat(cli): add provider logout command by @chengyongru in #3612
- fix: backfill DeepSeek reasoning_content history instead of dropping it (#3554, #3584) by @04cb in #3616
- feat(agent): limit concurrent subagent execution by @chengyongru in #3634
- fix: only advance dream_cursor on completed batches to prevent silent loss by @JiajunBernoulli in #3631
- fix: return absolute path for downloaded Feishu media files by @futurist in #3632
- fix(telegram): ignore unauthorized users silently by @kaseru in #3629
- fix(sdk): populate RunResult.tools_used and RunResult.messages by @chengyongru in #3620
- fix(agent): soften SSRF guard recovery by @Re-bin in #3635
- refactor(logging): preserve tracebacks and add channel context by @chengyongru in #3651
- fix(agent): gate provider progress deltas for non-streaming channels by @boogieLing in #3645
- feat(config): add toolHintMaxLength to control tool hint truncation by @chengyongru in #3641
- fix: use sequential MCP server connections to prevent CPU spin by @chengyongru in #3640
- fix(transcription): retry Whisper calls on transient failures by @chengyongru in #3646
- feat(webui): polish chat layout and titles by @Re-bin in #3653
- fix(webui): allow LAN access when host is 0.0.0.0 by @chengyongru in #3656
- fix(webui): require token_issue_secret for LAN bootstrap with frontend auth by @chengyongru in #3658
- fix(weixin): raise exceptions on message send failure to prevent silent loss by @chengyongru in #3659
- feat(webui): polish chat UX and slash commands by @Re-bin in #3661
- fix(dream): restore cursor with memory state by @Jefsky in #3660
- refactor(logging): preserve tracebacks in remaining except blocks by @chengyongru in #3678
- chore(ci): Enable full ruff -F (all F rules) checks and fix related errors by @yorkhellen in #3672
- fix(api): remove enable_compression to restore real SSE streaming by @zhw415876999-prog in #3677
- fix(onboard): allow empty strings and falsy values in input fields by @chengyongru in #3691
- feat: add image generation tool and WebUI mode by @Re-bin in #3695
- fix(memory): consolidate history hidden by replay window by @Re-bin in #3687
- feat(webui): redesign settings and BYOK configuration by @Re-bin in #3703
- fix(cli): sanitize surrogate code points before entering message bus by @chengyongru in #3697
- fix(feishu): send all messages to topic when in thread by @yorkhellen in #3704
- fix: log errors in silent exception handlers (matrix + weixin channels) by @vystartasv in #3664
- fix(cli): handle retry-wait messages in interactive mode by @eugenechae in #3705
- docs: add CLAUDE.md and .agent/ guides for AI contributors by @chengyongru in #3534
- feat(webui): add BYOK web search settings by @Re-bin in #3709
- fix(agent): persist _last_summary across restarts with used sentinel by @chengyongru in #3685
- Revert "fix(agent): persist _last_summary across restarts with used sentinel" by @Re-bin in #3710
- refactor: introduce AgentLoop.from_config() to centralize loop assembly by @chengyongru in #3708
- refactor(loop): convert _process_message to functional state machine by @chengyongru in #3715
- fix(utils): remove unreachable dead code in find_legal_message_start by @chengyongru in #3719
- fix(agent): move archived summary into system prompt for KV cache stability by @chengyongru in #3711
- feat: add NVIDIA NIM provider support by @barreler126 in #3707
- feat(cli): make bot name and icon configurable (#3650) by @pixan-ai in #3730
- fix(providers): wire MiMo to thinking_type to allow disabling reasoning (#3585) by @pixan-ai in #3734
- fix(webui): shim crypto.randomUUID for non-secure contexts by @NearlCrews in #3733
- fix(wecom): preserve real filename from SDK when payload omits name (#3737) by @04cb in #3751
- refactor(tools): plugin architecture with self-describing tools by @chengyongru in #3729
- fix(providers): set supports_max_completion_tokens for VolcEngine providers by @AlbertWang688 in #3738
- feat(feishu): add topic_isolation config switch by @yorkhellen in #3747
- feat(config): add ModelPresetConfig and runtime preset switching by @chengyongru in #3714
- chore: remove dead code (vulture + coverage verified) by @chengyongru in #3755
- fix(provider): preserve Bedrock tool config for history by @Re-bin in #3758
- refactor(agent): remove ask_user tool by @chengyongru in #3757
- fix(webui): default to new chat on load and preserve scroll on settings return by @XJPeng12 in #3759
- test(agent): expand coverage and refactor test structure by @chengyongru in #3766
- feat(reason): display model reasoning content during streaming by @Flinn-X in #3655
- feat(runner): model failover with fallback_models by @chengyongru in #3756
- fix(mcp): probe HTTP port before connecting to prevent event-loop crash by @chengyongru in #3740
- fix(feishu): register no-op handlers for bot member events by @chengyongru in #3775
- fix(agent): persist shortcut commands without polluting LLM context by @chengyongru in #3779
- [security] fix(feishu): confine downloaded media filenames by @Hinotoi-agent in #3789
- feat(pairing): chat-native DM sender approval by @chengyongru in #3774
- fix(shell): support UNC paths in Windows path extraction by @JiajunBernoulli in #3764
- fix: clear media_paths after successful voice transcription by @tamvicky in #3752
- refactor(tools): remove GlobTool by @chengyongru in #3841
- [security] fix(message): confine local media attachments by @Hinotoi-agent in #3842
- perf(agent): append runtime context after user content for cache stability by @chengyongru in #3844
- fix(web): back off Brave search rate limits by @boogieLing in #3840
- fix(codex): stabilize prompt cache key by @boogieLing in #3793
- feat(goal): /goal command & long-running tasks (long_task) by @Re-bin in #3788
- fix(webui): remove eager markdown preload by @yorkhellen in #3782
- feat: add Atomic Chat as OpenAI-compatible local LLM provider by @yanalialiuk in #3750
- docs(contributing): warn that
ruff formatpredates the codebase by @olgagaga in #3850 - fix(agent): align LLM wall timeout with sustained goals for agents by @Re-bin in #3855
- fix(exec): allow format in URL parameters while still blocking the format command by @Endeavour-Yuan in #3853
- docs: update CLAUDE.md to reflect current codebase by @chengyongru in #3860
- fix(agent): remove duplicate runtime context injection in mid-turn drain by @chengyongru in #3859
- fix(providers): wire MiMo thinking control on gateway providers (#3845) by @olgagaga in #3851
New Contributors
- @LZDQ made their first contribution in #3576
- @halldorjanetzko made their first contribution in #3573
- @Hinotoi-agent made their first contribution in #3569
- @spinvettle made their first contribution in #3563
- @tongtianli03-code made their first contribution in #3561
- @hongshunanhai made their first contribution in #3577
- @futurist made their first contribution in #3632
- @kaseru made their first contribution in #3629
- @Jefsky made their first contribution in #3660
- @zhw415876999-prog made their first contribution in #3677
- @vystartasv made their first contribution in #3664
- @eugenechae made their first contribution in #3705
- @barreler126 made their first contribution in #3707
- @NearlCrews made their first contribution in #3733
- @AlbertWang688 made their first contribution in #3738
- @Flinn-X made their first contribution in #3655
- @tamvicky made their first contribution in #3752
- @yanalialiuk made their first contribution in #3750
- @olgagaga made their first contribution in #3850
- @Endeavour-Yuan made their first contribution in #3853
Full Changelog: v0.1.5.post3...v0.2.0
详细ChangeLogv0.1.5.post3
2026年04月29日
🐈 nanobot v0.1.5.post3 is here 🎉 — 57 PRs merged, 12 new contributors. The agent learned to talk in threads.
If v0.1.5.post2 was about reach and polish, v0.1.5.post3 is about conversations becoming first-class citizens of their platform. Feishu group topics get isolated sessions. Discord threads inherit parent allowlists and keep their own context. Telegram can render inline keyboard choices. MSTeams prunes stale conversation references so outbound messages stop failing silently. And across all channels, sendProgress and sendToolHints can now be overridden per channel — quiet the noisy ones, keep the verbose ones. Underneath, DeepSeek-V4 is supported end to end: thinking mode and legacy session compatibility ship together, with follow-up fixes for incomplete reasoning history and non-string message content so long threads stay stable. A new ask_user tool lets the agent pause and ask you to choose mid-task. Olostep and Hugging Face joined the provider lineup, and a pair of timeout env vars (NANOBOT_LLM_TIMEOUT_S and NANOBOT_OPENAI_COMPAT_TIMEOUT_S) keep hung requests from holding your session hostage. The WebUI continued to evolve — image uploads, video rendering, ask-user choices, model settings — but remains source-preview only, not bundled into the wheel.
Highlights
-
Threads everywhere — Feishu, Discord, Slack, MSTeams — Each channel grew up this release. Feishu group topics now isolate sessions so messages in one topic don't leak into another; streaming cards and tool hints follow the original topic. Discord threads inherit their parent channel's
allowChannelsand get session isolation, which also means slash commands respect the allowlist. Slack stopped losing thread context on proactive replies. MSTeams conversation references gained TTL-based pruning (refTtlDays), auto-cleanup for Web Chat refs, and a touch interval to keep active refs alive. The theme is consistent: conversations belong to their thread, not to the channel at large. (#3449, #3397, #3440, #3462, #3475, #3447, #3487) -
Per-channel progress and interaction controls —
sendProgressandsendToolHintsused to be global on-or-off switches. Now you can place them inside any individual channel config to override the global default — keep Telegram quiet while WebSocket stays verbose. The agent also learned to ask users structured questions mid-task via the newask_usertool: in WebUI these render as buttons, in other channels they fall back to text. Telegram got inline keyboards (inline_keyboards: true) for renderingmessagetool button choices. The/history [n]command lets you review recent messages without scrolling. (#3487, #2791, #3398, #3454, #3466) -
DeepSeek-V4 and the wider provider stack — This release makes DeepSeek-V4 a first-class target: thinking mode and legacy session compatibility land in one go (#3420), so you can point the agent at V4 without abandoning older conversations. Real-world transcripts exposed two gaps that got dedicated follow-ups — truncated or incomplete reasoning history (#3453) and heterogeneous (non-string) message content (#3458) — so tool-heavy sessions don’t fall over mid-run. On top of that, Hugging Face Inference Providers arrived as a first-class provider (#3496), Olostep joined web search (#3505), OpenAI-compatible endpoints gained
extraBodyfor vLLM guided decoding and friends (#3491), and the timeout pairNANOBOT_LLM_TIMEOUT_S/NANOBOT_OPENAI_COMPAT_TIMEOUT_Ssplit outer turn limits from inner HTTP bounds (#3428, #3478). GitHub Copilot routes GPT-5 and o-series models correctly (#3380); Gemini routing picks upreasoning_effort="none"and Gemma (#3515). -
Memory and session hardening —
consolidationRatio(0.1–0.95) lets you tune how aggressively token-triggered consolidation compresses context.maxMessages(default 120) caps the replay window without touching persistence. History.jsonl gained atomic writes with fsync and directory sync, closing the last data-loss window on unexpected shutdowns. A raw_archive bloat path and several stuck-consolidation edges were sealed. Sessions now fsync on graceful shutdown. The result: memory is both more tunable and more durable. (#3285, #3482, #3508, #3369, #3412, #3415, #3459) -
macOS LaunchAgent and deployment — A new
docs/deployment.mdsection walks through deployingnanobot gatewayas a macOS LaunchAgent — plist,launchctl bootstrap/enable/kickstart, log paths, and the inevitable port-conflict gotcha when you forget to stop a manual gateway. Useful for anyone who wants the agent online at login without keeping a terminal open. (#3441) -
Security and reliability fixes — A shell injection vector via
path_appendon non-Windows platforms was closed. Workspace directory violations now stop the agent loop instead of logging a warning.resolve_config_env_varsstopped stripping excluded fields. Anthropic image_url blocks inside tool_result content get converted correctly. MCP capability names are sanitized for model API compatibility. Windows MCP stdio launchers avoid WinError 193. Structured tool-event payloads give channels richer progress data. Document parsers lazy-import to cut cold-start time. Twenty-odd smaller fixes across providers, channels, and the agent loop round out the release. (#3366, #3493, #3383, #3387, #3470, #3379, #3399, #3423)
Community
Heartfelt thanks to everyone who shipped v0.1.5.post3 — 57 PRs, 27 contributors, and a huge welcome to 12 first-time contributors. Every review, patch, and bug report helped; this release is a shared win. 🎉
What's Changed
- feat(transcription): add language parameter for Whisper STT by @chengyongru in #3375
- fix: normalize DashScope reasoning_effort (minimal vs minimum) by @hlgone in #3374
- fix(cli): respect sys.stdout.isatty() in commands.py by @knightconnorp in #3370
- fix(session): fsync sessions on graceful shutdown to prevent data loss by @hussein1362 in #3369
- fix(providers): support GPT-5 models on GitHub Copilot backend by @gongpx20069 in #3380
- fix(mcp): avoid WinError 193 for Windows stdio launchers by @lahuman in #3379
- fix(agent): prevent duplicate responses when sub-agents complete concurrently by @chengyongru in #3385
- fix(anthropic): convert image_url blocks inside tool_result content by @tetratorus in #3387
- fix(config): preserve excluded fields in resolve_config_env_vars by @saimonventura in #3383
- feat(webui): image attachments — composer + signed media pipeline by @Re-bin in #3393
- feat(telegram): add inline keyboard buttons by @gthieleb in #3398
- feat(agent): emit structured tool-event payloads via on_progress by @pblocz in #3399
- fix(agent): prevent history.jsonl bloat from raw_archive and stuck consolidation by @chengyongru in #3412
- fix(agent): bound remaining memory/history pollution paths by @Re-bin in #3415
- fix(provider): support DeepSeek V4 thinking mode and legacy session compatibility by @Re-bin in #3420
- fix(anthropic): omit temperature for opus-4-7 (#3417) by @04cb in #3418
- perf(document): lazy-import heavy document parsers by @mvanhorn in #3423
- feat(channels): add video support for Telegram and WebSocket by @Re-bin in #3429
- feat(webui): render video media attachments by @Re-bin in #3430
- fix(agent): add LLM request timeout to prevent session lock starvation by @yorkhellen in #3428
- docs: add macOS LaunchAgent setup for gateway by @choiking in #3441
- feat(agent): add ask user tool by @lzmjlrt in #2791
- fix(msteams): send threaded replies via replyToId by @chengyongru in #3447
- feat(feishu): thread-scoped sessions, reply_in_thread, non-blocking reaction by @chengyongru in #3449
- fix(providers): disable HTTP keepalive for local/LAN endpoints by @hussein1362 in #3444
- fix(heartbeat): inject delivered messages into channel session for reply continuity by @hussein1362 in #3391
- fix(provider): gate reasoning-to-content fallback behind spec flag by @chengyongru in #3446
- feat(memory): make consolidate ratio configurable by @chengyongru in #3285
- fix(security): prevent shell injection via path_append on non-Windows platforms by @yorkhellen in #3366
- fix(provider): handle incomplete DeepSeek reasoning history by @Re-bin in #3453
- feat(webui): add ask-user choices and model settings by @Re-bin in #3454
- fix(slack): preserve thread context for proactive replies by @Re-bin in #3462
- fix(agent): expose session timestamps in model context by @Re-bin in #3463
- fix(mcp): sanitize MCP capability names for model API compatibility by @chengyongru in #3470
- fix(slack): polish threaded replies and proactive delivery by @Re-bin in #3475
- fix(agent): resolve relative media paths in MessageTool by @chengyongru in #3471
- fix(agent): subagent announces from threaded callers route to channel session, not the originating thread by @mt-huerta in #3465
- fix(provider): normalize DeepSeek non-string message content by @boogieLing in #3458
- 修复:自动清理未支持或已过期的 MSTeams 会话引用,避免通知发送失败 Fixes: #3433 by @zhuzhh in #3440
- feat(session): enforce replay/file-cap invariants for history lifecycle by @boogieLing in #3459
- fix(discord): full thread support with session isolation and allowlist enforcement by @Lbin91 in #3397
- fix(provider): bound OpenAI-compatible request timeouts by @boogieLing in #3478
- fix(heartbeat): prevent internal reasoning leaks and finalization fallback in delivery by @hussein1362 in #3389
- feat(command): add /history command to review recent session messages by @LeoFYH in #3466
- fix(codex): stream progress deltas to channels by @boogieLing in #3480
- feat(config): wire max_messages into session history replay by @hussein1362 in #3482
- feat(providers): add Hugging Face inference provider by @chengyongru in #3496
- The agent loop should be stopped when workspace directory restrictions are violated by @lvqiushi in #3493
- fix(channels): send telegram attachments with named file path by @Seym0n in #3489
- feat(web-tools): Improve to allow bypassing Cloudflare captchas by @Mizarka in #3382
- feat(providers): add extra_body config for OpenAI-compatible endpoints by @hussein1362 in #3491
- fix(feishu): Fix done emoji addition and on-it emoji removal before task actually ends by @BarclayII in #3502
- feat(web_search): add olostep provider by @chengyongru in #3505
- Fix reasoning_effort="none" handling and add gemma to Gemini routing by @masterlyj in #3515
- fix: sanitize Matrix user_id for Windows-safe store file names by @JiajunBernoulli in #3510
- feat(channels): support per-channel progress controls by @boogieLing in #3487
- fix(memory): ensure atomic write for history.jsonl by @yorkhellen in #3508
New Contributors
- @knightconnorp made their first contribution in #3370
- @tetratorus made their first contribution in #3387
- @saimonventura made their first contribution in #3383
- @gthieleb made their first contribution in #3398
- @pblocz made their first contribution in #3399
- @mvanhorn made their first contribution in #3423
- @choiking made their first contribution in #3441
- @mt-huerta made their first contribution in #3465
- @zhuzhh made their first contribution in #3440
- @Seym0n made their first contribution in #3489
- @Mizarka made their first contribution in #3382
- @BarclayII made their first contribution in #3502
Full Changelog: v0.1.5.post2...v0.1.5.post3
详细ChangeLogv0.1.5.post2
2026年04月22日
🐈 nanobot v0.1.5.post2 is here 🎉 — 67 PRs merged, 12 new contributors. The agent's world got bigger and steadier.
If v0.1.5.post1 was about the agent learning to manage itself, v0.1.5.post2 is about reach and polish. Windows and Python 3.14 joined the supported matrix. The read_file tool learned to understand DOCX, XLSX, and PPTX. Microsoft Teams arrived as a channel. The OpenAI-compatible API started streaming via SSE. And beneath all of that, ~50 smaller fixes across cron, memory, retry, session files, and provider quirks kept turning "it works" into "it's solid." A dedicated browser UI also started taking shape in the repo — source preview for now.
Highlights
-
Windows + Python 3.14 — first-class support — A full CI matrix covering Windows runners and Python 3.14 landed, along with install markers and runtime fixes for the quirks those platforms expose. If you've been running nanobot on WSL because "Windows didn't quite work," you can stop. (#3194)
-
Office documents, natively readable — The
read_filetool now extracts text from DOCX, XLSX, and PPTX — tables and grouped shapes included, workbook handles closed safely. Combined with the earlier PDF support, the agent can open whatever format your colleague just emailed you without bouncing through a converter. (#3336, #3269, #3353) -
OpenAI-compatible API — SSE streaming —
/v1/chat/completionsnow emits SSE chunks whenstream=true, wiring up the existingon_stream/on_stream_endcallbacks. Any client built for the OpenAI API — LangChain, LlamaIndex, your own frontend — gets live deltas from nanobot instead of waiting for the whole response. The endpoint also stopped terminating streams with a success marker after a backend failure, so errors surface honestly. (#3222, #3262) -
Microsoft Teams, MiniMax thinking, LM Studio, MyTool — Microsoft Teams joined the channel roster. MiniMax got a dedicated Anthropic-style thinking endpoint plus a
reasoning_effort→reasoning_splitmapping fix. LM Studio is now supported via nullable API keys for local servers that don't expect one. The new MyTool lets the agent introspect its own runtime configuration — and hides sensitive nested config fields incheckoutput so self-inspection doesn't leak secrets. (#3197, #3160, #3363, #3186, #3177, #3261) -
Reliability — the unglamorous half of a release — Session files now use atomic writes with corrupt-file repair, so a bad shutdown no longer eats your history. Memory cursor recovery handles non-integer corruption. Auto-compact skips sessions with active tasks and unifies summary injection across consolidation paths. Providers gain a circuit breaker for Responses API fallback and recognize ZhiPu 1302 rate limits. Cron stops leaking intermediate progress, its tool schema works with OpenAI Codex/Responses, and retry heartbeats no longer spill into user channels. Subagent follow-ups persist in session history. Half of these you'll never notice — which is exactly the point. (#3312, #3340, #3081, #3304, #3302, #3356, #3320, #3295, #3229, #3242)
-
Channels — quieter and sharper — Telegram gained mid-stream splitting for long replies and better markdown rendering for modern LLM output. Discord stopped treating bot-to-bot messages as self-loops and added channel-based allow-lists. Email deduplicates SPF/DKIM-rejected messages to stop log spam and ignores self-sent mailbox messages. WeCom parses mixed inbound messages correctly. Each individually small; together they mean fewer "why did my bot do that" moments. (#3329, #3355, #3280, #3171, #3325, #3228, #3161)
-
WebUI — early preview, source only — A dedicated
webui/has landed in the repo with a WebSocket chat flow, i18n locale switcher, Apple-inspired typography with CJK support, and live dark-mode code-block theming. The underlying WebSocket channel also learned to multiplex multiplechat_ids over a single connection. Heads up: this is source-preview only — the WebUI is intentionally not bundled into the published wheel yet. If you want to try it, clone the repo and run it fromwebui/. A packaged release will follow once the UX settles. (#3310, #3272, #3314, #3306)
Community
v0.1.5.post2 is what a release looks like when the foundation is done and people start finishing things. A Windows CI matrix from @JiajunBernoulli. Native Office document extraction from @aiguozhi123456. Session atomic writes from the same author, catching a real data-loss edge case. A Telegram mid-stream split that makes long replies actually readable. Twelve new contributors, and a lot of returning ones quietly landing the things that were on everyone's wish list. The agent runs on Windows. It reads your documents. It keeps its history even when the power blinks. And there's a UI taking shape in webui/ for whoever wants to peek. That's a post release doing post-release work — and then some.
What's Changed
- fix(agent): skip auto-compact for sessions with active agent tasks by @chengyongru in #3085
- fix(provider): recover trailing assistant as user to prevent Zhipu 1214 by @chengyongru in #3086
- fix(log): remove noisy no-op logs from auto-compact by @chengyongru in #3094
- fix(log): only log auto-compact when messages are actually archived by @chengyongru in #3099
- refactor(context): deduplicate system prompt by @chengyongru in #3162
- fix(channel.wecom): inbound mixed msg parse by @dzydzydzy7 in #3161
- fix(providers): guard chat_with_retry against explicit None max_tokens (#3102) by @04cb in #3157
- fix(cron): respect deliver flag when agent produces output by @chengyongru in #3168
- feat(provider): add MiniMax Anthropic endpoint for thinking mode 添加minimax的思考模式 by @Aisht669 in #3160
- fix(discord): remove duplicate channel_id assignment in message handler by @LeoFYH in #3178
- Add support for nullable API keys and LM Studio by @sohamb117 in #3186
- fix(memory): handle missing cursor key in history entries by @JiajunBernoulli in #3195
- feat(msteams): add Microsoft Teams channel by @chengyongru in #3197
- fix(skills): use yaml.safe_load for frontmatter parsing to handle multiline descriptions by @yanghan-cyber in #3141
- fix(status): correct context percentage and sync consolidator by @chengyongru in #3209
- fix(api): prevent upload filename collisions and reject unsupported image URLs by @mohamed-elkholy95 in #3187
- perf(tools): cache ToolRegistry.get_definitions() between mutations by @chengyongru in #3210
- feat(agent): add MyTool for runtime self-inspection by @chengyongru in #3177
- feat(api): afeat(api): add SSE streaming for /v1/chat/completions by @wanghesong2019 in #3222
- feat: add channel-based filtering for Discord by @Lbin91 in #3171
- feat(dream): git-based section age annotations for memory staleness by @chengyongru in #3212
- fix: pass apiBase from config to transcription providers (Groq & OpenAI) by @chengyongru in #3237
- feat(windows): Windows + Python 3.14 support — CI matrix, install markers, runtime fixes by @JiajunBernoulli in #3194
- fix(agent): preserve user message to prevent GLM error 1214 by @chengyongru in #3233
- fix(email): ignore self-sent mailbox messages by @yorkhellen in #3228
- fix(exec): pass allowed_env_keys to exec tool calls in subagents by @mcampo in #3238
- fix(docs): update channel plugin build backend to hatchling by @JiajunBernoulli in #3192
- fix(memory): fall back to raw_archive on LLM error response by @chengyongru in #3248
- fix: guard tool execution against non-compliant API gateway injection #3220 by @subalkum in #3225
- fix: make cron tool schema require message for add action by @sicnuyudidi in #3163
- fix(api): avoid success-style SSE termination after backend failure by @shaun0927 in #3262
- fix(my-tool): hide sensitive nested config fields in check output by @shaun0927 in #3261
- fix(utils): extract PPTX table cells and grouped shape text (#3250) by @04cb in #3269
- fix(loop): persist subagent follow-up events in session history by @xzq-xu in #3242
- fix(agent): stop leaking provider retry heartbeats to user channels by @SamZhu19921116 in #3229
- feat(websocket): multiplex multiple chat_ids over a single connection by @Re-bin in #3272
- refactor(templates): separate identity and SOUL responsibilities by @chengyongru in #3275
- feat(wizard): add Channel Common, API Server menus and constraint validation by @chengyongru in #3273
- feat: add issue templates by @chengyongru in #3287
- fix: prevent GitStore from creating nested repos and overwriting .gitignore by @longle325 in #3289
- fix: harden cron tool contract by @yeyitech in #3125
- fix(config): return provider default api base in config resolution by @morandot in #3112
- fix(cli): respect sys.stdout.isatty() in stream renderer (#3265) by @pixan-ai in #3271
- docs: refactor README into a docs-first landing page by @Re-bin in #3306
- fix: unify summary injection strategy between token consolidation and auto-compact by @JiajunBernoulli in #3304
- fix(providers): add circuit breaker for Responses API fallback by @chengyongru in #3302
- feat(webui): add initial browser UI with websocket chat and i18n by @Re-bin in #3310
- fix(cron): drop top-level oneOf so OpenAI Codex/Responses accept tool schema by @coldxiangyu163 in #3295
- fix(discord): allow bot-to-bot messaging, only drop self-loops (#3217) by @pixan-ai in #3280
- fix(session): prevent data loss with atomic writes and corrupt-file repair by @aiguozhi123456 in #3312
- style(webui): improve typography and code block rendering by @chengyongru in #3314
- fix: suppress intermediate progress output in cron jobs by @chengyongru in #3320
- fix(agent): align subagent result session key with main agent for mid-turn injection by @chengyongru in #3321
- fix(email): deduplicate SPF/DKIM-rejected emails to stop log spam by @chengyongru in #3325
- feat(telegram): mid-stream split in send_delta by @chengyongru in #3329
- fix(utils): strip malformed think tags and harmony channel markers by @hlgone in #3327
- fix(loop): preserve partial context when /stop cancels a task by @hussein1362 in #3299
- fix(anthropic): strip trailing assistant messages to prevent prefill error by @hussein1362 in #3297
- fix(mcp): retry once on transient connection errors by @hussein1362 in #3338
- agent: use ContextVar for tool routing context by @chengyongru in #3345
- fix(memory): harden cursor recovery against non-integer corruption by @MuataSr in #3340
- fix(retry): recognize ZhiPu 1302 rate-limit error for retry by @chengyongru in #3356
- fix(telegram): improve markdown rendering for modern LLM output by @hussein1362 in #3355
- fix(commands): intercept non-priority commands during active turn by @chengyongru in #3359
- fix(utils/document): use try/finally in _extract_xlsx to ensure workbook is always closed by @XJPeng12 in #3353
- feat(read_file): add DOCX, XLSX, PPTX office document support by @aiguozhi123456 in #3336
- Fix/minimax reasoning split by @lahuman in #3363
New Contributors
- @dzydzydzy7 made their first contribution in #3161
- @Aisht669 made their first contribution in #3160
- @sohamb117 made their first contribution in #3186
- @Lbin91 made their first contribution in #3171
- @mcampo made their first contribution in #3238
- @sicnuyudidi made their first contribution in #3163
- @SamZhu19921116 made their first contribution in #3229
- @longle325 made their first contribution in #3289
- @hlgone made their first contribution in #3327
- @hussein1362 made their first contribution in #3299
- @MuataSr made their first contribution in #3340
- @lahuman made their first contribution in #3363
Full Changelog: v0.1.5.post1...v0.1.5.post2
详细ChangeLogv0.1.5.post1
2026年04月15日
🐈 nanobot v0.1.5.post1 is here 🎉 — 80 PRs merged, 25 new contributors. The agent learned to manage itself.
If v0.1.5 was about making the building livable, v0.1.5.post1 is about the building learning to take care of itself. The agent now compresses its own context before it gets too long, injects follow-up messages mid-turn instead of making you wait, discovers reusable skills from its own workflows, and opens a WebSocket so anything can talk to it. Meanwhile, 40+ bug fixes across cron, memory, retry, and channels turned "it works most of the time" into "it works."
Highlights
-
Mid-turn injection — follow-ups don't wait in line — If you send another message while the agent is still working, it no longer queues behind a lock. The follow-up gets injected into the active turn, and on streaming channels the reply continues in the same live response. This makes long tool-call chains feel interactive instead of one-way. Edge-case draining on error paths was hardened in a follow-up pass. (#3042, #3110)
-
Dream learns skills, not just facts — Dream's consolidation flow can now recognize repeated workflows and promote them into standalone workspace skills under
skills/. Combined withdisabledSkillsconfig for excluding skills you don't want, the agent's skill surface is now something that grows organically and stays manageable. (#3048, #2959) -
Auto compact — the agent manages its own context — Sessions no longer grow until they hit the wall. Auto compact watches for idle periods, then proactively summarizes older context while preserving recent live messages — so when you come back, the agent remembers what matters without dragging along everything that doesn't. This isn't the old "nuke the session" approach; it's surgical compression that keeps the conversation feeling continuous. Pair it with
idleCompactAfterMinutesin config for fine-grained control. (#3007, #3081, #3093) -
WebSocket channel — connect anything — A new
websocketchannel runs a WebSocket server with streaming (delta+stream_endevents), token-based auth (static or issued), per-connection sessions, and TLS support. Web apps, CLIs, Chrome extensions, scripts — anything that can open a socket can now talk to the agent in real time. (#2964) -
Channels got deeper — Telegram gained location sharing. Discord got streaming replies and proxy support. Feishu added done-emoji lifecycle, inline tool hints, and Lark global domain config. QQ and WeCom received full media support. Slack's
messagetool now resolves#channel_nameand@userto real IDs. The API endpoint accepts file uploads via JSON base64 and multipart, with automatic document extraction (PDF, DOCX, XLSX, PPTX) across all channels. And retry amplification — where a failed send would trigger cascading retries — was fixed across every channel. (#2910, #2939, #2960, #2993, #3046, #3044, #3138, #2938, #3053) -
Providers — adaptive thinking and Kimi — Anthropic's
adaptivereasoning mode landed, letting Claude decide when and how much to think. Kimi thinking-capable models (kimi-k2.5,k2.6-code-preview) now get automaticextra_body.thinkinginjection viareasoningEffort. StepFun Plan API reasoning fields fall back correctly. Non-Claude providers get proper role alternation enforcement. And tool-call arguments are normalized for strict providers that reject malformed JSON. (#2882, #3124, #2903, #2637, #3154) -
MCP, tools, and search — MCP resources and prompts are now exposed as read-only tools — the agent can query them directly. Multiple MCP servers connect in isolated tasks instead of racing each other. The notebook editing tool arrived. Kagi joined the web search provider lineup. And the exec tool got tighter: Windows support landed,
allowed_env_keyslets you selectively forward env vars, internal state files are write-protected, andworking_diroutside the workspace is rejected. (#2907, #3019, #3017, #2945, #2893, #2962, #3061) -
Cron stopped dropping jobs — Four separate cron fixes addressed reentrant store reloads during job execution, fixed-interval tasks duplicating due to concurrent store replacement, job config not reloading, and manual run state not being preserved. If you rely on scheduled tasks, this release is the one where they become boring. (#3038, #3034, #2895, #2930)
Community
Welcome to our 25 new contributors who made their first contribution in this release: @Bahtya, @LeoFYH, @xwind, @Xerxes-cn, @BalorLC3, @invictus-z, @zijiefang, @kronk307, @stutiredboy, @SHLE1, @RohitDayanand, @justforyoudear, @XJPeng12, @linziyanleo, @chenyahui, @JonasGao, @weitongtong, @danielphang, @mterhar, @ramonpaolo, @nikube, @yeyitech, @ravs-cyberrock, @samyzhh, and @razzh7.
v0.1.5.post1 reflects something we keep seeing in the commit log: the best contributions aren't always the flashiest ones. A cron race condition caught by @weitongtong. A retry amplification loop spotted by @Bahtya. A channel error path that silently swallowed messages, fixed by @yanghan-cyber. These are the changes that make an agent trustworthy — not because it can do more, but because it stops doing things wrong. 80 PRs later, nanobot is quieter, steadier, and a little more grown-up. That's worth celebrating.
Full Changelog: v0.1.5...v0.1.5.post1
What's Changed
- fix(matrix): correct e2eeEnabled camelCase alias mapping by @Bahtya in #2877
- fix(filesystem): correct write success message from bytes to characters by @LeoFYH in #2865
- fix: Matrix e2eeEnabled config alias and cron job name parameter (#2851, #2680) by @04cb in #2855
- ci: add ruff lint check for unused imports and variables by @JiajunBernoulli in #2847
- fix(docker): Windows CRLF breaks entrypoint.sh by @flobo3 in #2883
- fix(cli): sanitize surrogate characters in prompt history by @Bahtya in #2869
- fix(feishu): resolve mentions data and ensure access token initializationDev by @xwind in #2885
- fix(runner): silent retry on empty response before finalization by @Re-bin in #2889
- feat(agent): tool hint enhancement by @chengyongru in #2884
- feat(memory):dream enhancement (#2887) by @chengyongru in #2891
- fix(cron): fix not reload job config by @Xerxes-cn in #2895
- feat(anthropic): add adaptive thinking mode by @BalorLC3 in #2882
- docs: fix channel plugin guide — require Pydantic config model by @invictus-z in #2850
- fix(memory): prevent potential loss of compressed session history by @LingaoM in #2890
- fix(memory): add timestamp and cap to recent history injection by @Re-bin in #2906
- feat(mcp): expose MCP resources and prompts as read-only tools by @Re-bin in #2907
- chore: update .gitignore to include additional project-specific, build, test, and environment files by @JackLuguibin in #2862
- fix(provider): fallback to reasoning field for StepFun Plan API by @zijiefang in #2903
- fix(exec): add Windows support for shell command execution by @Re-bin in #2893
- feat(agent): prompt behavior directives, tool descriptions, and loop robustness by @Re-bin in #2912
- feat(telegram): add location/geo support by @kronk307 in #2910
- feat: telegram support stream edit interval by @stutiredboy in #2919
- fix(tool-hint): fold paths in exec commands and deduplicate by formatted string by @chengyongru in #2926
- fix(cron): Concurrency issues by @Xerxes-cn in #2930
- refactor(hook): add reraise flag to AgentHook and remove _LoopHookChain by @LingaoM in #2918
- Fix version mismatch: use importlib.metadata as single source of truth by @Bahtya in #2860
- fix(discord): enable streaming replies to avoid empty final response by @SHLE1 in #2939
- fix(status): use consistent divisor for token count display by @LeoFYH in #2951
- fix(dingtalk): #2696 by @RohitDayanand in #2948
- fix(exec): forward complete Windows env to subprocesses by @justforyoudear in #2941
- feat: unified session across channels via config toggle (closes #2798) by @wanghesong2019 in #2900
- fix(helpers): ensure assistant message content is never None by @pixan-ai in #2748
- fix(cli): remove default green style from Enabled column in tables by @XJPeng12 in #2936
- fix(providers): enforce role alternation for non-Claude providers by @linziyanleo in #2637
- feat(channels): add WebSocket server channel by @chengyongru in #2964
- fix(agent): deliver LLM errors to streaming channels and avoid polluting session context by @yanghan-cyber in #2963
- feat(exec): support allowed_env_keys to pass specified env vars to su… by @chenyahui in #2962
- feat(channel): add proxy support for Discord channel by @JonasGao in #2960
- fix: strip blocks from Gemma 4 and similar models by @chengyongru in #2991
- feat(feishu): streaming resuming, inline tool hints, and done emoji by @chengyongru in #2993
- fix(memory): harden consolidation with try/except on token estimation and chunk size cap by @franciscomaestre in #2978
- fix(agent): Avoid truncate_text name shadowing by @yorkhellen in #2997
- feat(cron): 添加 CronService.update_job 方法 by @weitongtong in #3005
- fix(utils): anchor unclosed think-tag regex to string start (#3004) by @04cb in #3020
- feat(agent): auto compact — proactive session compression by @chengyongru in #3007
- fix(cron): 修复固定间隔任务因 store 并发替换导致的重复执行 by @weitongtong in #3034
- fix(cron): guard _load_store against reentrant reload during job execution by @danielphang in #3038
- feat: Add Kagi search by @mterhar in #2945
- fix(mcp): support multiple MCP servers by connecting each in isolated… by @Qinnnnnn in #3019
- feat(tool): improve file editing and add notebook tool by @Re-bin in #3017
- fix(feishu): improve voice message download with detailed logging by @chengyongru in #3041
- feat(agent): mid-turn message injection for responsive follow-ups by @chengyongru in #3042
- feat(channels): Add full media support for QQ and WeCom channels by @chengyongru in #3044
- fix(agent): preserve tool results on fatal error to prevent orphan tool_calls (#2943) by @04cb in #3045
- feat(channels/feishu): add domain config for Lark global support by @chengyongru in #3046
- feat(skills): add disabled_skills config to exclude skills from loading by @chenyahui in #2959
- fix(shell): tighten exec safety guards (#2989, #2826) by @04cb in #3061
- feat(agent): integrate skill discovery into Dream by @chengyongru in #3048
- fix(retry): strip images in-place to prevent repeated error-retry cycles by @yanghan-cyber in #3060
- fix(channels): prevent retry amplification and silent message loss across channels by @Bahtya in #3053
- fix(provider): clarify local 502 recovery hints by @haosenwang1018 in #3075
- fix(mcp): hint on stdio protocol pollution by @haosenwang1018 in #3079
- fix: improve tool call parameter validation and error messages by @ramonpaolo in #2859
- fix(agent): persist user message before running turn loop by @nikube in #3076
- fix(agent): skip auto-compact for sessions with active agent tasks by @chengyongru in #3081
- fix(provider): recover trailing assistant as user to prevent Zhipu 1214 by @chengyongru in #3082
- docs(provider): clarify responses api routing by @haosenwang1018 in #3089
- fix(log): remove noisy no-op logs from auto-compact by @chengyongru in #3093
- fix(agent): drain injection queue on error/edge-case exit paths by @chengyongru in #3110
- fix(web): serialize duckduckgo search calls by @yeyitech in #3128
- test(loop): cover /stop checkpoint recovery by @yeyitech in #3130
- feat: add HTTP health endpoint on gateway port by @ravs-cyberrock in #2625
- fix(feishu): remove resuming and add streaming card fallback by @chengyongru in #3133
- feat(slack): resolve named message targets by @yeyitech in #3138
- feat(api): support file uploads via JSON base64 and multipart/form-data by @dividduang in #2938
- fix: handle dict config in is_allowed() and _validate_allow_from() by @samyzhh in #3153
- fix: normalize tool-call arguments for strict providers by @Michael-lhh in #3154
- feat: show active task count in /status output by @aiguozhi123456 in #3149
- fix: add retry termination notification to interaction channel by @aiguozhi123456 in #3150
- feat(provider): enable Kimi thinking via extra_body for k2.5 and k2.6 by @razzh7 in #3124
New Contributors
- @Bahtya made their first contribution in #2877
- @LeoFYH made their first contribution in #2865
- @xwind made their first contribution in #2885
- @Xerxes-cn made their first contribution in #2895
- @BalorLC3 made their first contribution in #2882
- @invictus-z made their first contribution in #2850
- @zijiefang made their first contribution in #2903
- @kronk307 made their first contribution in #2910
- @stutiredboy made their first contribution in #2919
- @SHLE1 made their first contribution in #2939
- @RohitDayanand made their first contribution in #2948
- @justforyoudear made their first contribution in #2941
- @XJPeng12 made their first contribution in #2936
- @linziyanleo made their first contribution in #2637
- @chenyahui made their first contribution in #2962
- @JonasGao made their first contribution in #2960
- @weitongtong made their first contribution in #3005
- @danielphang made their first contribution in #3038
- @mterhar made their first contribution in #2945
- @ramonpaolo made their first contribution in #2859
- @nikube made their first contribution in #3076
- @yeyitech made their first contribution in #3128
- @ravs-cyberrock made their first contribution in #2625
- @samyzhh made their first contribution in #3153
- @razzh7 made their first contribution in #3124
Full Changelog: v0.1.5...v0.1.5.post1
详细ChangeLogv0.1.5
2026年04月06日
🐈 nanobot v0.1.5 is here 🎉 — 66 PRs merged, 27 new contributors, and the first release with its own home.
We're excited to announce that nanobot now has an official website at nanobot.wiki, with multilingual documentation in English, Chinese, Japanese, Korean, Spanish, and French. Building it reminded us why we do this: nanobot has always belonged to the open-source community, and a proper home — one that speaks your language — felt overdue. Every doc page, every translation, every example is open and contribution-ready. That's not going to change.
Now, about the release itself. If v0.1.4.post6 was about decomposing the foundation, v0.1.5 is about making the building livable. The agent can now run for hours without losing its mind. Memory got a proper architecture. And running nanobot in production went from "possible" to "comfortable." This is the release where nanobot stops being a prototype and starts being infrastructure.
Highlights
-
Long-running tasks got more reliable — Long-running tasks received a ground-up reliability pass. The runtime now handles
CancelledErrorwithout orphaning subprocesses, retry classification uses structured error metadata instead of regex-on-error-text (so a 429 quota exhaustion stops immediately while a rate limit waits and retries), SDK-level auto-retries were disabled to prevent request amplification, and Azure retries no longer double-dip. If your agent runs cron jobs, orchestrates tools overnight, or handles bursty traffic — this is the release that makes those sessions stick. (#2733, #2762, #2759, #2761, #2765) -
Memory got an architecture — meet Dream — The new two-stage memory system separates live conversation history from consolidated long-term knowledge. Dream runs as a background consolidation pass — think of it as the agent sleeping on what it learned — backed by git-versioned storage so every memory state is recoverable. Legacy
HISTORY.mdfiles migrate automatically. Jinja2 templating arrived alongside Dream, giving you control over how the agent shapes its responses and memory summaries. This isn't a feature bolted on — it's the memory system nanobot should have had from day one. (#2717, #2779, and 10+ follow-up hardening commits) -
Running nanobot in production got real —
execcalls are now sandboxed viabwrapand containers run as non-root by default. The exec tool no longer leaks host environment variables to the LLM. API port binds to localhost by default. Config secrets support${VAR}interpolation so you never have to hardcode a key again. A newnanobot-apiDocker service gives you an isolated OpenAI-compatible endpoint out of the box. WhatsApp bridge gained automatic local auth. These aren't glamorous changes — they're the reason you'll sleep through the night after deploying. (#1940, #2831, #2830, #2841, #2715) -
Three new providers, and GPT-5 is ready — GPT-5 model family support landed with proper temperature handling. Xiaomi MiMo joined for on-device inference fans. Baidu Qianfan arrived for the Chinese ecosystem. Dashscope and ModelArk got proper thinking parameter control. And
reasoning_content(chain-of-thought from DeepSeek-R1, Kimi, MiMo) is now visible and preserved through the full message pipeline. nanobot keeps meeting users wherever their models are. (#2788, #2495, #2811, #2840, #2770) -
Channels kept getting better — Email now extracts attachments with MIME filtering and filename sanitization. WhatsApp gained voice transcription via Groq/OpenAI Whisper. Feishu auto-removes reactions after processing and supports video downloads. Telegram renders tool hints as collapsible blockquotes, supports DM threads, and splits oversized streamed replies. WeChat multimodal alignment continued. Langfuse integration landed for production observability. And
/statusnow shows web search provider usage alongside cache hit rates. (#2815, #2530, #2812, #2810, #2793, #2520, #2659, #2832, #2703) -
Developer experience, quietly — Built-in
grepandglobtools give the agent native code search. The Tool class was refactored with proper JSON Schema for parameters. The Python SDK facade enables programmatic per-session isolation. The CLI gained--configfor multi-instance setups. Web search was unified underWebToolsConfigwith toggle controls. And the test suite grew to 1,142 tests, all green. (#2754, #2780, #2653, #2740, #2643)
Community
Welcome to our 27 new contributors who made their first contribution in this release.
v0.1.5 is shaped by a simple conviction: an AI agent framework earns trust not by adding features, but by being the kind of software you'd run unattended on a Friday night. Memory that doesn't forget. Retries that don't amplify. Sandboxes that don't leak. Every contributor who hardened a boundary, caught a race condition, or added a test — you made nanobot more trustworthy today than it was yesterday. That's the only metric that matters.
Full Changelog: v0.1.4.post6...v0.1.5
What's Changed
- fix(skill-creator): Fix grammar in SKILL.md: 'another the agent' by @quanmou in #2586
- feat: add OpenAI-compatible API by @goxofy in #1362
- feat(agent): add CompositeHook for composable lifecycle hooks by @sontianye in #2615
- feat: add Python SDK facade and per-session isolation by @Re-bin in #2653
- fix: three minor user-facing fixes (#2651, #2566, #2579) by @04cb in #2656
- fix: Prevent ExecTool registration in Subagent when exec_config.enable is False by @yorkhellen in #2648
- feat(channel): matrix/discord enhancement by @chengyongru in #2673
- Feat(WeiXin): WeXin multimodal capabilities and align with version 2.1.1 by @xcosmosbox in #2614
- fix(test): fix flaky test_fixed_session_requests_are_serialized by @chengyongru in #2676
- fix: restore GitHub Copilot auth flow by @RongLei-intel in #2668
- fix(agent): message tool incorrectly replies to original chat when targeting different chat_id by @WormW in #2474
- fix: ExecTool to block root directory paths when restrict_to_workspace is enabled by @yorkhellen in #2683
- fix(providers): only apply cache_control for Claude models on OpenRouter by @Tejas1Koli in #2687
- feat(provider): show cache hit rate in /status (#2645) by @chengyongru in #2703
- feat(cron): add deliver parameter to support silent jobs by @xgzlucario in #2718
- chore(provider): Use OpenAI Responses API for Azure OpenAI Provider by @kunalk16 in #2661
- test(matrix): skip cleanly when optional deps are missing by @haosenwang1018 in #2741
- feat(cli): add --config option to channels login and status commands by @masterlyj in #2740
- feat: harden agent runtime for long-running tasks by @Re-bin in #2733
- feat(channel): channel enhancement by @chengyongru in #2769
- fix: restore Weixin typing indicator by @cypggs in #2646
- feat(provider): add Xiaomi MiMo LLM support by @LingaoM in #2495
- feat(provider): support reasoning_content in OpenAI compat provider by @LingaoM in #2770
- fix(restart): send completion notice after channel is ready and unify… by @imfondof in #2745
- feat: unify web tool config under WebToolsConfig + add web tool toggle controls by @Shiniese in #2643
- fix: Support media directory access when
restrict_to_workspaceis enabled by @Shiniese in #2743 - fix: Retry-After was ignored, causing premature retries (now honors header/json hints) by @pikaxinge in #2761
- fix: stop retry amplification (12→4 requests) by disabling SDK auto-retries by @pikaxinge in #2759
- feat(memory): two-stage memory system with Dream consolidation by @chengyongru in #2717
- feat: integrate Jinja2 templating for agent responses and memory cons… by @JackLuguibin in #2779
- fix(security): add ssrfWhitelist config to unblock Tailscale/CGNAT (#2669) by @04cb in #2715
- refactor: streamline Tool class methods and improve type handling by @JackLuguibin in #2780
- fix(provider): restore reasoning_content and extra_content in message… by @LingaoM in #2786
- feat(providers): add GPT-5 model family support by @friday-james in #2788
- perf(cache): stabilize tool prefix caching under MCP tool churn by @pikaxinge in #2722
- fix(docker): rewrite github ssh git deps to https for npm build by @Wenzhang-Chen in #1700
- feat(agent): add built-in grep and glob search tools by @Re-bin in #2754
- fix(cli): prevent spinner ANSI escape codes from being printed verbatim by @chengyongru in #2809
- feat(telegram): render tool hints as expandable blockquotes by @chengyongru in #2810
- feat(provider): add Qianfan provider support by @chengyongru in #2811
- feat(feishu): auto-remove reaction after processing and support video download by @chengyongru in #2812
- fix: stop leaking reasoning_content to stream output by @chengyongru in #2817
- fix(dream): allow LLM to retry on tool errors by @chengyongru in #2824
- fix(web-search): fix Jina search request format and restore DuckDuckGo fallback by @KimGLee in #2808
- Fix: add asyncio timeout guard for DuckDuckGo search by @hoaresky in #2805
- fix(telegram): support threads in DMs by @IlyaSemenov in #2793
- refactor(agent): streamline hook method calls and enhance error logging by @JackLuguibin in #2794
- feat: sandbox exec calls with bwrap and run container as non-root (minimally fixes #1873) by @kinchahoy in #1940
- chore: add codespell support (config, workflow to detect/not fix) and make it fix a few typos by @yarikoptic in #121
- security: prevent exec tool from leaking process env vars by @benlenarts in #2831
- docs: another two places for renaming assitant to agent by @qixinbo in #2835
- expand /status to show web search provider usage limits (#2820) by @wanghesong2019 in #2832
- security: support ${VAR} env var interpolation for config secrets by @benlenarts in #2830
- fix(shell): kill subprocess on CancelledError to prevent orphan proce… by @LingaoM in #2765
- fix(feishu): match bot's own open_id in _is_bot_mentioned to prevent … by @yq612 in #2719
- feat(provider): 添加 Langfuse 观测平台的集成支持 by @lang07123 in #2659
- fix(matrix): fix e2ee authentication by @limdingwen in #2596
- feat(whatsapp): add voice message transcription via OpenAI/Groq Whisper by @franciscomaestre in #2530
- fix(whatsapp): detect phone vs LID by JID suffix, not field name by @franciscomaestre in #2531
- Fix cron reminder notifications being suppressed by @mrbob-git in #2449
- fix(telegram): split oversized final streamed replies by @Michael-lhh in #2520
- feat(email): add attachment extraction support by @benlenarts in #2815
- feat(agent): Adjust thinking method for Dashscope and Modelark by @power88 in #2840
- feat(docker): add nanobot-api service with isolated workspace by @dividduang in #2841
- fix: make app-layer retry classification structured (408/409/timeout/connection) by @pikaxinge in #2762
- fix(status): use correct AgentLoop attribute for web search config by @yanghan-cyber in #2844
New Contributors
- @quanmou made their first contribution in #2586
- @goxofy made their first contribution in #1362
- @sontianye made their first contribution in #2615
- @RongLei-intel made their first contribution in #2668
- @WormW made their first contribution in #2474
- @Tejas1Koli made their first contribution in #2687
- @masterlyj made their first contribution in #2740
- @cypggs made their first contribution in #2646
- @LingaoM made their first contribution in #2495
- @imfondof made their first contribution in #2745
- @Shiniese made their first contribution in #2643
- @friday-james made their first contribution in #2788
- @Wenzhang-Chen made their first contribution in #1700
- @hoaresky made their first contribution in #2805
- @IlyaSemenov made their first contribution in #2793
- @kinchahoy made their first contribution in #1940
- @yarikoptic made their first contribution in #121
- @qixinbo made their first contribution in #2835
- @wanghesong2019 made their first contribution in #2832
- @yq612 made their first contribution in #2719
- @lang07123 made their first contribution in #2659
- @limdingwen made their first contribution in #2596
- @franciscomaestre made their first contribution in #2530
- @mrbob-git made their first contribution in #2449
- @power88 made their first contribution in #2840
- @dividduang made their first contribution in #2841
- @yanghan-cyber made their first contribution in #2844
Full Changelog: v0.1.4.post6...v0.1.5
详细ChangeLogv0.1.4.post6
2026年03月27日
🐈 nanobot v0.1.4.post6 is here — 57 PRs merged, 27 new contributors, and a release that's less about adding surface area than about rethinking what's underneath.
Some releases are about what you can do. This one is about how cleanly you can do it. The agent runtime got formally decomposed, a major dependency was removed, streaming went end-to-end, and a security vulnerability was closed. Beneath the feature work, v0.1.4.post6 is a structural turning point — the kind of release that makes the next release possible.
Highlights
-
The agent runtime was decomposed into composable pieces — A shared
AgentRunnerwas extracted, lifecycle hooks were unified into a formalHookContext, and subagent progress is now preserved even on failure. Command routing was refactored into a plugin-friendly structure, andprocess_directwas unified to returnOutboundMessageconsistently. This isn't just cleanup — it's the foundation for pluggable agent behaviors, custom execution strategies, and third-party lifecycle integrations that are coming next. (#2524, #2541, #2388, #2338) -
litellm was replaced with native OpenAI + Anthropic SDKs — The entire provider layer was rewritten to talk directly to upstream SDKs instead of routing through litellm. Prompt cache optimization for Anthropic, proper
max_completion_tokenshandling for OpenAI o1, and Gemini thought signature preservation all came along for the ride. If you've ever debugged a litellm traceback at 2am, you understand why this matters. (#2448, #1109, #2468, #2550, #2453) -
Streaming went end-to-end — From provider to channel to CLI, streaming output now flows as a first-class path. Feishu gained CardKit streaming support, queued stream deltas are coalesced to reduce API calls, and the channel manager handles stream boundaries correctly. This is the difference between "the bot is typing..." and actually watching it think. (#2365, #2545, #2497)
-
A security vulnerability was patched — Email injection and spoofing via missing authentication verification has been fixed. Inbound emails now verify SPF/DKIM through
Authentication-Resultsheaders, withverify_dkimandverify_spfenabled by default. Email content is tagged with[EMAIL-CONTEXT]to prevent LLM prompt injection from email bodies. See the advisory for details. (GHSA-4gmr-2vc8-7qh3) -
WeChat support landed as a full channel — WeChat (Weixin) joined the channel family with HTTP long-poll, QR code login, and plugin 1.0.3 compatibility. Alongside it, Telegram, QQ, WhatsApp, and Feishu all received cross-channel enhancements including retry mechanisms with exponential backoff. (#2412, #2428, #2386, #2478)
-
Provider coverage kept expanding — Mistral and OVMS providers arrived, Step Fun (阶跃星辰) joined the ecosystem, and custom provider error reporting got much more honest — raw API errors instead of opaque
JSONDecodeError. nanobot continues to meet users wherever their models live. (#2199, #2472, #2289, #2139) -
The agent got smarter about resources — Per-session concurrent dispatch landed, native multimodal sensory capabilities were added, token estimation now counts all message fields, and memory consolidation properly reserves completion headroom. The agent loop also handles
CancelledErrorgracefully and records subagent results with correct roles. (#2393, #2304, #2344, #2378, #2239, #2104) -
Feishu and Telegram both leveled up — Feishu gained streaming cards, code block parsing in post messages, and fixes for markdown rendering and media types. Telegram got HTTP(S) URL media support, separated connection pools to prevent pool exhaustion, and quieter network error logging. Small individually, substantial together. (#2545, #2246, #1814, #1755, #1793, #2247, #2272)
-
CLI and onboarding became more capable — A full-featured onboard wizard arrived,
--direnables multiple instances,/statusshows runtime info,-hworks everywhere, and timezone is now configurable. The kind of polish that makes first-run experience feel intentional. (#2101, #1763, #1985, #2123, #2477, #1136, #2266) -
Infrastructure hardened across the board — Zombie processes are reaped on shell timeout, cron job stores are scoped to workspaces, MCP tool schemas handle nullable params correctly, Docker builds include openssh-client, and the test suite was reorganized into a cleaner structure. The kind of work that prevents the bug report you'd otherwise file next month. (#2362, #2204, #2230, #2287, #1911, #2427, #2367)
Community
A warm welcome to our 27 new contributors in this release.
v0.1.4.post6 is shaped by a belief that the most important work in open source isn't always the most visible. Replacing a core dependency, decomposing a runtime, closing a security hole — none of these make for flashy demos, but all of them make nanobot a project you can build on with more confidence tomorrow than yesterday. Thank you to everyone who contributed code, fixes, docs, and ideas. The foundation is getting stronger.
Full Changelog: v0.1.4.post5...v0.1.4.post6
What's Changed
- fix:Workspace path in onboard command ignores config setting by @danielyangfei in #1136
- feat: add --dir option to onboard command for Multiple Instances by @skiyo in #1763
- fix(providers): handle empty choices in custom provider response by @JiajunBernoulli in #2139
- feat(slack): update reaction emoji on task completion by @sihyeonn in #1852
- fix(feishu): fix markdown rendering issues in headings and tables by @xgzlucario in #1814
- fix(feishu): use correct msg_type for audio/video files by @weipengOO98 in #1755
- fix: preserve image paths in fallback and session history by @Re-bin in #2165
- docs(readme): fix broken link to Channel Plugin Guide by @angleyanalbedo in #2040
- fix:subagent result messages incorrectly recorded as user role by @yorkhellen in #2104
- fix(cron): show schedule details and run state in _list_jobs() output by @pjhoberman in #2107
- logo: transparent background by @vivganes in #1647
- fix: When using custom_provider, a prompt "LiteLLM:WARNING" will still appear during conversation by @JavisPeng in #2191
- feat(telegram): support HTTP(S) URLs for media in TelegramChannel by @h4nz4 in #1793
- feat: parse feishu code block content in post message by @mamamiyear in #2246
- fix: separate Telegram connection pools and add timeout retry to prevent pool exhaustion by @Re-bin in #2247
- Fix TypeError for MCP tools with nullable JSON Schema params by @rreben in #2230
- fix: nanobot onboard update config crash by @mamamiyear in #2266
- docs: add subagent workspace assignment hint to spawn tool description by @JilunSun7274 in #2248
- Full-featured onboard wizard![from nightly] by @chengyongru in #2101
- fix(custom_provider): show raw API error instead of JSONDecodeError by @asdf17128 in #2289
- fix(agent): handle asyncio.CancelledError in message loop by @cdkey85 in #2239
- feat(tools): enhance ExecTool with enable flag and custom deny_patterns by @angleyanalbedo in #1824
- feat(cron): add run history tracking for cron jobs by @xzq-xu in #1838
- Add support for -h in the CLI by @JamesWrigley in #2123
- fix: add openssh-client and use HTTPS for GitHub in Docker build by @KEEPSLAMDUNK in #1911
- Harden email IMAP polling retries by @jr551 in #2122
- docs: add github copilot oauth setup and exclude from generated config by @Harvey-Mackie in #2310
- feat(agent): implement native multimodal autonomous sensory capabilities by @vandazia in #2304
- fix: normalize MCP tool schema for OpenAI-compatible providers by @haosenwang1018 in #2287
- feat: add /status command to show runtime info by @robbyczgw-cla in #1985
- refactor(agent): unify process_direct to return OutboundMessage by @Re-bin in #2338
- fix(agent): count all message fields in token estimation by @Re-bin in #2344
- perf: optimize prompt cache hit rate for Anthropic models by @coldxiangyu163 in #1109
- feat: end-to-end streaming output for providers, channels, and CLI by @Re-bin in #2365
- feat(provider): add mistral/ovms provider by @chengyongru in #2199
- fix(memory): reserve completion headroom before token consolidation by @Re-bin in #2378
- Refactor command routing for a plugin-friendly structure by @Re-bin in #2388
- feat(agent): enable per-session concurrent dispatch by @Re-bin in #2393
- fix(shell): reap zombie processes when command timeout kills subprocess by @macroadster in #2362
- fix(heartbeat): retain bounded legal session suffix by @Re-bin in #2413
- feat(wechat): support wechat channel by @chengyongru in #2412
- fix(cron): scope cron job store to workspace directory by @MiguelPF in #2204
- feat: telegram/qq/whatsapp/feishu enhancement by @chengyongru in #2386
- proposal to adopt mypy some e.g. interfaces problems by @19emtuck in #2367
- refactor(tests): optimize unit test structure by @chengyongru in #2427
- refactor: replace litellm with native openai + anthropic SDKs by @Re-bin in #2448
- Fix/Feat(WeiXin): Adapt to WeChat plugin 1.0.3 by @xcosmosbox in #2428
- Unintended Discord behaviour with Threads by @Seeratul in #2452
- fix: preserve Gemini thought signatures in tool calls by @yoheinishikubo in #2453
- fix(providers): add max_completion_tokens for openai o1 compatibility (backport to main) by @flobo3 in #2468
- feat(config): add configurable timezone for runtime context by @Re-bin in #2477
- feat(channel): add message send retry mechanism with exponential backoff by @chengyongru in #2478
- feat(provider): add Step Fun (阶跃星辰) provider support by @ZouR-Ma in #2472
- refactor: extract shared agent runner and preserve subagent progress on failure by @Re-bin in #2524
- refactor: unify agent runner lifecycle hooks by @Re-bin in #2541
- fix(providers): make max_tokens and max_completion_tokens mutually exclusive (#2491) by @chengyongru in #2550
- fix(channel): coalesce queued stream deltas to reduce API calls by @chengyongru in #2497
- feat(feishu): support stream output (cardkit) (#2382) by @chengyongru in #2545
- fix(telegram): log network errors as warnings without stacktrace by @flobo3 in #2272
New Contributors
- @danielyangfei made their first contribution in #1136
- @skiyo made their first contribution in #1763
- @sihyeonn made their first contribution in #1852
- @xgzlucario made their first contribution in #1814
- @weipengOO98 made their first contribution in #1755
- @angleyanalbedo made their first contribution in #2040
- @pjhoberman made their first contribution in #2107
- @JavisPeng made their first contribution in #2191
- @h4nz4 made their first contribution in #1793
- @mamamiyear made their first contribution in #2246
- @rreben made their first contribution in #2230
- @JilunSun7274 made their first contribution in #2248
- @cdkey85 made their first contribution in #2239
- @JamesWrigley made their first contribution in #2123
- @KEEPSLAMDUNK made their first contribution in #1911
- @jr551 made their first contribution in #2122
- @Harvey-Mackie made their first contribution in #2310
- @vandazia made their first contribution in #2304
- @robbyczgw-cla made their first contribution in #1985
- @macroadster made their first contribution in #2362
- @MiguelPF made their first contribution in #2204
- @19emtuck made their first contribution in #2367
- @xcosmosbox made their first contribution in #2428
- @Seeratul made their first contribution in #2452
- @yoheinishikubo made their first contribution in #2453
- @ZouR-Ma made their first contribution in #2472
Full Changelog: v0.1.4.post5...v0.1.4.post6
详细ChangeLogv0.1.4.post5
2026年03月16日
🐈 nanobot v0.1.4.post5 is here — 57 PRs merged, 29 new contributors, and a release cycle shaped less by spectacle than by something quieter: careful refinement where it matters most.
This is the kind of release that makes a project feel more trustworthy in daily use. The edges got smoother, the failure modes got softer, and the platform got broader. Across channels, providers, memory, MCP, CLI, and infrastructure, nanobot is becoming not just more capable, but more dependable — more like a tool you can actually live with.
Highlights
-
Reliability took center stage — A lot of this release is about making nanobot fail more gracefully. Agent loops are less likely to crash, MCP connections now handle cancellation better, orphaned tool results are preserved correctly, and async CLI/subagent output behaves more cleanly. (#1999, #1953, #2075, #1930, #2039)
-
Memory became more practical — Async background consolidation landed, consolidation inputs are passed through more faithfully, payloads are validated before persistence, and
save_memoryis enforced more consistently. This is a meaningful step toward memory that feels less magical and more reliable. (#1961, #1962, #1868, #1810, #1909) -
The channel layer keeps maturing — Channel plugin architecture arrived, channel discovery is now automatic, and built-in channel/config boundaries are cleaner. That kind of structural work matters: it makes growth easier without making the system brittle. (#1982, #1888)
-
Provider support keeps expanding outward — Ollama support landed for local models, VolcEngine and BytePlus joined the ecosystem,
openrouter/*models are supported, and web search providers are now configurable with fallback behavior. nanobot is increasingly meeting users where they already are. (#1863, #1608, #2026, #398) -
Observability and tooling got stronger — Langsmith integration brings better conversation tracking, built-in skill packaging got fixed up, and smarter filesystem/shell tooling improves pagination, fallback matching, and output behavior. The system is becoming easier to inspect and easier to trust. (#1920, #1416, #1895)
-
Feishu saw major polish — Reply/quote support landed, tool calls can now render in code blocks, group mention behavior improved, Groq Whisper audio compatibility was fixed, and broader multimedia handling got much better. Feishu support feels substantially more complete after this cycle. (#1963, #1966, #1768, #1741, #2034)
-
Telegram got meaningfully better in groups and media workflows — Group response behavior is now configurable, reply-to-message context works across text and media, and media filename collision bugs were cleaned up. These are small details individually, but together they make conversations feel much more natural. (#1389, #1900, #1796)
-
Enterprise and collaboration channels improved too — WeCom channel support landed, Slack thread behavior was clarified, QQ legacy plain-text replies were restored, and DingTalk gained both voice recognition text retrieval and multimedia improvements. (#1327, #1784, #1941, #1859, #2034)
-
CLI and runtime behavior are more predictable — Gateway port defaults now respect config, restart flows are more portable, Windows compatibility got attention, and shell/workspace guards became stricter around home-expanded and tilde-based paths. This is the kind of work users only notice when it’s missing — which is exactly why it matters. (#1797, #1785, #1958, #1479, #1827, #1845)
-
A lot of sharp edges disappeared — Hidden files are no longer synced by accident, non-vision models won’t receive
image_url, heartbeat and cron got less noisy, and version IDs now show up in logs. These aren’t flashy changes, but they make nanobot feel more settled, more deliberate, and more production-ready. (#1856, #1901, #1973, #2058)
Community
A huge welcome to our 29 new contributors in this release.
Open source grows in two ways: through bold new ideas, and through the patient work of noticing rough edges and smoothing them out. v0.1.4.post5 has plenty of both. Thank you to everyone who contributed features, fixes, refactors, docs, and infrastructure improvements — nanobot is becoming stronger not all at once, but through many careful hands moving it forward together.
Full Changelog: v0.1.4.post4...v0.1.4.post5
What's Next
Looking ahead, we’ll continue moving nanobot toward a more modular, plugin-oriented ecosystem. As a first step, we plan to experiment and iterate in the channel layer first — using channels as the proving ground for a more extensible architecture before expanding that approach further across the project.
We’ll also keep using the nightly branch for faster testing, earlier feedback, and quicker iteration on new ideas. If you’re interested in helping shape that future, we’d warmly welcome contributions there. You can find the contribution workflow and guidelines in CONTRIBUTING.md.
And one more small note: v0.1.4.post5 will likely be the last release in the 0.1.4 line. It closes out this cycle with a lot of polish and hard-earned stability — and also makes room for what comes next.
The next main version is already taking shape, and we think it will be worth the wait. 😉
What's Changed
- fix: ensure feishu audio file has .opus extension for Groq Whisper compatibility by @chengyongru in #1741
- fix(slack): define thread usage in send() by @ailuntz in #1784
- fix(cli): let gateway use config port by default by @Protocol-zero-0 in #1797
- fix(cli): respect config.gateway.port in gateway command by @ailuntz in #1785
- fix(telegram): add group_policy to control bot response behavior in groups by @haosenwang1018 in #1389
- Add missing scripts to built-in skill
skill-creatorby @yankeguo in #1416 - feat: add LLM retry with exponential backoff for transient errors by @kiplangatkorir in #1512
- refactor: implement token-based context compression mechanism by @VITOHJL in #1704
- fix: bump litellm version to 1.82.1 for Moonshot provider support by @greyishsong in #1855
- feat: support retrieving DingTalk voice recognition text by @dingyanyi2019 in #1859
- fix(subagent): preserve reasoning_content in assistant messages by @lailoo in #1848
- fix: exclude hidden files when syncing workspace templates by @yapex in #1856
- Add WeChat Work (WeCom) channel support by @chengyongru in #1327
- feat: add Ollama as a local LLM provider by @letzdoo-js in #1863
- fix(memory): pass temperature, max_tokens and reasoning_effort to memory consolidation by @ethanclaw in #1868
- refactor: auto-discover channels via pkgutil, eliminate hardcoded registry by @Re-bin in #1888
- feat: allow direct references in hatch metadata for wecom dep by @for13to1 in #1885
- Fix Gemini thought_signature loss in tool-call replay by @WhalerO in #1874
- fix(exec): enforce workspace guard for home-expanded paths by @suger-m in #1827
- enhance: improve filesystem & shell tools with pagination, fallback matching, and smarter output by @Re-bin in #1895
- fix: detect tilde paths in restrictToWorkspace shell guard by @nikolasdehor in #1845
- fix: wecom-aibot-sdk-python should use pypi version by @chengyongru in #1897
- fix: force save_memory in consolidation by @Re-bin in #1909
- feat(channels): add "restart" command by @groudas in #1751
- feat(feishu): add global group mention policy by @Zeknes in #1768
- feat(telegram): support reply-to-message context (text and media) by @Schokobecher in #1900
- feat: Add VolcEngine and BytePlus (Pay-per-use & Coding Plan) support by @Maaannnn in #1608
- fix: preserve interactive CLI formatting for async subagent output by @ducheng121 in #1930
- fix: catch BaseException in MCP connection to handle CancelledError by @chengyongru in #1953
- fix(qq): restore plain text replies for legacy clients by @tsubasakong in #1941
- [紧急]修复we_chat在pyproject.toml配置的问题 by @ALIZE126 in #1919
- fix(restart): use -m nanobot for Windows compatibility by @chengyongru in #1958
- fix(memory): validate save_memory payload before persisting by @shenchengtsi in #1810
- feat(ci): add GitHub Actions workflow for test directory by @JiajunBernoulli in #1916
- docs: correct BaiLian dashscope apiBase endpoint by @tsubasakong in #1949
- Integrate Langsmith for conversation tracking by @korruz in #1920
- feat(web): add configurable web search providers with key-missing fallback by @chris-alexander in #398
- chore: bump wecom-aibot-sdk-python to >=0.1.5 by @chengyongru in #1981
- feat: channel plugin architecture with decoupled configs by @Re-bin in #1982
- fix(channels login): add shell=True for npm subprocess calls on Windows by @gongpx20069 in #1479
- fix(cron, heartbeat): prevent notification spam from cron and heartbeat tasks by @SJK-py in #1973
- feat:在MCP注册时指定启用工具以便让agent识别更准确并且减少token消耗 by @lvqiushi in #1965
- fix: add exception handling to prevent agent loop crash by @chengyongru in #1999
- fix(telegram): avoid media filename collisions by @Protocol-zero-0 in #1796
- feat(feishu): implement message reply/quote support by @mru4913 in #1963
- feat(feishu): display tool calls in code block messages + fix empty by @nne998 in #1966
- Support
openrouter/*models by @rick2047 in #2026 - fix: filter image_url for non-vision models at provider layer by @coldxiangyu163 in #1901
- Fix builtin skills inaccessible when restrictToWorkspace is enabled by @benlenarts in #2037
- Feat/dingtalk multimedia enhance by @chengyongru in #2034
- fix(heartbeat): inject current datetime into Phase 1 prompt by @who96 in #2038
- docs: add branching strategy and CONTRIBUTING guide by @chengyongru in #2021
- fix(loop): restore /new immediate return with safe background consolidation by @chengyongru in #1962
- feat: implement async memory background consolidation by @nne998 in #1961
- Fix orphan tool results in truncated session history by @xx2689 in #2075
- fix(cli): stop spinner before printing tool progress lines by @who96 in #2039
- qol: add version id to log output by @pve in #2058
New Contributors
- @ailuntz made their first contribution in #1784
- @Protocol-zero-0 made their first contribution in #1797
- @greyishsong made their first contribution in #1855
- @dingyanyi2019 made their first contribution in #1859
- @lailoo made their first contribution in #1848
- @yapex made their first contribution in #1856
- @letzdoo-js made their first contribution in #1863
- @ethanclaw made their first contribution in #1868
- @for13to1 made their first contribution in #1885
- @WhalerO made their first contribution in #1874
- @groudas made their first contribution in #1751
- @Zeknes made their first contribution in #1768
- @Schokobecher made their first contribution in #1900
- @Maaannnn made their first contribution in #1608
- @ducheng121 made their first contribution in #1930
- @tsubasakong made their first contribution in #1941
- @ALIZE126 made their first contribution in #1919
- @JiajunBernoulli made their first contribution in #1916
- @korruz made their first contribution in #1920
- @SJK-py made their first contribution in #1973
- @lvqiushi made their first contribution in #1965
- @mru4913 made their first contribution in #1963
- @nne998 made their first contribution in #1966
- @rick2047 made their first contribution in #2026
- @benlenarts made their first contribution in #2037
- @who96 made their first contribution in #2038
- @xx2689 made their first contribution in #2075
Full Changelog: v0.1.4.post4...v0.1.4.post5
详细ChangeLog