Repository navigation
Releases: HKUDS/nanobot
Release list
v0.3.5
🐈 nanobot v0.3.5 brings the workbench to the terminal — and makes conversations easier to continue across the browser, terminal, and chat apps.
The headline is one agent, more places to work. Run nanobot for the native terminal client or nanobot webui for the browser. Both use the same gateway and saved WebSocket conversations. Terminal sessions can be resumed, forked, inspected, and detached without building a separate agent runtime.
The browser workbench has grown around real multitasking: grouped conversation panes, temporary chats, persistent sidebar ordering, session mentions, a skills marketplace, portable Agent Plugins, and browser OAuth for remote MCP servers. Automations now have task and calendar views, clearer scheduling controls, and per-run replies. Mobile composition, settings, context charts, app logos, and branded mentions received another round of focused polish.
The other story is continuity you can inspect. Context usage and compaction are visible, interrupted work has clearer recovery controls, and session history is more durable across pagination, reconnects, and upgrades. This release also tightens attachment, process, workspace, and email-authentication boundaries. Please read the upgrade notes before replacing an existing installation.
Highlights
- A native terminal workbench — Start with
nanobot, switch sessions, paste supported clipboard images, complete app and skill references, inspect context and file diffs, queue follow-ups, and use/detachto leave the gateway running. - Browser conversations side by side — Arrange up to four topics in resizable groups, keep sidebar ordering, drag saved sessions into mentions, and use temporary chats when you do not want a persistent topic.
- Automations that are easier to manage — Switch between task and calendar views, inspect run replies, and adjust schedules with clearer controls. Editing a job preserves pending executions; deleting one no longer leaves navigation blocked.
- Visible context and steadier long sessions — Per-round token/cache charts, context-compaction progress, paged history search, cumulative summaries, and file-read deduplication scoped to the actual model context.
- Apps and skills with clearer identities — SkillHub discovery, portable Agent Plugins, remote MCP OAuth and token refresh, visible connection failures, and consistent app logos and brand names in chat.
- A better small-screen experience — Home-screen installation through PWA support, narrower composer controls, draggable context sheets, touch-friendly chart details, and settings navigation that matches its opening direction.
- Broader model and search choices — DeepSeek Responses and V4 vision support, Eden AI and OrcaRouter gateways, AnySearch, online OAuth model catalogs, and more resilient provider fallback and Responses-history handling.
- More reliable channels and runtime boundaries — Rich Telegram streaming, improved Feishu onboarding, safer QQ attachments, trusted email authentication results, optional macOS Seatbelt isolation, and fewer leaked credentials in subprocess environments.
- Embedding and operations — SDK host integration hooks, explicit Desktop attachment, gateway readiness reporting, and checked, version-matched terminal distributions.
Upgrade Notes
- Back up configuration, workspaces, and session storage; stop old processes first. Session JSONL files now live under the configuration directory's
sessions/<workspace-id>/tree. The first upgraded start migrates existing workspace sessions after verifying the copy. Do not let old and new versions write the same workspace concurrently. Before downgrading, stop nanobot and usenanobot sessions restore-workspace --config <config.json> --workspace <workspace>; the command refuses to overwrite a different existing file. See the session storage and rollback guide. - Email verification requires an explicit receiver trust anchor. If
verifySpforverifyDkimis enabled, configurechannels.email.trustedAuthservIdsusing the exact identity confirmed by your receiving mail service. That service must remove forged headers claiming its identity and provide one consolidated authentication-results header. Existing verified Email configurations without this field will not start. Keep Email disabled until configured; do not disable verification as a workaround. Follow the Email upgrade guide. - Plain
nanobotopens the native terminal UI. Usenanobot --classicfor the Python prompt ornanobot -m "Hello!"for one-shot usage. Platform wheels include both the WebUI and the matching TUI, so first TUI launch needs neither Bun nor a GitHub download. Supported wheels target macOS 13+ arm64/x64, glibc 2.17+ Linux arm64/x64, and Windows x64. Other platforms and source-distribution builds can use the classic prompt or WebUI; editable source development uses Bun. - The last attached client owns the on-demand gateway lifetime. Closing the last interactive WebUI/TUI launcher stops that gateway. Use
/detachin the terminal ornanobot gateway --backgroundfor work that must continue without a client. - Remote project selection uses paths on the nanobot host. It requires Restricted access. It does not select a directory from the browser device, and remote clients cannot enable Full Access.
- The gateway health response is more informative.
/healthcan return HTTP 503 when its enabled WebSocket channel is not running. It does not certify model, MCP, or other channel connectivity; update monitoring that previously assumed every live process returned 200. - Recheck concurrency and timeout limits.
NANOBOT_MAX_CONCURRENT_REQUESTSis unlimited unless set to a positive integer; configure an explicit cap if your deployment needs one. Subagent concurrency defaults to four and excess work waits for capacity. The oldagents.defaults.failOnToolErrorfield andNANOBOT_LLM_TIMEOUT_Sare no longer used. Model streams, including internal tasks, useNANOBOT_STREAM_IDLE_TIMEOUT_S(90 seconds by default), renewed by each event rather than a fixed total-duration timeout.
Community
Thank you to everyone who contributed code, reviewed changes, reported regressions, and tested nanobot in everyday work. Since v0.3.0, the release includes 402 merged PRs and 45 first-time contributors. The goal remains a small, inspectable agent whose conversations and work can move with you.
What's Changed
- docs(readme): clarify WebUI, gateway, and CLI quick starts by @Re-bin in #5082
- chore: defer compatibility cleanup to v0.3.1 by @Re-bin in #5083
- Smooth WebUI streaming with state-driven viewport motion by @chengyongru in #4696
- feat: open WebUI after fresh desktop install by @chengyongru in #5085
- fix(skills): tolerate null requires/bins/env in skill metadata by @santhreal in #5086
- fix(memory): skip non-dict history.jsonl lines when reading by @santhreal in #5090
- fix(session): coerce null session metadata to empty dict by @santhreal in #5091
- fix(webui): restore file edit diff display by @chengyongru in #5096
- feat(channels): enable tool hints by default by @chengyongru in #5097
- fix(feishu): tolerate null text fields when extracting post content by @santhreal in #5093
- fix(triggers): coerce string lastRunAtMs when loading local triggers by @santhreal in #5092
- fix(feishu): tolerate null multi_url and list fields in card extract by @santhreal in #5089
- fix(triggers): treat null runHistory as empty when loading triggers by @santhreal in #5087
- fix(agent): preserve pending message runtime context by @yu-xin-c in #5084
- fix(webui): prevent long messages from widening mobile thread by @chengyongru in #5100
- fix(heartbeat): route unified sessions to last channel by @yu-xin-c in #4928
- feat(exec): allow extra bwrap bind roots by @yu-xin-c in #4625
- fix(pairing): treat null approved/pending maps as empty by @santhreal in #5088
- fix(channels): ignore confirmations after connect cancellation by @KDB-Wind in #5069
- fix(mcp): normalize local schema refs by @amplifierplus in #5057
- fix(agent): preserve output across length recovery by @chengyongru in #5056
- fix(memory): progress past completed no-op Dream batches by @shixi-li in #5054
- feat(agent): make idle compaction scan interval configurable by @khmylov in #5036
- feat(dingtalk): gate private chats and mention sender in group replies by @lmzopq in #4446
- fix(cli): support Codex OAuth in Quick Start by @chengyongru in #4939
- fix(image): pass aspect ratio and size to Gemini Flash image models by @stupidloud in #4656
- fix(security): harden generated image URL downloads by @Re-bin in #5095
- refactor(agent): remove dead lifecycle scaffolding by @chengyongru in https://github.com/HKUDS/n...
v0.3.0
🐈 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): re...
v0.2.2
🐈 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...
v0.2.1
🐈 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 A...
v0.2.0
🐈 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 https://...
v0.1.5.post3
🐈 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 https://github.com/HK...
v0.1.5.post2
🐈 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 an...
v0.1.5.post1
🐈 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 prox...
v0.1.5
🐈 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 ...
v0.1.4.post6
🐈 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
- fi...