# Changelog All notable changes to DeerFlow are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [2.0.0] — 2026-06-15 DeerFlow 2.0 is a ground-up rewrite around a "super agent" harness with sub-agents, persistent memory, sandbox execution, and an extensible skills/tools system. It shares no code with the 1.x line, which now lives on the [`main-1.x` branch](https://github.com/bytedance/deer-flow/tree/main-1.x). This release closes [milestone 2.0.0](https://github.com/bytedance/deer-flow/milestone/1) with **102 merged pull requests** since the first 2.0 milestone tag. ### ⚠ Breaking changes - **harness:** Hydrate runs from `RunStore` and persist interrupted status. Run cancellation/multitask semantics now require a working RunStore on the worker that owns the run; cross-worker cancels return 409 instead of silently appearing successful. ([#2932]) ### Added #### Agents & runtime - **agent:** Custom-agent self-updates with user isolation — agents can persist edits to their own `SOUL.md` / `config.yaml` from inside a normal chat. ([#2713]) - **loop-detection:** Make loop detection configurable with per-tool frequency overrides; keep configurable on/off switch. ([#2586], [#2711]) - **loop-detection:** Defer warning injection so detector pairs cleanly with tool-call lifecycle. ([#2752]) - **run:** Propagate `model_name` from the gateway request through the runtime and persistence stack into the SQLite-backed store. ([#2775]) - **subagents:** Stream subagent token usage to the header via terminal task events. ([#2882]) #### Models & integrations - **models:** Add StepFun reasoning model adapter. ([#3461]) - **community:** Add Brave Search web search tool. ([#3528]) - **channels:** Enhance Discord with mention-only mode, thread routing, and typing indicators. ([#2842]) - **im:** Add user-owned IM channel connections — users can bind their own Slack/Telegram/Discord/Feishu/DingTalk/WeChat/WeCom accounts on top of the operator-configured bots. ([#3487]) #### Observability - **trace:** Set the LangGraph trace name to `lead_agent` (or the custom agent's `agent_name`) for cleaner Langfuse/LangSmith traces. ([#3101]) - **frontend:** Refine token usage display modes. ([#2329]) - **defaults:** Enable token usage tracking by default. ([#2841]) - **defaults:** Raise default summarization trigger threshold. ([#3174]) ### Performance - **harness:** Push thread metadata filters into SQL instead of post-filtering in Python. ([#2865]) - **runtime:** Index runs by `thread_id` to avoid O(n) scans in `RunManager`. ([#3499]) - **runtime:** Index messages in `MemoryRunEventStore` to avoid O(n) scans. ([#3531]) ### Security - **upload:** Reject symlinked upload destinations. ([#2623]) - **uploads:** Add Windows support for safe symlink-protected uploads. ([#2794]) - **mcp:** Mask sensitive values in MCP config API responses. ([#2667]) - **mcp:** Harden the MCP config endpoint against malformed input. ([#3425]) - **auth:** Reject cross-site auth POSTs. ([#2740]) - **gateway:** Cap skill artifact preview decompression to prevent zip-bomb-style abuse. ([#2963]) ### Fixed #### Runtime, gateway & persistence - **runtime:** Rollback restore checkpoint now supersedes newer checkpoints. ([#2582]) - **runtime:** Persist run message summaries. ([#2850]) - **runtime:** Bound `write_file` execution-failure observations to keep failure traces from blowing out the context. ([#3133]) - **runtime:** Protect the sync singleton's init and reset paths. ([#3413]) - **runtime:** Avoid PostgreSQL aggregate `FOR UPDATE` on run events. ([#2962]) - **runs:** Restore historical runs from persistent store after a gateway restart. ([#2989]) - **gateway:** Return ISO 8601 timestamps from threads endpoints. ([#2599]) - **gateway:** Make cancel idempotent for already-interrupted runs. ([#3058]) - **gateway:** Split `stream_existing_run` into per-method routes for unique OpenAPI `operationId`s. ([#3228]) - **events:** Serialize structured DB event content. ([#2762]) - **persistence:** Emit timezone-aware timestamps from SQLite-backed stores. ([#3130]) - **persistence:** Reuse token usage model grouping expression. ([#2910]) - **runs:** Ignore stale run reconnect conflicts. ([#3284]) - **nginx:** Defer CORS to the gateway allowlist instead of double-applying it. ([#2861]) #### Agents, subagents & middleware - **subagents:** Make subagent timeout terminal state atomic. ([#2583]) - **subagents:** Use model override for tools and middleware. ([#2641]) - **subagents:** Consolidate `system_prompt` and skills into a single `SystemMessage`. ([#2701]) - **subagent:** Isolate subagents from the parent run's checkpointer. ([#3559]) - **agents:** Make `update_agent` honor `runtime.context` `user_id` like `setup_agent` does. ([#2867]) - **agents:** Resolve duplicate `todos` channel type conflict in `TodoMiddleware`. ([#3200]) - **agents:** Offload blocking filesystem IO in the custom-agent router off the event loop. ([#3457]) - **agents:** Keep new agent bootstrap in user scope. ([#2784]) - **loop-detection:** Keep tool-call pairing on warn injection. ([#2725]) - **middleware:** Sync raw tool-call metadata. ([#2757]) - **middleware:** Handle invalid tool calls in dangling pairing middleware. ([#2891]) - **middleware:** Prevent todo completion reminder IM-message leak. ([#2907]) - **middleware:** Normalize tool result adjacency before model calls. ([#2939]) #### Memory & tracing - **memory:** Replace short-lived `asyncio.run()` with a persistent event loop. ([#2627]) - **memory:** Isolate queued memory updates by agent. ([#2941]) - **memory:** Parse wrapped memory-update JSON responses. ([#3252]) - **tracing:** Propagate `session_id` and `user_id` into Langfuse traces. ([#2944]) - **trace:** Decode unicode escape sequences in non-ASCII memory trace info. ([#3104]) #### Tools, sandbox & MCP - **mcp:** Fix env resolution in MCP config lists. ([#2556]) - **models:** Record Codex token usage in `usage_metadata`. ([#2585]) - **sandbox:** Supplement `list_running` in `RemoteSandboxBackend`. ([#2716]) - **sandbox:** Disable MSYS path conversion for Git Bash on Windows. ([#2766]) - **sandbox:** Avoid blocking sandbox readiness polling. ([#2822]) - **sandbox:** Uphold the `/mnt/user-data` contract at the `Sandbox` API boundary. ([#2881]) - **sandbox:** Scope provisioner PVC data by user. ([#2973]) - **sandbox:** Merge idempotent sandbox state updates. ([#3518]) - **tools:** Introduce `Runtime` type alias to eliminate Pydantic serialization warnings. ([#2774]) - **tools:** Preserve `tool_search` promotions across re-entrant `get_available_tools`. ([#2885]) - **harness:** Wrap async-only config tools for sync client execution. ([#2878]) - **harness:** Wrap all async-only tools for sync clients. ([#2935]) #### Skills & channels - **skills:** Enforce `allowed-tools` metadata. ([#2626]) - **skills:** Harden slash skill activation across chat channels. ([#3466]) - **skills:** Fix custom skill install permissions. ([#3241]) - **channels:** Authenticate gateway command requests. ([#2742]) #### Auth - **auth:** Replace setup-status 429 rate limit with a cached response. ([#2915]) - **auth:** Persist auto-generated JWT secret so it survives restarts. ([#2933]) #### Frontend - **frontend:** Restore `localhost` fallback for `getGatewayConfig` in prod mode. ([#2718]) - **chat:** Prevent the first user message from being swallowed in new conversations. ([#2731]) - **frontend:** Use backend thread token usage for the header total. ([#2800]) - **frontend:** Wait for async chat submit before clearing the input. ([#2940]) - **frontend:** Resolve login page flickering and the resize-observer loop. ([#2954]) - **frontend:** Deduplicate restored thread messages. ([#2958]) - **frontend:** Avoid duplicate optimistic user message. ([#3002]) - **frontend:** Hide the copy button for streaming assistant messages. ([#3176]) - **frontend:** Show a new thread in the sidebar immediately on creation. ([#3283]) - **frontend:** Isolate new chat thread messages. ([#3508]) - **frontend:** Cap deeply nested list indentation to prevent render crashes. ([#3393], [#3570]) - **token-usage:** Dedupe token usage aggregation by message id. ([#2770]) #### Build, deploy, scripts & config - **packaging:** Add `postgres` extra for store/checkpointer support; clarify install guidance. ([#2584]) - **harness:** Resolve runtime paths from the project root. ([#2642]) - **docker:** Force nginx to resolve upstream names at request time. ([#2717]) - **docker:** Default Gateway to a single worker to prevent multi-worker breakage. ([#3475]) - **scripts:** Preserve `uv` extras across `make dev` restarts. ([#2767], [#2754]) - **scripts:** Clean up local nginx on stop. ([#3005]) - **deploy:** Fall back to `python` / `openssl` when `python3` is absent for secret generation. ([#3074]) - **config:** Make the reload boundary discoverable from code. ([#3144], [#3153]) - **replay-e2e:** Key replay fixtures by caller and conversation. ([#3453]) ### Changed - **provider (refactor):** Share assistant payload replay matching across providers. ([#3307]) ### Documentation - Document blocking-IO detection usage and maintenance. ([#3233]) - Clean standalone LangGraph server remnants from docs. ([#3301]) ### Internal - **dev:** Add async/thread boundary detector. ([#2936]) - **runtime:** Add lifecycle end-to-end coverage. ([#2946]) - **windows:** Add `PYTHONIOENCODING` and `PYTHONUTF8` to backend Makefile targets. ([#3069]) - **blocking-io:** Fail-loud repo-root resolution and shared detector CLI shim. ([#3512]) [2.0.0]: https://github.com/bytedance/deer-flow/releases/tag/v2.0.0 [#2329]: https://github.com/bytedance/deer-flow/pull/2329 [#2556]: https://github.com/bytedance/deer-flow/pull/2556 [#2582]: https://github.com/bytedance/deer-flow/pull/2582 [#2583]: https://github.com/bytedance/deer-flow/pull/2583 [#2584]: https://github.com/bytedance/deer-flow/pull/2584 [#2585]: https://github.com/bytedance/deer-flow/pull/2585 [#2586]: https://github.com/bytedance/deer-flow/pull/2586 [#2599]: https://github.com/bytedance/deer-flow/pull/2599 [#2623]: https://github.com/bytedance/deer-flow/pull/2623 [#2626]: https://github.com/bytedance/deer-flow/pull/2626 [#2627]: https://github.com/bytedance/deer-flow/pull/2627 [#2641]: https://github.com/bytedance/deer-flow/pull/2641 [#2642]: https://github.com/bytedance/deer-flow/pull/2642 [#2667]: https://github.com/bytedance/deer-flow/pull/2667 [#2701]: https://github.com/bytedance/deer-flow/pull/2701 [#2711]: https://github.com/bytedance/deer-flow/pull/2711 [#2713]: https://github.com/bytedance/deer-flow/pull/2713 [#2716]: https://github.com/bytedance/deer-flow/pull/2716 [#2717]: https://github.com/bytedance/deer-flow/pull/2717 [#2718]: https://github.com/bytedance/deer-flow/pull/2718 [#2725]: https://github.com/bytedance/deer-flow/pull/2725 [#2731]: https://github.com/bytedance/deer-flow/pull/2731 [#2740]: https://github.com/bytedance/deer-flow/pull/2740 [#2742]: https://github.com/bytedance/deer-flow/pull/2742 [#2752]: https://github.com/bytedance/deer-flow/pull/2752 [#2754]: https://github.com/bytedance/deer-flow/pull/2754 [#2757]: https://github.com/bytedance/deer-flow/pull/2757 [#2762]: https://github.com/bytedance/deer-flow/pull/2762 [#2766]: https://github.com/bytedance/deer-flow/pull/2766 [#2767]: https://github.com/bytedance/deer-flow/pull/2767 [#2770]: https://github.com/bytedance/deer-flow/pull/2770 [#2774]: https://github.com/bytedance/deer-flow/pull/2774 [#2775]: https://github.com/bytedance/deer-flow/pull/2775 [#2784]: https://github.com/bytedance/deer-flow/pull/2784 [#2794]: https://github.com/bytedance/deer-flow/pull/2794 [#2800]: https://github.com/bytedance/deer-flow/pull/2800 [#2822]: https://github.com/bytedance/deer-flow/pull/2822 [#2841]: https://github.com/bytedance/deer-flow/pull/2841 [#2842]: https://github.com/bytedance/deer-flow/pull/2842 [#2850]: https://github.com/bytedance/deer-flow/pull/2850 [#2861]: https://github.com/bytedance/deer-flow/pull/2861 [#2865]: https://github.com/bytedance/deer-flow/pull/2865 [#2867]: https://github.com/bytedance/deer-flow/pull/2867 [#2878]: https://github.com/bytedance/deer-flow/pull/2878 [#2881]: https://github.com/bytedance/deer-flow/pull/2881 [#2882]: https://github.com/bytedance/deer-flow/pull/2882 [#2885]: https://github.com/bytedance/deer-flow/pull/2885 [#2891]: https://github.com/bytedance/deer-flow/pull/2891 [#2907]: https://github.com/bytedance/deer-flow/pull/2907 [#2910]: https://github.com/bytedance/deer-flow/pull/2910 [#2915]: https://github.com/bytedance/deer-flow/pull/2915 [#2932]: https://github.com/bytedance/deer-flow/pull/2932 [#2933]: https://github.com/bytedance/deer-flow/pull/2933 [#2935]: https://github.com/bytedance/deer-flow/pull/2935 [#2936]: https://github.com/bytedance/deer-flow/pull/2936 [#2939]: https://github.com/bytedance/deer-flow/pull/2939 [#2940]: https://github.com/bytedance/deer-flow/pull/2940 [#2941]: https://github.com/bytedance/deer-flow/pull/2941 [#2944]: https://github.com/bytedance/deer-flow/pull/2944 [#2946]: https://github.com/bytedance/deer-flow/pull/2946 [#2954]: https://github.com/bytedance/deer-flow/pull/2954 [#2958]: https://github.com/bytedance/deer-flow/pull/2958 [#2962]: https://github.com/bytedance/deer-flow/pull/2962 [#2963]: https://github.com/bytedance/deer-flow/pull/2963 [#2973]: https://github.com/bytedance/deer-flow/pull/2973 [#2989]: https://github.com/bytedance/deer-flow/pull/2989 [#3002]: https://github.com/bytedance/deer-flow/pull/3002 [#3005]: https://github.com/bytedance/deer-flow/pull/3005 [#3058]: https://github.com/bytedance/deer-flow/pull/3058 [#3069]: https://github.com/bytedance/deer-flow/pull/3069 [#3074]: https://github.com/bytedance/deer-flow/pull/3074 [#3101]: https://github.com/bytedance/deer-flow/pull/3101 [#3104]: https://github.com/bytedance/deer-flow/pull/3104 [#3130]: https://github.com/bytedance/deer-flow/pull/3130 [#3133]: https://github.com/bytedance/deer-flow/pull/3133 [#3144]: https://github.com/bytedance/deer-flow/pull/3144 [#3153]: https://github.com/bytedance/deer-flow/pull/3153 [#3174]: https://github.com/bytedance/deer-flow/pull/3174 [#3176]: https://github.com/bytedance/deer-flow/pull/3176 [#3200]: https://github.com/bytedance/deer-flow/pull/3200 [#3228]: https://github.com/bytedance/deer-flow/pull/3228 [#3233]: https://github.com/bytedance/deer-flow/pull/3233 [#3241]: https://github.com/bytedance/deer-flow/pull/3241 [#3252]: https://github.com/bytedance/deer-flow/pull/3252 [#3283]: https://github.com/bytedance/deer-flow/pull/3283 [#3284]: https://github.com/bytedance/deer-flow/pull/3284 [#3301]: https://github.com/bytedance/deer-flow/pull/3301 [#3307]: https://github.com/bytedance/deer-flow/pull/3307 [#3393]: https://github.com/bytedance/deer-flow/pull/3393 [#3413]: https://github.com/bytedance/deer-flow/pull/3413 [#3425]: https://github.com/bytedance/deer-flow/pull/3425 [#3453]: https://github.com/bytedance/deer-flow/pull/3453 [#3457]: https://github.com/bytedance/deer-flow/pull/3457 [#3461]: https://github.com/bytedance/deer-flow/pull/3461 [#3466]: https://github.com/bytedance/deer-flow/pull/3466 [#3475]: https://github.com/bytedance/deer-flow/pull/3475 [#3487]: https://github.com/bytedance/deer-flow/pull/3487 [#3499]: https://github.com/bytedance/deer-flow/pull/3499 [#3508]: https://github.com/bytedance/deer-flow/pull/3508 [#3512]: https://github.com/bytedance/deer-flow/pull/3512 [#3518]: https://github.com/bytedance/deer-flow/pull/3518 [#3528]: https://github.com/bytedance/deer-flow/pull/3528 [#3531]: https://github.com/bytedance/deer-flow/pull/3531 [#3559]: https://github.com/bytedance/deer-flow/pull/3559 [#3570]: https://github.com/bytedance/deer-flow/pull/3570