bytedance/deer-flowPublic

An open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.

AI summary: An enterprise-grade, open-source super agent harness for orchestrating complex, multi-agent research workflows.

Stars
79.5K
+90 today
Forks
10.9K
Watchers
333
Open issues
590
Open PRs
364
Contributors
~343
Commits
2.9K
Branches
47

PythonMITCreated May 7, 2025Last push todayLatest release v2.0.0+1.1K stars this week+1.4K this month

Star history

since May 4, 2025
020K40K60KMay 2025Oct 2025Mar 2026Aug 2026
79.5K stars as of Aug 7, 2026, tracked back to May 4, 2025. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulAugMonWedFri2025-08-10: 0 commits2025-08-11: 1 commit2025-08-12: 0 commits2025-08-13: 1 commit2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 1 commit2025-08-17: 1 commit2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 4 commits2025-08-21: 3 commits2025-08-22: 1 commit2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 1 commit2025-09-04: 3 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 1 commit2025-09-09: 4 commits2025-09-10: 1 commit2025-09-11: 0 commits2025-09-12: 3 commits2025-09-13: 1 commit2025-09-14: 2 commits2025-09-15: 0 commits2025-09-16: 3 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 3 commits2025-09-23: 0 commits2025-09-24: 1 commit2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 2 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 1 commit2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 2 commits2025-10-12: 1 commit2025-10-13: 1 commit2025-10-14: 1 commit2025-10-15: 3 commits2025-10-16: 4 commits2025-10-17: 1 commit2025-10-18: 0 commits2025-10-19: 3 commits2025-10-20: 2 commits2025-10-21: 4 commits2025-10-22: 5 commits2025-10-23: 2 commits2025-10-24: 5 commits2025-10-25: 2 commits2025-10-26: 4 commits2025-10-27: 4 commits2025-10-28: 2 commits2025-10-29: 1 commit2025-10-30: 0 commits2025-10-31: 1 commit2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 1 commit2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 1 commit2025-11-11: 1 commit2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 1 commit2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 2 commits2025-11-22: 2 commits2025-11-23: 0 commits2025-11-24: 2 commits2025-11-25: 1 commit2025-11-26: 0 commits2025-11-27: 3 commits2025-11-28: 4 commits2025-11-29: 3 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 3 commits2025-12-03: 0 commits2025-12-04: 1 commit2025-12-05: 1 commit2025-12-06: 2 commits2025-12-07: 0 commits2025-12-08: 1 commit2025-12-09: 1 commit2025-12-10: 1 commit2025-12-11: 1 commit2025-12-12: 1 commit2025-12-13: 1 commit2025-12-14: 0 commits2025-12-15: 2 commits2025-12-16: 1 commit2025-12-17: 2 commits2025-12-18: 0 commits2025-12-19: 1 commit2025-12-20: 0 commits2025-12-21: 2 commits2025-12-22: 0 commits2025-12-23: 2 commits2025-12-24: 0 commits2025-12-25: 3 commits2025-12-26: 2 commits2025-12-27: 1 commit2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 2 commits2025-12-31: 0 commits2026-01-01: 1 commit2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 1 commit2026-01-06: 2 commits2026-01-07: 2 commits2026-01-08: 0 commits2026-01-09: 3 commits2026-01-10: 1 commit2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 25 commits2026-01-15: 14 commits2026-01-16: 56 commits2026-01-17: 71 commits2026-01-18: 26 commits2026-01-19: 26 commits2026-01-20: 25 commits2026-01-21: 25 commits2026-01-22: 39 commits2026-01-23: 15 commits2026-01-24: 52 commits2026-01-25: 25 commits2026-01-26: 11 commits2026-01-27: 10 commits2026-01-28: 22 commits2026-01-29: 52 commits2026-01-30: 16 commits2026-01-31: 30 commits2026-02-01: 24 commits2026-02-02: 59 commits2026-02-03: 24 commits2026-02-04: 9 commits2026-02-05: 9 commits2026-02-06: 69 commits2026-02-07: 33 commits2026-02-08: 28 commits2026-02-09: 61 commits2026-02-10: 8 commits2026-02-11: 3 commits2026-02-12: 2 commits2026-02-13: 5 commits2026-02-14: 7 commits2026-02-15: 1 commit2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 3 commits2026-02-19: 1 commit2026-02-20: 0 commits2026-02-21: 3 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 4 commits2026-02-25: 8 commits2026-02-26: 3 commits2026-02-27: 2 commits2026-02-28: 4 commits2026-03-01: 6 commits2026-03-02: 4 commits2026-03-03: 2 commits2026-03-04: 5 commits2026-03-05: 5 commits2026-03-06: 7 commits2026-03-07: 1 commit2026-03-08: 8 commits2026-03-09: 4 commits2026-03-10: 8 commits2026-03-11: 8 commits2026-03-12: 2 commits2026-03-13: 10 commits2026-03-14: 7 commits2026-03-15: 0 commits2026-03-16: 4 commits2026-03-17: 7 commits2026-03-18: 7 commits2026-03-19: 1 commit2026-03-20: 5 commits2026-03-21: 2 commits2026-03-22: 9 commits2026-03-23: 8 commits2026-03-24: 13 commits2026-03-25: 15 commits2026-03-26: 15 commits2026-03-27: 15 commits2026-03-28: 8 commits2026-03-29: 20 commits2026-03-30: 12 commits2026-03-31: 8 commits2026-04-01: 13 commits2026-04-02: 11 commits2026-04-03: 17 commits2026-04-04: 10 commits2026-04-05: 11 commits2026-04-06: 15 commits2026-04-07: 12 commits2026-04-08: 8 commits2026-04-09: 14 commits2026-04-10: 14 commits2026-04-11: 12 commits2026-04-12: 9 commits2026-04-13: 2 commits2026-04-14: 10 commits2026-04-15: 6 commits2026-04-16: 6 commits2026-04-17: 1 commit2026-04-18: 10 commits2026-04-19: 6 commits2026-04-20: 5 commits2026-04-21: 2 commits2026-04-22: 2 commits2026-04-23: 7 commits2026-04-24: 10 commits2026-04-25: 5 commits2026-04-26: 22 commits2026-04-27: 0 commits2026-04-28: 12 commits2026-04-29: 0 commits2026-04-30: 10 commits2026-05-01: 8 commits2026-05-02: 7 commits2026-05-03: 1 commit2026-05-04: 6 commits2026-05-05: 5 commits2026-05-06: 2 commits2026-05-07: 5 commits2026-05-08: 9 commits2026-05-09: 12 commits2026-05-10: 5 commits2026-05-11: 7 commits2026-05-12: 8 commits2026-05-13: 4 commits2026-05-14: 1 commit2026-05-15: 7 commits2026-05-16: 3 commits2026-05-17: 5 commits2026-05-18: 3 commits2026-05-19: 2 commits2026-05-20: 10 commits2026-05-21: 13 commits2026-05-22: 5 commits2026-05-23: 8 commits2026-05-24: 0 commits2026-05-25: 1 commit2026-05-26: 7 commits2026-05-27: 1 commit2026-05-28: 11 commits2026-05-29: 8 commits2026-05-30: 1 commit2026-05-31: 2 commits2026-06-01: 3 commits2026-06-02: 3 commits2026-06-03: 9 commits2026-06-04: 1 commit2026-06-05: 2 commits2026-06-06: 2 commits2026-06-07: 7 commits2026-06-08: 15 commits2026-06-09: 11 commits2026-06-10: 7 commits2026-06-11: 6 commits2026-06-12: 11 commits2026-06-13: 13 commits2026-06-14: 8 commits2026-06-15: 1 commit2026-06-16: 4 commits2026-06-17: 14 commits2026-06-18: 7 commits2026-06-19: 18 commits2026-06-20: 5 commits2026-06-21: 18 commits2026-06-22: 8 commits2026-06-23: 13 commits2026-06-24: 11 commits2026-06-25: 9 commits2026-06-26: 2 commits2026-06-27: 5 commits2026-06-28: 5 commits2026-06-29: 0 commits2026-06-30: 2 commits2026-07-01: 9 commits2026-07-02: 10 commits2026-07-03: 14 commits2026-07-04: 23 commits2026-07-05: 9 commits2026-07-06: 15 commits2026-07-07: 10 commits2026-07-08: 4 commits2026-07-09: 12 commits2026-07-10: 14 commits2026-07-11: 23 commits2026-07-12: 26 commits2026-07-13: 14 commits2026-07-14: 27 commits2026-07-15: 14 commits2026-07-16: 13 commits2026-07-17: 10 commits2026-07-18: 9 commits2026-07-19: 16 commits2026-07-20: 14 commits2026-07-21: 24 commits2026-07-22: 17 commits2026-07-23: 15 commits2026-07-24: 13 commits2026-07-25: 11 commits2026-07-26: 25 commits2026-07-27: 18 commits2026-07-28: 24 commits2026-07-29: 21 commits2026-07-30: 9 commits2026-07-31: 11 commits2026-08-01: 12 commits2026-08-02: 8 commits2026-08-03: 2 commits2026-08-04: 5 commits2026-08-05: 3 commits2026-08-06: 0 commits2026-08-07: 0 commits2026-08-08: 0 commits
2,437 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Landmark project

    79,506 stars

  • Very active

    2,437 commits in 52 weeks

  • Community-driven

    ~343 contributors

  • Well documented

    High community health score

  • Permissive license

    MIT

  • Continuous integration

    Automated checks passing

  • Repeat trending

    19 trending appearances

  • Top 10% tracked

    Rank 87 of 1058

What deer-flow does

DeerFlow 2.0, developed by ByteDance, is a highly sophisticated framework for orchestrating AI agents to perform deep exploration and efficient research. It acts as a 'super agent harness' that coordinates multiple specialized sub-agents, manages shared memory, and provides secure sandboxed environments for execution. Built as a ground-up rewrite of its predecessor, it leverages extensible skills and integrates deeply with enterprise LLMs. It excels at breaking down massive, ambiguous research tasks into manageable steps, executing code, crawling data, and synthesizing results reliably at scale.

Enterprise developers, AI researchers, and data scientists looking to build highly reliable, multi-step autonomous workflows. Requires Python proficiency and access to high-tier LLM APIs (like DeepSeek v3 or Claude).

  • Multi-Agent Orchestration: Manages specialized sub-agents to tackle different facets of a complex problem.
  • Secure Sandboxing: Executes AI-generated code and research tasks safely isolated from the host system.
  • Advanced Memory Management: Shares context seamlessly between agents to prevent redundant work or hallucinations.
  • Extensible Skill System: Easily plug in custom enterprise tools, databases, or API integrations.
  • Enterprise Scale: Backed by ByteDance, designed to handle massive, long-running agentic workflows reliably.

Where teams use it

Deep Market Research

Deploying agents to scour the web, analyze competitor APIs, and synthesize a comprehensive market report overnight.

Automated Code Auditing

Coordinating a fleet of sub-agents to read a massive monorepo, identify security flaws, and draft fix proposals.

Scientific Literature Review

Instructing the harness to find, read, and summarize hundreds of academic papers on a specific niche topic.

Enterprise Tool Integration

Connecting the harness to internal knowledge bases to automate complex data retrieval and analysis tasks for analysts.

Getting started: pip install deerflow

README

main branch

🦌 DeerFlow - 2.0

English | 中文 | 日本語 | Français | Русский

Python Node.js License: MIT

bytedance%2Fdeer-flow | Trendshift

On February 28th, 2026, DeerFlow claimed the 🏆 #1 spot on GitHub Trending following the launch of version 2. Thanks a million to our incredible community — you made this happen! 💪🔥

DeerFlow (Deep Exploration and Efficient Research Flow) is an open-source super agent harness that orchestrates sub-agents, memory, and sandboxes to do almost anything — powered by extensible skills.

deer-flow-720p.mp4

Note

DeerFlow 2.0 is a ground-up rewrite. It shares no code with v1. If you're looking for the original Deep Research framework, it's maintained on the 1.x branch — contributions there are still welcome. Active development has moved to 2.0.

Official Website

Learn more and see real demos on our official website.

Sister Projects

image
  • LLM Space - Meet our secret weapon behind DeerFlow — one desktop tool to prototype agent ideas, inspect each harness step, replay failures, and benchmark performance.

Coding Plan from ByteDance Volcengine

InfoQuest

DeerFlow has newly integrated the intelligent search and crawling toolset independently developed by BytePlus--InfoQuest (supports free online experience)

InfoQuest_banner

Table of Contents

One-Line Agent Setup

If you use Claude Code, Codex, Cursor, Windsurf, or another coding agent, you can hand it the setup instructions in one sentence:

Help me clone DeerFlow if needed, then bootstrap it for local development by following https://raw.githubusercontent.com/bytedance/deer-flow/main/Install.md

That prompt is intended for coding agents. It tells the agent to clone the repo if needed, choose Docker when available, and stop with the exact next command plus any missing config the user still needs to provide.

Quick Start

Configuration

  1. Clone the DeerFlow repository

    git clone https://github.com/bytedance/deer-flow.git
    cd deer-flow
  2. Run the setup wizard

    From the project root directory (deer-flow/), run:

    make setup

    This launches an interactive wizard that guides you through choosing an LLM provider, optional web search, and execution/safety preferences such as sandbox mode, bash access, and file-write tools. It generates a minimal config.yaml and writes your keys to .env. Takes about 2 minutes.

    The wizard also lets you configure an optional web search provider, or skip it for now.

    Run make doctor at any time to verify your setup and get actionable fix hints. If you are opening a GitHub issue about a local setup or runtime problem, run make support-bundle. The command prints reporter next steps, writes a *-issue-summary.md file to paste into the issue, a *-issue-draft.md file for AI-assisted issue filing, and an optional evidence zip under .deer-flow/support-bundles/. If an AI assistant files the issue, start from the draft and replace every REQUIRED placeholder instead of inventing missing facts. Attach the zip only if a maintainer asks for it, or if the summary alone is not enough. Maintainers and AI triage tools can start with triage.json; the bundle includes redacted diagnostics and file manifests only, and does not include .env, raw conversation messages, or user file contents.

    Advanced / manual configuration: If you prefer to edit config.yaml directly, run make config instead to copy the full template. See config.example.yaml for the complete reference including CLI-backed providers (Codex CLI, Claude Code OAuth), OpenRouter, Responses API, subagent runtime caps such as subagents.max_total_per_run, and more.

    Optional per-model pricing must use one currency across all priced models. DeerFlow disables Console cost estimates when currencies are mixed rather than presenting an invalid aggregate.

    Manual model configuration examples
    models:
      - name: gpt-4o
        display_name: GPT-4o
        use: langchain_openai:ChatOpenAI
        model: gpt-4o
        api_key: $OPENAI_API_KEY
    
      - name: openrouter-gemini-2.5-flash
        display_name: Gemini 2.5 Flash (OpenRouter)
        use: langchain_openai:ChatOpenAI
        model: google/gemini-2.5-flash-preview
        api_key: $OPENROUTER_API_KEY
        base_url: https://openrouter.ai/api/v1
    
      - name: gpt-5-responses
        display_name: GPT-5 (Responses API)
        use: langchain_openai:ChatOpenAI
        model: gpt-5
        api_key: $OPENAI_API_KEY
        use_responses_api: true
        output_version: responses/v1
    
      - name: qwen3-32b-vllm
        display_name: Qwen3 32B (vLLM)
        use: deerflow.models.vllm_provider:VllmChatModel
        model: Qwen/Qwen3-32B
        api_key: $VLLM_API_KEY
        base_url: http://localhost:8000/v1
        supports_thinking: true
        when_thinking_enabled:
          extra_body:
            chat_template_kwargs:
              enable_thinking: true

    OpenRouter and similar OpenAI-compatible gateways should be configured with langchain_openai:ChatOpenAI plus base_url. If you prefer a provider-specific environment variable name, point api_key at that variable explicitly (for example api_key: $OPENROUTER_API_KEY).

    To route OpenAI models through /v1/responses, keep using langchain_openai:ChatOpenAI and set use_responses_api: true with output_version: responses/v1.

    For vLLM 0.19.0, use deerflow.models.vllm_provider:VllmChatModel. For Qwen-style reasoning models, DeerFlow toggles reasoning with extra_body.chat_template_kwargs.enable_thinking and preserves vLLM's non-standard reasoning field across multi-turn tool-call conversations. Legacy thinking configs are normalized automatically for backward compatibility. If the endpoint reports a cumulative usage snapshot on every streaming chunk, set cumulative_stream_usage: true so DeerFlow converts those snapshots into per-chunk deltas; the option is disabled by default and leaves usage unchanged when a stable completion id is unavailable. Reasoning models may also require the server to be started with --reasoning-parser .... If your local vLLM deployment accepts any non-empty API key, you can still set VLLM_API_KEY to a placeholder value.

    CLI-backed provider examples:

    models:
      - name: gpt-5.4
        display_name: GPT-5.4 (Codex CLI)
        use: deerflow.models.openai_codex_provider:CodexChatModel
        model: gpt-5.4
        supports_thinking: true
        supports_reasoning_effort: true
    
      - name: claude-sonnet-4.6
        display_name: Claude Sonnet 4.6 (Claude Code OAuth)
        use: deerflow.models.claude_provider:ClaudeChatModel
        model: claude-sonnet-4-6
        max_tokens: 4096
        supports_thinking: true
    • Codex CLI reads ~/.codex/auth.json
    • Claude Code accepts CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_AUTH_TOKEN, CLAUDE_CODE_CREDENTIALS_PATH, or ~/.claude/.credentials.json
    • ACP agent entries are separate from model providers — if you configure acp_agents.codex, point it at a Codex ACP adapter such as npx -y @zed-industries/codex-acp
    • On macOS, export Claude Code auth explicitly if needed:
    eval "$(python3 scripts/export_claude_code_oauth.py --print-export)"

    API keys can also be set manually in .env (recommended) or exported in your shell:

    OPENAI_API_KEY=your-openai-api-key
    TAVILY_API_KEY=your-tavily-api-key

Running the Application

Deployment Sizing

Use the table below as a practical starting point when choosing how to run DeerFlow:

Deployment target Starting point Recommended Notes
Local evaluation / make dev 4 vCPU, 8 GB RAM, 20 GB free SSD 8 vCPU, 16 GB RAM Good for one developer or one light session with hosted model APIs. 2 vCPU / 4 GB is usually not enough.
Docker development / make docker-start 4 vCPU, 8 GB RAM, 25 GB free SSD 8 vCPU, 16 GB RAM Image builds, bind mounts, and sandbox containers need more headroom than pure local dev.
Long-running server / make up 8 vCPU, 16 GB RAM, 40 GB free SSD 16 vCPU, 32 GB RAM Preferred for shared use, multi-agent runs, report generation, or heavier sandbox workloads.
  • These numbers cover DeerFlow itself. If you also host a local LLM, size that service separately.
  • Linux plus Docker is the recommended deployment target for a persistent server. macOS and Windows are best treated as development or evaluation environments.
  • If CPU or memory usage stays pinned, reduce concurrent runs first, then move to the next sizing tier.

Option 1: Docker (Recommended)

Development (hot-reload, source mounts):

make docker-init    # Pull sandbox image (only once or when image updates)
make docker-start   # Start services (auto-detects sandbox mode from config.yaml)
make docker-logs    # View logs

make docker-start starts provisioner only when config.yaml uses provisioner mode (sandbox.use: deerflow.community.aio_sandbox:AioSandboxProvider with provisioner_url).

Docker builds use the upstream uv registry by default. If you need faster mirrors in restricted networks, export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple and NPM_REGISTRY=https://registry.npmmirror.com before running make docker-init or make docker-start.

Local AIO sandbox control traffic is always direct: loopback/private addresses, single-label cluster hosts, and Docker/Podman internal hostnames do not inherit HTTP_PROXY or HTTPS_PROXY. External sandbox FQDNs and public IPs still honor environment proxy settings.

Backend processes automatically pick up config.yaml changes on the next config access, so model metadata updates do not require a manual restart during development. The checkpoint storage settings database.checkpoint_channel_mode and database.checkpoint_delta.snapshot_frequency (default 10) are exceptions: both are frozen when the process first builds an agent (including through DeerFlowClient) and require a process restart to change safely.

The optional database.checkpoint_cache section (delta channel mode only) caches materialized checkpoint histories: type is memory (default) or redis, and max_entries: 0 disables the cache. The redis backend is Gateway/async-only; the sync TUI/embedded path supports memory only. The cache is performance-only — results are identical with it disabled — so it is never frozen and workers sharing one checkpoint database may safely run different cache settings.

Tip

On Linux, if Docker-based commands fail with permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock, add your user to the docker group and re-login before retrying. See CONTRIBUTING.md for the full fix.

Production (builds images locally, mounts runtime config and data):

make up     # Build images and start all production services
make down   # Stop and remove containers

Access: http://localhost:2026

For persistent deployments, configure database.backend as sqlite or postgres. The selected backend is shared by the LangGraph checkpointer, LangGraph Store, and DeerFlow application data. The deprecated checkpointer section, when present, overrides the first two for backward compatibility.

The unified nginx endpoint is same-origin by default and does not emit browser CORS headers. If you run a split-origin or port-forwarded browser client, set GATEWAY_CORS_ORIGINS to comma-separated exact origins such as http://localhost:3000; the Gateway then applies the CORS allowlist and matching CSRF origin checks.

Browser login uses HttpOnly session cookies. The login page offers a "keep me signed in" option that extends the browser session when the request is HTTPS (including trusted X-Forwarded-Proto: https) or localhost HTTP. The localhost exception uses the direct request Host and ignores forwarded host headers. Public HTTP deployments, including many temporary sandbox URLs, fall back to session cookies by default. DeerFlow never stores the password in browser storage; the UI may remember only the email address.

DeerFlow still uses Forwarded / X-Forwarded-* headers to recover the browser-facing scheme and origin behind a proxy. The bundled nginx sets X-Forwarded-Proto, but preserves an upstream HTTPS value and does not overwrite every forwarded header. Configure the outer trusted proxy to replace or strip client-supplied forwarding headers before traffic reaches DeerFlow.

Important

The Gateway still owns active run tasks in process, so production defaults to a single Gateway worker (GATEWAY_WORKERS=1). Multi-worker deployments require Postgres, the Redis stream bridge (stream_bridge.type: redis), run_ownership.heartbeat_enabled: true, and run_events.backend: db; process-local memory/JSONL event stores cannot enforce singleton delivery receipts across workers. The bridge shares SSE delivery and bounded Last-Event-ID replay across workers. When a valid reconnect cursor has been trimmed, or a subscriber that already established an empty-stream wait falls behind before its first delivery, Memory and Redis emit a machine-readable SSE gap event instead of silently returning a partial replay; the Web UI reloads durable thread/event state and resumes from the retained tail. Lease reconciliation marks runs from dead workers as errors, persists their delivery receipts, publishes the terminal stream marker, schedules retained-stream cleanup, and updates the affected thread status. SSE and /wait consumers also refresh durable status on heartbeats as a fallback if terminal publication fails. Malformed Redis reconnect IDs live-tail new events instead of replaying the retained buffer, and the rolling retained-buffer TTL (stream_ttl_seconds) remains a cleanup safety net rather than a run timeout. IM channel state and other process-local services still need their own multi-worker coordination.

Run cancellation may land on any Gateway worker. A non-owning worker now persists the interrupt or rollback request for the live owner, which observes it during lease renewal and performs the normal cancellation flow; load-balancer routing alone no longer produces a 409. The first accepted action wins even if a retry lands on the owner, and accepted cancellation competes atomically with owner completion. Dead owners still follow lease takeover and orphan recovery. Cancellation latency is therefore bounded by the lease heartbeat interval.

With lease heartbeat enabled, a transient RunStore renewal error is retried only until the last confirmed lease expires; the stale worker then cancels local execution and suppresses checkpoint, completion-hook, delivery-receipt, and thread-status finalization. A remote tool side effect already in flight may still be outside local cancellation.

Reconciliation uses an atomic takeover claim that re-checks the lease after candidate selection, so a successful owner renewal wins over orphan recovery and only one reconciler can report a run as recovered. When multiple Gateway workers share the Docker/AIO or E2B sandbox backend, also configure sandbox.ownership.type: redis; E2B uses the leases during background startup and periodic reconciliation so duplicate/orphan cleanup cannot terminate a live peer's sandbox.

See CONTRIBUTING.md for detailed Docker development guide.

Option 2: Local Development

If you prefer running services locally:

Prerequisite: complete the "Configuration" steps above first (make setup). make dev requires a valid config.yaml in the project root. Set DEER_FLOW_PROJECT_ROOT to define that root explicitly, or DEER_FLOW_CONFIG_PATH to point at a specific config file. Runtime state defaults to .deer-flow under the project root and can be moved with DEER_FLOW_HOME; skills default to skills/ under the project root and can be moved with DEER_FLOW_SKILLS_PATH. Run make doctor to verify your setup before starting. On Windows, run the local development flow from Git Bash. Native cmd.exe and PowerShell shells are not supported for the bash-based service scripts, and WSL is not guaranteed because some scripts rely on Git for Windows utilities such as cygpath.

  1. Check prerequisites:

    make check  # Verifies Node.js 22+, pnpm, uv, nginx

    The local make check, make install, make dev, and make start entry points use a direct pnpm/pnpm.cmd executable when available and otherwise fall back to corepack pnpm. Corepack runs from frontend/, so it honors the packageManager version pinned in frontend/package.json; enabling a global pnpm shim is not required.

  2. Install dependencies:

    make install  # Install backend + frontend dependencies + pre-commit hooks
  3. (Optional) Pre-pull sandbox image:

    # Recommended if using Docker/Container-based sandbox
    make setup-sandbox
  4. (Optional) Load sample memory data for local review:

    python scripts/load_memory_sample.py

    This copies the sample fixture into the default local runtime memory file so reviewers can immediately test Settings > Memory. See backend/docs/MEMORY_SETTINGS_REVIEW.md for the shortest review flow.

  5. Start services:

    make dev
  6. Access: http://localhost:2026

Startup Modes

DeerFlow runs the agent runtime inside the Gateway API. Development mode enables hot-reload; production mode uses a pre-built frontend.

Local Foreground Local Daemon Docker Dev Docker Prod
Dev ./scripts/serve.sh --dev
make dev
./scripts/serve.sh --dev --daemon
make dev-daemon
./scripts/docker.sh start
make docker-start
Prod ./scripts/serve.sh --prod
make start
./scripts/serve.sh --prod --daemon
make start-daemon
./scripts/deploy.sh
make up
Action Local Docker Dev Docker Prod
Stop ./scripts/serve.sh --stop
make stop
./scripts/docker.sh stop
make docker-stop
./scripts/deploy.sh down
make down
Restart ./scripts/serve.sh --restart [flags] ./scripts/docker.sh restart

Gateway owns /api/langgraph/* and translates those public LangGraph-compatible paths to its native /api/* routers behind nginx.

For workflows that invoke backend/langgraph.json through LangGraph Studio or a direct LangGraph Server, DeerFlow consumes the authenticated identity published by that runtime and uses it for custom-agent configuration/SOUL, user skills and skill policy, uploads, thread data, and memory reads/writes. This keeps authenticated runs out of the shared default filesystem bucket, and the server-owned identity takes precedence over ordinary client-supplied user_id values. External identities such as email addresses are mapped to stable, collision-resistant directory-safe user IDs before accessing DeerFlow storage. The default DeerFlow service topology remains the Gateway-embedded runtime described above.

Gateway runs automatically enforce native delivery for artifacts created or modified under /mnt/user-data/outputs: present_files must present at least one output produced by the current run, and the terminal run.delivery receipt must be durably recorded. Virtual artifact paths are resolved within the same authenticated user and thread scope that produced the output before the output-directory boundary is validated. Runs that do not produce output artifacts keep ordinary conversational behavior.

DeerFlow's built-in custom events are available through both LangGraph streaming interfaces: native clients can continue subscribing to stream_mode="custom", while callback-based integrations can consume the same payloads as on_custom_event records from astream_events(version="v2"). The callback event name matches the payload's type field.

Docker Production Deployment

deploy.sh supports building and starting separately:

# One-step (build + start)
deploy.sh

# Two-step (build once, start later)
deploy.sh build              # build all images
deploy.sh start              # start pre-built images

# Stop
deploy.sh down

Advanced

Sandbox Mode

DeerFlow supports multiple sandbox execution modes:

  • Local Execution (runs sandbox code directly on the host machine)
  • Docker Execution (runs sandbox code in isolated Docker containers)
  • Docker Execution with Kubernetes (runs sandbox code in Kubernetes pods via provisioner service)

For Docker development, service startup follows config.yaml sandbox mode. In Local/Docker modes, provisioner is not started.

See the Sandbox Configuration Guide to configure your preferred mode.

MCP Server

DeerFlow supports configurable MCP servers and skills to extend its capabilities. For HTTP/SSE MCP servers, OAuth token flows are supported (client_credentials, refresh_token). For stdio MCP servers, per-tool call timeouts can be configured with tool_call_timeout. MCP tool names are prefixed with <server_name>_ by default to prevent collisions across servers. If a server already namespaces its own tools, set tool_name_prefix: false on that server in extensions_config.json to keep the original names. Disable the prefix only when the resulting names remain unique across all enabled servers. Settings > Tools updates one MCP server at a time: an invalid stdio command on one server no longer blocks toggling another, while enabling that invalid server remains protected by the command allowlist and surfaces the backend validation message in the UI. Targeted updates accept both DeerFlow's type field and the MCP-spec transport field for SSE/HTTP servers. Runtime MCP and skill updates replace extensions_config.json atomically, so an interrupted write cannot leave the shared configuration truncated or partially written. MCP routing hints can also prefer a specific MCP tool for matching requests without forbidding other tools. When tool_search defers MCP schemas, matching routing metadata can auto-promote up to tool_search.auto_promote_top_k deferred schemas before the model call. See the MCP Server Guide for detailed instructions.

Security: pass per-request MCP credentials only through config.context.secrets; credentials must never be placed in either run metadata surface (metadata.auth_token or config.metadata.auth_token). See MCP credential migration and cleanup for the supported interceptor flow and the required rotation and retained-copy cleanup when migrating from legacy metadata credentials.

IM Channels

DeerFlow supports receiving tasks from messaging apps. Channels auto-start when configured — no public IP required for any of them.

DeerFlow can also expose user-owned IM channel connections in the workspace UI. When channel_connections is enabled, logged-in users can bind Telegram, Slack, Discord, Feishu/Lark, DingTalk, WeChat, or WeCom from the sidebar / Settings > Channels. It reuses the existing outbound channels.* transports, so no public IP or provider callback URL is required. Incoming IM messages then run under the connected DeerFlow user account. See IM Channel Connections for setup and security notes.

Channel Transport Difficulty
Telegram Bot API (long-polling) Easy
Slack Socket Mode Moderate
Feishu / Lark WebSocket Moderate
WeChat Tencent iLink (long-polling) Moderate
WeCom WebSocket Moderate
DingTalk Stream Push (WebSocket) Moderate

Configuration in config.yaml:

channels:
  # LangGraph-compatible Gateway API base URL (default: http://localhost:8001/api)
  langgraph_url: http://localhost:8001/api
  # Gateway API URL (default: http://localhost:8001)
  gateway_url: http://localhost:8001

  # Optional: global session defaults for all mobile channels
  session:
    assistant_id: lead_agent  # or a custom agent name; custom agents are routed via lead_agent + agent_name
    config:
      recursion_limit: 100
    context:
      thinking_enabled: true
      is_plan_mode: false
      subagent_enabled: false

  feishu:
    enabled: true
    app_id: $FEISHU_APP_ID
    app_secret: $FEISHU_APP_SECRET
    # domain: https://open.feishu.cn       # China (default)
    # domain: https://open.larksuite.com   # International

  wecom:
    enabled: true
    bot_id: $WECOM_BOT_ID
    bot_secret: $WECOM_BOT_SECRET

  slack:
    enabled: true
    bot_token: $SLACK_BOT_TOKEN     # xoxb-...
    app_token: $SLACK_APP_TOKEN     # xapp-... (Socket Mode)
    allowed_users: []               # empty = allow all

  telegram:
    enabled: true
    bot_token: $TELEGRAM_BOT_TOKEN
    # Optional: render final Markdown replies as Telegram Rich Messages.
    rich_messages: false
    allowed_users: []               # empty = allow all

  wechat:
    enabled: false
    bot_token: $WECHAT_BOT_TOKEN
    ilink_bot_id: $WECHAT_ILINK_BOT_ID
    qrcode_login_enabled: true      # optional: allow first-time QR bootstrap when bot_token is absent
    allowed_users: []               # empty = allow all
    polling_timeout: 35             # timing values must be positive finite seconds
    polling_retry_delay: 5
    qrcode_poll_interval: 2
    qrcode_poll_timeout: 180
    state_dir: ./.deer-flow/wechat/state
    max_inbound_image_bytes: 20971520
    max_outbound_image_bytes: 20971520
    max_inbound_file_bytes: 52428800
    max_outbound_file_bytes: 52428800

    # Optional: per-channel / per-user session settings
    session:
      assistant_id: mobile-agent  # custom agent names are also supported here
      context:
        thinking_enabled: false
      users:
        "123456789":
          assistant_id: vip-agent
          config:
            recursion_limit: 150
          context:
            thinking_enabled: true
            subagent_enabled: true

  dingtalk:
    enabled: true
    client_id: $DINGTALK_CLIENT_ID             # Client ID of your DingTalk application
    client_secret: $DINGTALK_CLIENT_SECRET     # Client Secret of your DingTalk application
    allowed_users: []                          # empty = allow all
    card_template_id: ""                       # Optional: AI Card template ID for streaming typewriter effect

Notes:

  • assistant_id: lead_agent calls the default LangGraph assistant directly.
  • If assistant_id is set to a custom agent name, DeerFlow still routes through lead_agent and injects that value as agent_name, so the custom agent's SOUL/config takes effect for IM channels.
  • IM channel workers call Gateway's LangGraph-compatible API internally and automatically attach process-local internal auth plus the CSRF cookie/header pair required for thread and run creation.
  • Feishu/Lark now queues rapid follow-up messages per mapped DeerFlow thread_id instead of immediately surfacing the generic busy reply, and topic replies keep a per-message card with a compact source-message preview across queued/running/final patches.

Set the corresponding API keys in your .env file:

# Telegram
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ

# Slack
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...

# Feishu / Lark
FEISHU_APP_ID=cli_xxxx
FEISHU_APP_SECRET=your_app_secret

# WeChat iLink
WECHAT_BOT_TOKEN=your_ilink_bot_token
WECHAT_ILINK_BOT_ID=your_ilink_bot_id

# WeCom
WECOM_BOT_ID=your_bot_id
WECOM_BOT_SECRET=your_bot_secret

# DingTalk
DINGTALK_CLIENT_ID=your_client_id
DINGTALK_CLIENT_SECRET=your_client_secret

Telegram Setup

  1. Chat with @BotFather, send /newbot, and copy the HTTP API token.
  2. Set TELEGRAM_BOT_TOKEN in .env and enable the channel in config.yaml.
  3. The bot accepts inbound text, photos, and documents (with or without captions). Hosted Bot API downloads are limited to 20 MB per attachment.

Slack Setup

  1. Create a Slack App at api.slack.com/apps → Create New App → From scratch.
  2. Under OAuth & Permissions, add Bot Token Scopes: app_mentions:read, chat:write, im:history, im:read, im:write, files:write.
  3. Enable Socket Mode → generate an App-Level Token (xapp-…) with connections:write scope.
  4. Under Event Subscriptions, subscribe to bot events: app_mention, message.im.
  5. Set SLACK_BOT_TOKEN and SLACK_APP_TOKEN in .env and enable the channel in config.yaml.

Feishu / Lark Setup

  1. Create an app on Feishu Open Platform → enable Bot capability.
  2. Add permissions: im:message, im:message.p2p_msg:readonly, im:resource.
  3. Under Events, subscribe to im.message.receive_v1 and select Long Connection mode.
  4. Copy the App ID and App Secret. Set FEISHU_APP_ID and FEISHU_APP_SECRET in .env and enable the channel in config.yaml.

WeChat Setup

  1. Enable the wechat channel in config.yaml.
  2. Either set WECHAT_BOT_TOKEN in .env, or set qrcode_login_enabled: true for first-time QR bootstrap.
  3. When bot_token is absent and QR bootstrap is enabled, watch backend logs for the QR content returned by iLink and complete the binding flow.
  4. After the QR flow succeeds, DeerFlow persists the acquired token under state_dir for later restarts.
  5. For Docker Compose deployments, keep state_dir on a persistent volume so the get_updates_buf cursor and saved auth state survive restarts.

WeCom Setup

  1. Create a bot on the WeCom AI Bot platform and obtain the bot_id and bot_secret.
  2. Enable channels.wecom in config.yaml and fill in bot_id / bot_secret.
  3. Set WECOM_BOT_ID and WECOM_BOT_SECRET in .env.
  4. Make sure backend dependencies include wecom-aibot-python-sdk. The channel uses a WebSocket long connection and does not require a public callback URL.
  5. The current integration supports inbound text, image, and file messages. Final images/files generated by the agent are also sent back to the WeCom conversation.

DingTalk Setup

  1. Create a DingTalk application in the DingTalk Developer Console and enable Robot capability.
  2. Set the message receiving mode to Stream Mode in the robot configuration page.
  3. Copy the Client ID and Client Secret, set DINGTALK_CLIENT_ID and DINGTALK_CLIENT_SECRET in .env, and enable the channel in config.yaml.
  4. (Optional) To enable streaming AI Card replies (typewriter effect), create an AI Card template on the DingTalk Card Platform, then set card_template_id in config.yaml to the template ID. You also need to apply for the Card.Streaming.Write and Card.Instance.Write permissions.

When DeerFlow runs in Docker Compose, IM channels execute inside the gateway container. In that case, do not point channels.langgraph_url or channels.gateway_url at localhost; use container service names such as http://gateway:8001/api and http://gateway:8001, or set DEER_FLOW_CHANNELS_LANGGRAPH_URL and DEER_FLOW_CHANNELS_GATEWAY_URL.

Commands

Once a channel is connected, you can interact with DeerFlow directly from the chat:

Command Description
/new Start a new conversation
/status Show current thread info
/models List available models
/memory View memory
/help Show help

Messages without a command prefix are treated as regular chat — DeerFlow creates a thread and responds conversationally.

Request Trace Correlation

Gateway request trace correlation is disabled by default so existing HTTP responses and log formats stay unchanged. To enable it, set:

logging:
  enhance:
    enabled: true
    format: text

When enabled, every Gateway HTTP response includes X-Trace-Id, logs include trace_id, and Langfuse traces created by that request include metadata.deerflow_trace_id with the same value.

Gateway run history also records one terminal run.delivery receipt per run, including zero-output and crash-recovered runs. The receipt is persisted before the durable terminal run status during normal execution. Orphan recovery first atomically claims an expired lease and then idempotently backfills the receipt, so a stale recovery scan cannot overwrite a live run's detailed delivery facts. Receipt persistence remains best-effort during an event-store outage. Runs that fail checkpoint preflight (or are cancelled while waiting for prior finalization) keep the existing completion-data behavior: they receive the zero-delivery receipt but do not overwrite RunStore completion fields with an empty snapshot.

LangSmith Tracing

DeerFlow has built-in LangSmith integration for observability. When enabled, all LLM calls, agent runs, and tool executions are traced and visible in the LangSmith dashboard.

Add the following to your .env file:

LANGSMITH_TRACING=true
LANGSMITH_ENDPOINT=https://api.smith.langchain.com
LANGSMITH_API_KEY=lsv2_pt_xxxxxxxxxxxxxxxx
LANGSMITH_PROJECT=xxx

Langfuse Tracing

DeerFlow also supports Langfuse observability for LangChain-compatible runs.

Add the following to your .env file:

LANGFUSE_TRACING=true
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxxxxxxxxxx
LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxxxxxxxxxx
LANGFUSE_BASE_URL=https://cloud.langfuse.com

If you are using a self-hosted Langfuse instance, set LANGFUSE_BASE_URL to your deployment URL.

Trace correlation fields. Every agent run is annotated with Langfuse's reserved trace attributes so the Sessions and Users pages light up automatically:

  • session_id = LangGraph thread_id — groups every trace of the same conversation
  • user_id = effective user from get_effective_user_id() (falls back to default in no-auth mode)
  • trace_name = assistant id (defaults to lead-agent)
  • tags = [env:<DEER_FLOW_ENV>, model:<model_name>] (omitted when not set)
  • metadata.deerflow_trace_id = DeerFlow request correlation id, matching X-Trace-Id when request trace correlation is enabled

These are injected into RunnableConfig.metadata at the graph invocation root for both the gateway path (runtime/runs/worker.py::run_agent) and the embedded path (client.py::DeerFlowClient.stream), so any LangChain-compatible callback can read them. Set DEER_FLOW_ENV (or ENVIRONMENT) to tag traces by deployment environment.

Monocle Tracing

DeerFlow also supports Monocle, an OpenTelemetry-based tracer for agentic applications. It records each run end-to-end: LLM calls, agent steps, and tool and MCP invocations, with their inputs, outputs, timings, and token counts.

Add the following to your .env file:

MONOCLE_TRACING=true
MONOCLE_EXPORTERS=file          # file, console, okahu, s3, blob, gcs (default: file)
OKAHU_API_KEY=okh_xxxxxxxx      # required only for the `okahu` exporter

Each run writes one trace file to .monocle/; open it in the Monocle VS Code extension to inspect the span timeline and token counts. Connect to Okahu, an agent-observability platform, to analyze traces across runs and run trace-based and agentic evaluations (via the okahu exporter).

Traces capture span inputs and outputs verbatim — prompts, tool arguments, and model responses — plus token usage and timings. The file exporter keeps them on local disk and never rotates or cleans them up, so prune .monocle/ periodically; the remote exporters (okahu, s3, blob, gcs) send that same data off-box, so enable only destinations you trust. Monocle is initialized once at Gateway startup: a configuration error (unknown exporter, missing OKAHU_API_KEY) is logged there and tracing stays off until the Gateway restarts.

Using Multiple Providers

LangSmith and Langfuse attach as LangChain callbacks, so you can enable both and DeerFlow reports each run to both. If an enabled provider is missing required credentials or fails to initialize, DeerFlow fails fast and names it. Monocle uses a global OpenTelemetry provider rather than a callback; Langfuse shares that provider, so all three can run together. Because both span processors sit on the same shared provider, Monocle's exporters also see Langfuse's spans when both are enabled.

For Docker deployments, tracing is disabled by default. Set LANGSMITH_TRACING=true and LANGSMITH_API_KEY in your .env to enable it.

From Deep Research to Super Agent Harness

DeerFlow started as a Deep Research framework — and the community ran with it. Since launch, developers have pushed it far beyond research: building data pipelines, generating slide decks, spinning up dashboards, automating content workflows. Things we never anticipated.

That told us something important: DeerFlow wasn't just a research tool. It was a harness — a runtime that gives agents the infrastructure to actually get work done.

So we rebuilt it from scratch.

DeerFlow 2.0 is no longer a framework you wire together. It's a super agent harness — batteries included, fully extensible. Built on LangGraph and LangChain, it ships with everything an agent needs out of the box: a filesystem, memory, skills, sandbox-aware execution, and the ability to plan and spawn sub-agents for complex, multi-step tasks.

Use it as-is. Or tear it apart and make it yours.

Core Features

Skills & Tools

Skills are what make DeerFlow do almost anything.

A standard Agent Skill is a structured capability module — a Markdown file that defines a workflow, best practices, and references to supporting resources. DeerFlow ships with built-in skills for research, report generation, slide creation, web pages, image and video generation, and more. But the real power is extensibility: add your own skills, replace the built-in ones, or combine them into compound workflows.

Skills are loaded progressively — only when the task needs them, not all at once. This keeps the context window lean and makes DeerFlow work well even with token-sensitive models.

A skill directory is a package boundary: once DeerFlow finds its SKILL.md, nested SKILL.md files under that package (for example evaluation fixtures) remain supporting data and are not registered as runtime skills. Namespace directories without their own SKILL.md can still group nested skills.

Users can explicitly activate an enabled skill for a single turn by starting the request with /skill-name, for example /data-analysis analyze uploads/foo.csv. DeerFlow loads that skill's SKILL.md as hidden current-turn context while leaving the base prompt limited to skill metadata. Slash activation respects disabled skills, custom-agent skill whitelists, and existing channel commands such as /new and /help.

An enabled skill's allowed-tools policy applies only after that skill is explicitly slash-activated or captured in the agent's active skill context after a read_file load. Merely enabling, advertising, or listing a skill in a custom agent or subagent skills allowlist does not reduce that agent's normal toolset; subagents use the same progressive discovery and activation policy as the lead agent. During a slash-activated run, that explicit skill's policy is authoritative: reading another SKILL.md may provide instructions but cannot widen the slash skill's tools. Without slash activation, policies from skills actually loaded into active context retain their union semantics. Once active, the policy filters both model-visible tool schemas and tool execution. Framework discovery tools (tool_search and describe_skill) remain available so an allowed deferred tool or installed skill can still be discovered, but discovery and promotion never grant permission to execute a business tool omitted from allowed-tools. task is not framework-exempt; a restrictive skill must list it explicitly to delegate to a subagent. Per-step policy decisions are internal runtime context and are removed from observable or persisted context copies. Registry failures and an active set with no remaining valid skill fail closed to framework-safe tools; individual stale paths are ignored only when another valid active skill remains. This is best-effort behavioral scoping, not a hard security boundary: loading skill instructions through another tool is not captured, and active-skill entries can be evicted from bounded context.

When you install .skill archives through the Gateway, DeerFlow accepts standard optional frontmatter metadata such as version, author, and compatibility instead of rejecting otherwise valid external skills.

Disabling a skill also removes it from the sandbox filesystem view, so shell commands and structured file tools follow the same enabled state. Local, Docker/AIO, hostPath provisioner, and newly created E2B sandboxes source /mnt/skills from enabled-only projections that update when public, custom, legacy, or managed integration skills are toggled, edited, created, deleted, or installed. Managed integration packages remain shared, while their projected filesystem visibility follows each user's enabled state. Multi-worker Gateways re-read on-disk enable state while rebuilding user projections, so a toggle handled by one worker is honored by another worker's next sandbox acquire. Existing E2B sandboxes retain their creation-time snapshot until they are recreated. PVC-backed provisioner skills keep their configured PVC snapshot/layout for now; dynamic PVC materialization is tracked separately.

Managed integrations install shared read-only skill packs without mixing them into custom skills. The Lark/Feishu CLI integration is available under Settings → Integrations → Lark / Feishu CLI; an administrator installs or upgrades the official lark-* pack once under {DEER_FLOW_HOME}/integrations/skills/lark-cli, and every user discovers that same pack with an independent enabled state. Each user's app configuration and OAuth data remain isolated under {DEER_FLOW_HOME}/users/{user_id}/integrations/lark-cli/{config,data}. These secret directories are restricted to 0700, regular credential files to 0600, and symlinks are rejected.

After installation, users can click Connect Lark to open a browser authorization link; no terminal authorization is required. The same UI can request additional permission domains such as Calendar, Docs, or Drive, or a specific OAuth scope reported by lark-cli. A cheap status refresh only inspects the local credential tree, so the UI reports Credentials configured (not live-verified) until an explicit browser completion performs live token verification. The action then remains Reconnect Lark so users can replace or extend authorization. If an agent hits missing Lark authorization during a conversation, the managed lark-shared guidance points the user back to the same settings entry with ?settings=integrations.

Installing the Lark skill pack resolves the latest official larksuite/cli release from GitHub and downloads that version's skills at install time, so the Gateway needs outbound internet access for that step (it falls back to a bottom-line pinned version if the release lookup fails). The settings page shows the installed version and, when available, the newest published version so an admin can reinstall to upgrade. Air-gapped deployments can pre-stage the archive and point DEER_FLOW_LARK_CLI_SKILLS_ARCHIVE at the local file. Integrity does not depend on a pinned archive byte hash (GitHub does not guarantee stable source-archive bytes); instead the download is restricted to the official GitHub host, every archive member passes structural safety guards, and a content hash of the effective installed skill tree (including DeerFlow's injected shared guidance) is recorded so content changes are auditable across reinstalls.

When sandbox.use selects the AIO provider, the same install also downloads the official Linux amd64 and arm64 CLI release archives, verifies their published SHA-256 checksums, safely extracts one executable per architecture, and mounts the resulting runtime read-only at /mnt/integrations/lark-cli/runtime. An architecture-selecting launcher in that mount makes lark-cli available in the sandbox PATH. Air-gapped AIO deployments can pre-stage a symlink-free runtime tree containing bin/lark-cli plus both linux-{amd64,arm64}/lark-cli files and set DEER_FLOW_LARK_CLI_SANDBOX_RUNTIME_DIR to that directory.

Sandbox trust boundary: the browser never receives the Lark app secret, but agent conversations run lark-cli inside the sandbox, so the per-user credential directories are mounted into it: config (holding the long-lived appSecret) is mounted read-only and data (refreshable OAuth tokens) writable. Both remain readable by any process the agent runs there, so code reached via prompt injection in a tool result could read them. Treat the sandbox as inside the Lark credential trust boundary until the sidecar credential-broker follow-up removes these mounts from sandbox execution.

For remote/Kubernetes deployments (the provisioner backend), the sandbox lark-cli runtime can instead be supplied by an optional init container that copies the binaries into a shared emptyDir — no install-time GitHub download and no hostPath/PVC runtime mount. Publish the image under docker/lark-cli-init and set LARK_CLI_INIT_IMAGE on the provisioner; it stays off (legacy behavior) when unset. The Lark integration status (GET /api/integrations/lark/status) reports sandbox_runtime_mode and sandbox_runtime_ready so the Settings UI shows whether lark-cli will actually be present in the sandbox at chat time, rather than a green status hiding a later command not found.

If a trusted operator manages the configured skills directory through an external mount such as MinIO, NFS, or CSI, an administrator can call POST /api/skills/reload after changing files. This invalidates skill prompt caches for the current Gateway process and waits up to the bounded refresh timeout so subsequent runs rescan the latest files; running tasks are unchanged. A loader-level filesystem failure returns a generic server error and preserves the last successfully loaded process cache rather than publishing an empty catalog. Uvicorn workers and Kubernetes Pods must each be targeted separately. Direct mount writes bypass the validation, SkillScan, and history applied by DeerFlow's install/edit APIs, so only operator-controlled systems should have write access.

Skill installs and agent-managed skill edits run through SkillScan, a native deterministic safety scanner before the LLM-based skill scanner. Phase 1 runs offline with no Semgrep/OpenGrep dependency, blocks high-confidence CRITICAL findings such as private keys or shell execution, and passes warning findings to the LLM scanner for contextual review. Python instance-client exfiltration checks follow a minimal same-scope evidence chain: a simple name bound to a known client constructor, optional name-to-name aliases, and an actual outbound method or context-manager use supported by that constructor. Constructor roots must be proven imports; bare canonical-looking names are not inferred as modules. Nested scopes do not inherit client handles and inherit only constructor import aliases that are never rebound in the enclosing scope. Comprehensions, walrus-bearing statements, annotations, complex binding targets, unsupported operations, and ambiguous branch flows produce no finding from this signal; skipped constructs conservatively invalidate every name they may bind so stale client state cannot create a finding. A deterministic work budget or recursion limit reached by this best-effort analysis does not discard find

(README truncated)

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

1 total
  1. DeerFlow 2.0.0 releasedv2.0.0Jun 25, 2026

    # DeerFlow 2.0.0 DeerFlow 2.0 is a **ground-up rewrite** around a "super agent" harness that orchestrates **sub-agents**, **persistent memory**, **sandboxed execution**, and an extensible **skills/tools** system. It shares no code with the 1.x line, which lives on the [`main-1.x` branch](https://github.com/bytedance/deer-flow/tree/main-1.x). This release closes the [2.0.0 milestone](https://github.com/bytedance/deer-flow/milestone/1) with **182 merged PRs** since the first 2.0 milestone tag. > 📖 Full notes: [CHANGELOG.md](CHANGELOG.md) · [中文版](CHANGELOG_zh.md) --- ## ⚠️ Breaking change - **Run hydration** — runs now hydrate from `RunStore` and persist `interrupted` status. Cancellation now requires the worker who owns the run; cross-worker cancels return `409` instead of silently appearing successful. ([#2932]) ## ✨ Highlights - **Custom agents that update themselves** — agents can persist edits to their own `SOUL.md` / `config.yaml` from a normal chat, with full per-user isolation. ([#2713]) - **User-owned IM channel connections** — users can bind their own Slack, Telegram, Discord, Feishu/Lark, DingTalk, WeChat, and WeCom accounts on t

Commits per week

last 52 weeks
2270Week of 2025-08-10: 3 commitsWeek of 2025-08-17: 9 commitsWeek of 2025-08-24: 0 commitsWeek of 2025-08-31: 4 commitsWeek of 2025-09-07: 10 commitsWeek of 2025-09-14: 5 commitsWeek of 2025-09-21: 6 commitsWeek of 2025-09-28: 0 commitsWeek of 2025-10-05: 3 commitsWeek of 2025-10-12: 11 commitsWeek of 2025-10-19: 23 commitsWeek of 2025-10-26: 12 commitsWeek of 2025-11-02: 1 commitsWeek of 2025-11-09: 2 commitsWeek of 2025-11-16: 5 commitsWeek of 2025-11-23: 13 commitsWeek of 2025-11-30: 7 commitsWeek of 2025-12-07: 6 commitsWeek of 2025-12-14: 6 commitsWeek of 2025-12-21: 10 commitsWeek of 2025-12-28: 3 commitsWeek of 2026-01-04: 9 commitsWeek of 2026-01-11: 166 commitsWeek of 2026-01-18: 208 commitsWeek of 2026-01-25: 166 commitsWeek of 2026-02-01: 227 commitsWeek of 2026-02-08: 114 commitsWeek of 2026-02-15: 8 commitsWeek of 2026-02-22: 21 commitsWeek of 2026-03-01: 30 commitsWeek of 2026-03-08: 47 commitsWeek of 2026-03-15: 26 commitsWeek of 2026-03-22: 83 commitsWeek of 2026-03-29: 91 commitsWeek of 2026-04-05: 86 commitsWeek of 2026-04-12: 44 commitsWeek of 2026-04-19: 37 commitsWeek of 2026-04-26: 59 commitsWeek of 2026-05-03: 40 commitsWeek of 2026-05-10: 35 commitsWeek of 2026-05-17: 46 commitsWeek of 2026-05-24: 29 commitsWeek of 2026-05-31: 22 commitsWeek of 2026-06-07: 70 commitsWeek of 2026-06-14: 57 commitsWeek of 2026-06-21: 66 commitsWeek of 2026-06-28: 63 commitsWeek of 2026-07-05: 87 commitsWeek of 2026-07-12: 113 commitsWeek of 2026-07-19: 110 commitsWeek of 2026-07-26: 120 commitsWeek of 2026-08-02: 18 commitsAug 10, 2025Aug 2, 2026
2.4K commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 11 commitsSun 1:00 — 0 commitsSun 2:00 — 0 commitsSun 3:00 — 1 commitsSun 4:00 — 3 commitsSun 5:00 — 3 commitsSun 6:00 — 2 commitsSun 7:00 — 12 commitsSun 8:00 — 14 commitsSun 9:00 — 22 commitsSun 10:00 — 28 commitsSun 11:00 — 38 commitsSun 12:00 — 7 commitsSun 13:00 — 10 commitsSun 14:00 — 10 commitsSun 15:00 — 19 commitsSun 16:00 — 14 commitsSun 17:00 — 20 commitsSun 18:00 — 6 commitsSun 19:00 — 19 commitsSun 20:00 — 24 commitsSun 21:00 — 41 commitsSun 22:00 — 54 commitsSun 23:00 — 28 commitsMon 0:00 — 8 commitsMon 1:00 — 2 commitsMon 2:00 — 2 commitsMon 3:00 — 9 commitsMon 4:00 — 2 commitsMon 5:00 — 1 commitsMon 6:00 — 5 commitsMon 7:00 — 17 commitsMon 8:00 — 19 commitsMon 9:00 — 35 commitsMon 10:00 — 16 commitsMon 11:00 — 22 commitsMon 12:00 — 15 commitsMon 13:00 — 16 commitsMon 14:00 — 30 commitsMon 15:00 — 20 commitsMon 16:00 — 28 commitsMon 17:00 — 19 commitsMon 18:00 — 12 commitsMon 19:00 — 19 commitsMon 20:00 — 18 commitsMon 21:00 — 23 commitsMon 22:00 — 20 commitsMon 23:00 — 21 commitsTue 0:00 — 8 commitsTue 1:00 — 1 commitsTue 2:00 — 1 commitsTue 3:00 — 2 commitsTue 4:00 — 2 commitsTue 5:00 — 1 commitsTue 6:00 — 1 commitsTue 7:00 — 10 commitsTue 8:00 — 20 commitsTue 9:00 — 34 commitsTue 10:00 — 23 commitsTue 11:00 — 31 commitsTue 12:00 — 8 commitsTue 13:00 — 28 commitsTue 14:00 — 18 commitsTue 15:00 — 16 commitsTue 16:00 — 12 commitsTue 17:00 — 15 commitsTue 18:00 — 17 commitsTue 19:00 — 17 commitsTue 20:00 — 10 commitsTue 21:00 — 18 commitsTue 22:00 — 38 commitsTue 23:00 — 38 commitsWed 0:00 — 2 commitsWed 1:00 — 3 commitsWed 2:00 — 3 commitsWed 3:00 — 4 commitsWed 4:00 — 2 commitsWed 5:00 — 1 commitsWed 6:00 — 5 commitsWed 7:00 — 26 commitsWed 8:00 — 25 commitsWed 9:00 — 37 commitsWed 10:00 — 39 commitsWed 11:00 — 17 commitsWed 12:00 — 13 commitsWed 13:00 — 12 commitsWed 14:00 — 24 commitsWed 15:00 — 11 commitsWed 16:00 — 26 commitsWed 17:00 — 12 commitsWed 18:00 — 6 commitsWed 19:00 — 17 commitsWed 20:00 — 13 commitsWed 21:00 — 25 commitsWed 22:00 — 23 commitsWed 23:00 — 29 commitsThu 0:00 — 7 commitsThu 1:00 — 9 commitsThu 2:00 — 2 commitsThu 3:00 — 2 commitsThu 4:00 — 4 commitsThu 5:00 — 2 commitsThu 6:00 — 1 commitsThu 7:00 — 11 commitsThu 8:00 — 23 commitsThu 9:00 — 30 commitsThu 10:00 — 17 commitsThu 11:00 — 38 commitsThu 12:00 — 20 commitsThu 13:00 — 23 commitsThu 14:00 — 32 commitsThu 15:00 — 40 commitsThu 16:00 — 37 commitsThu 17:00 — 27 commitsThu 18:00 — 12 commitsThu 19:00 — 11 commitsThu 20:00 — 12 commitsThu 21:00 — 16 commitsThu 22:00 — 19 commitsThu 23:00 — 26 commitsFri 0:00 — 4 commitsFri 1:00 — 1 commitsFri 2:00 — 1 commitsFri 3:00 — 1 commitsFri 4:00 — 2 commitsFri 5:00 — 2 commitsFri 6:00 — 2 commitsFri 7:00 — 12 commitsFri 8:00 — 17 commitsFri 9:00 — 32 commitsFri 10:00 — 21 commitsFri 11:00 — 23 commitsFri 12:00 — 2 commitsFri 13:00 — 13 commitsFri 14:00 — 49 commitsFri 15:00 — 46 commitsFri 16:00 — 35 commitsFri 17:00 — 28 commitsFri 18:00 — 15 commitsFri 19:00 — 17 commitsFri 20:00 — 19 commitsFri 21:00 — 48 commitsFri 22:00 — 50 commitsFri 23:00 — 23 commitsSat 0:00 — 13 commitsSat 1:00 — 0 commitsSat 2:00 — 4 commitsSat 3:00 — 2 commitsSat 4:00 — 0 commitsSat 5:00 — 3 commitsSat 6:00 — 4 commitsSat 7:00 — 4 commitsSat 8:00 — 15 commitsSat 9:00 — 21 commitsSat 10:00 — 25 commitsSat 11:00 — 29 commitsSat 12:00 — 4 commitsSat 13:00 — 6 commitsSat 14:00 — 9 commitsSat 15:00 — 25 commitsSat 16:00 — 37 commitsSat 17:00 — 33 commitsSat 18:00 — 38 commitsSat 19:00 — 25 commitsSat 20:00 — 21 commitsSat 21:00 — 41 commitsSat 22:00 — 65 commitsSat 23:00 — 34 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.
DateListRankStars gained
Aug 3, 2026daily#14+209
Aug 2, 2026daily#14+209
Jun 23, 2026daily#17+7
Jun 22, 2026daily#20+13
Mar 30, 2026daily#8+199
Mar 29, 2026daily#12+224
Mar 28, 2026daily#11+190
Mar 27, 2026daily#5+236
Mar 26, 2026daily#5+238
Mar 25, 2026daily#1+407
Mar 24, 2026daily#1+532
Mar 23, 2026daily#3+423
Mar 22, 2026daily#4+594
Mar 11, 2026daily#17+138
Mar 10, 2026daily#14+196
  • public-apis/public-apis

    A collective list of free APIs

    454.9K stars · Python

  • freeCodeCamp/freeCodeCamp

    freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.

    453.6K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    385.5K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript