Initial commit: hardened DeerFlow factory

Vendored deer-flow upstream (bytedance/deer-flow) plus prompt-injection
hardening:

- New deerflow.security package: content_delimiter, html_cleaner,
  sanitizer (8 layers — invisible chars, control chars, symbols, NFC,
  PUA, tag chars, horizontal whitespace collapse with newline/tab
  preservation, length cap)
- New deerflow.community.searx package: web_search, web_fetch,
  image_search backed by a private SearX instance, every external
  string sanitized and wrapped in <<<EXTERNAL_UNTRUSTED_CONTENT>>>
  delimiters
- All native community web providers (ddg_search, tavily, exa,
  firecrawl, jina_ai, infoquest, image_search) replaced with hard-fail
  stubs that raise NativeWebToolDisabledError at import time, so a
  misconfigured tool.use path fails loud rather than silently falling
  back to unsanitized output
- Native client back-doors (jina_client.py, infoquest_client.py)
  stubbed too
- Native-tool tests quarantined under tests/_disabled_native/
  (collect_ignore_glob via local conftest.py)
- Sanitizer Layer 7 fix: only collapse horizontal whitespace, preserve
  newlines and tabs so list/table structure survives
- Hardened runtime config.yaml references only the searx-backed tools
- Factory overlay (backend/) kept in sync with deer-flow tree as a
  reference / source

See HARDENING.md for the full audit trail and verification steps.
This commit is contained in:
2026-04-12 14:23:57 +02:00
commit 6de0bf9f5b
889 changed files with 173052 additions and 0 deletions

214
config.yaml Normal file
View File

@@ -0,0 +1,214 @@
# ============================================================================
# DeerFlow Configuration - Hardened with Prompt Injection Protection
# ============================================================================
# This config uses OpenClaw-style hardened web search/fetch with SearX
# and Ollama Cloud for LLM inference.
config_version: 6
# ============================================================================
# Logging
# ============================================================================
log_level: info
# ============================================================================
# Token Usage Tracking
# ============================================================================
token_usage:
enabled: true
# ============================================================================
# Models Configuration - Ollama Cloud
# ============================================================================
models:
# Primary model: Ollama Cloud (Kimi K2.5)
- name: kimi-k2.5
display_name: Kimi K2.5 (Ollama Cloud)
use: langchain_ollama:ChatOllama
model: ollama-cloud/kimi-k2.5
base_url: https://api.ollama.cloud/v1
api_key: $OLLAMA_CLOUD_API_KEY
num_predict: 8192
temperature: 0.7
reasoning: true
supports_thinking: true
supports_vision: true
# Fallback: Lightweight model for summarization/titles
- name: qwen2.5
display_name: Qwen 2.5 (Ollama Cloud)
use: langchain_ollama:ChatOllama
model: ollama-cloud/qwen2.5
base_url: https://api.ollama.cloud/v1
api_key: $OLLAMA_CLOUD_API_KEY
num_predict: 4096
temperature: 0.7
supports_thinking: false
supports_vision: false
# ============================================================================
# Tool Groups
# ============================================================================
tool_groups:
- name: web
- name: file:read
- name: file:write
- name: bash
# ============================================================================
# Tools Configuration - Hardened SearX
# ============================================================================
# NOTE: These use OpenClaw-style hardening with prompt injection protection.
# The searx_url points to the private SearX instance.
tools:
# Hardened web search with prompt injection protection
- name: web_search
group: web
use: deerflow.community.searx.tools:web_search_tool
searx_url: http://10.67.67.1:8888
max_results: 10
# Hardened web fetch with HTML sanitization
- name: web_fetch
group: web
use: deerflow.community.searx.tools:web_fetch_tool
max_chars: 10000
# Image search via SearX
- name: image_search
group: web
use: deerflow.community.searx.tools:image_search_tool
max_results: 5
# File operations (standard)
- name: ls
group: file:read
use: deerflow.sandbox.tools:ls_tool
- name: read_file
group: file:read
use: deerflow.sandbox.tools:read_file_tool
- name: glob
group: file:read
use: deerflow.sandbox.tools:glob_tool
max_results: 200
- name: grep
group: file:read
use: deerflow.sandbox.tools:grep_tool
max_results: 100
- name: write_file
group: file:write
use: deerflow.sandbox.tools:write_file_tool
- name: str_replace
group: file:write
use: deerflow.sandbox.tools:str_replace_tool
# Bash execution (disabled by default for security)
# Uncomment only if using Docker sandbox or trusted environment
# - name: bash
# group: bash
# use: deerflow.sandbox.tools:bash_tool
# ============================================================================
# Guardrails Configuration (Additional Security Layer)
# ============================================================================
# Blocks dangerous tool calls before execution.
# See: backend/docs/GUARDRAILS.md
guardrails:
enabled: true
provider:
use: deerflow.guardrails.builtin:AllowlistProvider
config:
# Deny potentially dangerous tools
denied_tools: []
# Or use allowlist approach (only these allowed):
# allowed_tools: ["web_search", "web_fetch", "image_search", "read_file", "write_file", "ls", "glob", "grep"]
# ============================================================================
# Sandbox Configuration
# ============================================================================
# For production, use Docker sandbox. For local dev, local sandbox is fine.
sandbox:
use: deerflow.sandbox.local:LocalSandboxProvider
# Host bash is disabled by default for security
allow_host_bash: false
# Optional: Mount additional directories
# mounts:
# - host_path: /home/user/projects
# container_path: /mnt/projects
# read_only: false
# Tool output truncation limits
bash_output_max_chars: 20000
read_file_output_max_chars: 50000
ls_output_max_chars: 20000
# ============================================================================
# Skills Configuration
# ============================================================================
skills:
container_path: /mnt/skills
# ============================================================================
# Title Generation
# ============================================================================
title:
enabled: true
max_words: 6
max_chars: 60
model_name: qwen2.5 # Use lightweight model
# ============================================================================
# Summarization
# ============================================================================
summarization:
enabled: true
model_name: qwen2.5 # Use lightweight model
trigger:
- type: tokens
value: 15564
keep:
type: messages
value: 10
trim_tokens_to_summarize: 15564
# ============================================================================
# Memory Configuration
# ============================================================================
memory:
enabled: true
storage_path: memory.json
debounce_seconds: 30
model_name: qwen2.5
max_facts: 100
fact_confidence_threshold: 0.7
injection_enabled: true
max_injection_tokens: 2000
# ============================================================================
# Skill Self-Evolution (Disabled for security)
# ============================================================================
skill_evolution:
enabled: false
# ============================================================================
# Checkpointer Configuration
# ============================================================================
checkpointer:
type: sqlite
connection_string: checkpoints.db
# ============================================================================
# IM Channels (Disabled by default)
# ============================================================================
# Uncomment and configure if needed
# channels:
# langgraph_url: http://localhost:2024
# gateway_url: http://localhost:8001