File size: 9,923 Bytes
033ca06
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# Contributing to DeerFlow Backend

Thank you for your interest in contributing to DeerFlow! This document provides guidelines and instructions for contributing to the backend codebase.

## Table of Contents

- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [Project Structure](#project-structure)
- [Code Style](#code-style)
- [Making Changes](#making-changes)
- [Testing](#testing)
- [Pull Request Process](#pull-request-process)
- [Architecture Guidelines](#architecture-guidelines)

## Getting Started

### Prerequisites

- Python 3.12 or higher
- [uv](https://docs.astral.sh/uv/) package manager
- Git
- Docker (optional, for Docker sandbox testing)

### Fork and Clone

1. Fork the repository on GitHub
2. Clone your fork locally:
   ```bash
   git clone https://github.com/YOUR_USERNAME/deer-flow.git
   cd deer-flow
   ```

## Development Setup

### Install Dependencies

```bash
# From project root
cp config.example.yaml config.yaml

# Install backend dependencies
cd backend
make install
```

### Configure Environment

Set up your API keys for testing:

```bash
export OPENAI_API_KEY="your-api-key"
# Add other keys as needed
```

### Run the Development Server

```bash
# Terminal 1: LangGraph server
make dev

# Terminal 2: Gateway API
make gateway
```

## Project Structure

```
backend/src/
β”œβ”€β”€ agents/                  # Agent system
β”‚   β”œβ”€β”€ lead_agent/         # Main agent implementation
β”‚   β”‚   └── agent.py        # Agent factory and creation
β”‚   β”œβ”€β”€ middlewares/        # Agent middlewares
β”‚   β”‚   β”œβ”€β”€ thread_data_middleware.py
β”‚   β”‚   β”œβ”€β”€ sandbox_middleware.py
β”‚   β”‚   β”œβ”€β”€ title_middleware.py
β”‚   β”‚   β”œβ”€β”€ uploads_middleware.py
β”‚   β”‚   β”œβ”€β”€ view_image_middleware.py
β”‚   β”‚   └── clarification_middleware.py
β”‚   └── thread_state.py     # Thread state definition
β”‚
β”œβ”€β”€ gateway/                 # FastAPI Gateway
β”‚   β”œβ”€β”€ app.py              # FastAPI application
β”‚   └── routers/            # Route handlers
β”‚       β”œβ”€β”€ models.py       # /api/models endpoints
β”‚       β”œβ”€β”€ mcp.py          # /api/mcp endpoints
β”‚       β”œβ”€β”€ skills.py       # /api/skills endpoints
β”‚       β”œβ”€β”€ artifacts.py    # /api/threads/.../artifacts
β”‚       └── uploads.py      # /api/threads/.../uploads
β”‚
β”œβ”€β”€ sandbox/                 # Sandbox execution
β”‚   β”œβ”€β”€ __init__.py         # Sandbox interface
β”‚   β”œβ”€β”€ local.py            # Local sandbox provider
β”‚   └── tools.py            # Sandbox tools (bash, file ops)
β”‚
β”œβ”€β”€ tools/                   # Agent tools
β”‚   └── builtins/           # Built-in tools
β”‚       β”œβ”€β”€ present_file_tool.py
β”‚       β”œβ”€β”€ ask_clarification_tool.py
β”‚       └── view_image_tool.py
β”‚
β”œβ”€β”€ mcp/                     # MCP integration
β”‚   └── manager.py          # MCP server management
β”‚
β”œβ”€β”€ models/                  # Model system
β”‚   └── factory.py          # Model factory
β”‚
β”œβ”€β”€ skills/                  # Skills system
β”‚   └── loader.py           # Skills loader
β”‚
β”œβ”€β”€ config/                  # Configuration
β”‚   β”œβ”€β”€ app_config.py       # Main app config
β”‚   β”œβ”€β”€ extensions_config.py # Extensions config
β”‚   └── summarization_config.py
β”‚
β”œβ”€β”€ community/               # Community tools
β”‚   β”œβ”€β”€ tavily/             # Tavily web search
β”‚   β”œβ”€β”€ jina/               # Jina web fetch
β”‚   β”œβ”€β”€ firecrawl/          # Firecrawl scraping
β”‚   └── aio_sandbox/        # Docker sandbox
β”‚
β”œβ”€β”€ reflection/              # Dynamic loading
β”‚   └── __init__.py         # Module resolution
β”‚
└── utils/                   # Utilities
    └── __init__.py
```

## Code Style

### Linting and Formatting

We use `ruff` for both linting and formatting:

```bash
# Check for issues
make lint

# Auto-fix and format
make format
```

### Style Guidelines

- **Line length**: 240 characters maximum
- **Python version**: 3.12+ features allowed
- **Type hints**: Use type hints for function signatures
- **Quotes**: Double quotes for strings
- **Indentation**: 4 spaces (no tabs)
- **Imports**: Group by standard library, third-party, local

### Docstrings

Use docstrings for public functions and classes:

```python
def create_chat_model(name: str, thinking_enabled: bool = False) -> BaseChatModel:
    """Create a chat model instance from configuration.

    Args:
        name: The model name as defined in config.yaml
        thinking_enabled: Whether to enable extended thinking

    Returns:
        A configured LangChain chat model instance

    Raises:
        ValueError: If the model name is not found in configuration
    """
    ...
```

## Making Changes

### Branch Naming

Use descriptive branch names:

- `feature/add-new-tool` - New features
- `fix/sandbox-timeout` - Bug fixes
- `docs/update-readme` - Documentation
- `refactor/config-system` - Code refactoring

### Commit Messages

Write clear, concise commit messages:

```
feat: add support for Claude 3.5 model

- Add model configuration in config.yaml
- Update model factory to handle Claude-specific settings
- Add tests for new model
```

Prefix types:
- `feat:` - New feature
- `fix:` - Bug fix
- `docs:` - Documentation
- `refactor:` - Code refactoring
- `test:` - Tests
- `chore:` - Build/config changes

## Testing

### Running Tests

```bash
uv run pytest
```

### Writing Tests

Place tests in the `tests/` directory mirroring the source structure:

```
tests/
β”œβ”€β”€ test_models/
β”‚   └── test_factory.py
β”œβ”€β”€ test_sandbox/
β”‚   └── test_local.py
└── test_gateway/
    └── test_models_router.py
```

Example test:

```python
import pytest
from src.models.factory import create_chat_model

def test_create_chat_model_with_valid_name():
    """Test that a valid model name creates a model instance."""
    model = create_chat_model("gpt-4")
    assert model is not None

def test_create_chat_model_with_invalid_name():
    """Test that an invalid model name raises ValueError."""
    with pytest.raises(ValueError):
        create_chat_model("nonexistent-model")
```

## Pull Request Process

### Before Submitting

1. **Ensure tests pass**: `uv run pytest`
2. **Run linter**: `make lint`
3. **Format code**: `make format`
4. **Update documentation** if needed

### PR Description

Include in your PR description:

- **What**: Brief description of changes
- **Why**: Motivation for the change
- **How**: Implementation approach
- **Testing**: How you tested the changes

### Review Process

1. Submit PR with clear description
2. Address review feedback
3. Ensure CI passes
4. Maintainer will merge when approved

## Architecture Guidelines

### Adding New Tools

1. Create tool in `src/tools/builtins/` or `src/community/`:

```python
# src/tools/builtins/my_tool.py
from langchain_core.tools import tool

@tool
def my_tool(param: str) -> str:
    """Tool description for the agent.

    Args:
        param: Description of the parameter

    Returns:
        Description of return value
    """
    return f"Result: {param}"
```

2. Register in `config.yaml`:

```yaml
tools:
  - name: my_tool
    group: my_group
    use: src.tools.builtins.my_tool:my_tool
```

### Adding New Middleware

1. Create middleware in `src/agents/middlewares/`:

```python
# src/agents/middlewares/my_middleware.py
from langchain.agents.middleware import BaseMiddleware
from langchain_core.runnables import RunnableConfig

class MyMiddleware(BaseMiddleware):
    """Middleware description."""

    def transform_state(self, state: dict, config: RunnableConfig) -> dict:
        """Transform the state before agent execution."""
        # Modify state as needed
        return state
```

2. Register in `src/agents/lead_agent/agent.py`:

```python
middlewares = [
    ThreadDataMiddleware(),
    SandboxMiddleware(),
    MyMiddleware(),  # Add your middleware
    TitleMiddleware(),
    ClarificationMiddleware(),
]
```

### Adding New API Endpoints

1. Create router in `src/gateway/routers/`:

```python
# src/gateway/routers/my_router.py
from fastapi import APIRouter

router = APIRouter(prefix="/my-endpoint", tags=["my-endpoint"])

@router.get("/")
async def get_items():
    """Get all items."""
    return {"items": []}

@router.post("/")
async def create_item(data: dict):
    """Create a new item."""
    return {"created": data}
```

2. Register in `src/gateway/app.py`:

```python
from src.gateway.routers import my_router

app.include_router(my_router.router)
```

### Configuration Changes

When adding new configuration options:

1. Update `src/config/app_config.py` with new fields
2. Add default values in `config.example.yaml`
3. Document in `docs/CONFIGURATION.md`

### MCP Server Integration

To add support for a new MCP server:

1. Add configuration in `extensions_config.json`:

```json
{
  "mcpServers": {
    "my-server": {
      "enabled": true,
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@my-org/mcp-server"],
      "description": "My MCP Server"
    }
  }
}
```

2. Update `extensions_config.example.json` with the new server

### Skills Development

To create a new skill:

1. Create directory in `skills/public/` or `skills/custom/`:

```
skills/public/my-skill/
└── SKILL.md
```

2. Write `SKILL.md` with YAML front matter:

```markdown
---
name: My Skill
description: What this skill does
license: MIT
allowed-tools:
  - read_file
  - write_file
  - bash
---

# My Skill

Instructions for the agent when this skill is enabled...
```

## Questions?

If you have questions about contributing:

1. Check existing documentation in `docs/`
2. Look for similar issues or PRs on GitHub
3. Open a discussion or issue on GitHub

Thank you for contributing to DeerFlow!