mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-03 06:12:14 +08:00
* fix(config): reload AppConfig when config path or mtime changes - Track resolved path + mtime; invalidate cache on change - Preserve set_app_config() injection behavior - Add regression tests (test_app_config_reload.py) - Document behavior in README and backend/CLAUDE.md Signed-off-by: Gao Mingfei <g199209@gmail.com> * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Gao Mingfei <g199209@gmail.com> Co-authored-by: Willem Jiang <willem.jiang@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
from deerflow.config.app_config import get_app_config, reset_app_config
|
|
|
|
|
|
def _write_config(path: Path, *, model_name: str, supports_thinking: bool) -> None:
|
|
path.write_text(
|
|
yaml.safe_dump(
|
|
{
|
|
"sandbox": {"use": "deerflow.sandbox.local:LocalSandboxProvider"},
|
|
"models": [
|
|
{
|
|
"name": model_name,
|
|
"use": "langchain_openai:ChatOpenAI",
|
|
"model": "gpt-test",
|
|
"supports_thinking": supports_thinking,
|
|
}
|
|
],
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
|
|
def _write_extensions_config(path: Path) -> None:
|
|
path.write_text(json.dumps({"mcpServers": {}, "skills": {}}), encoding="utf-8")
|
|
|
|
|
|
def test_get_app_config_reloads_when_file_changes(tmp_path, monkeypatch):
|
|
config_path = tmp_path / "config.yaml"
|
|
extensions_path = tmp_path / "extensions_config.json"
|
|
_write_extensions_config(extensions_path)
|
|
_write_config(config_path, model_name="first-model", supports_thinking=False)
|
|
|
|
monkeypatch.setenv("DEER_FLOW_CONFIG_PATH", str(config_path))
|
|
monkeypatch.setenv("DEER_FLOW_EXTENSIONS_CONFIG_PATH", str(extensions_path))
|
|
reset_app_config()
|
|
|
|
try:
|
|
initial = get_app_config()
|
|
assert initial.models[0].supports_thinking is False
|
|
|
|
_write_config(config_path, model_name="first-model", supports_thinking=True)
|
|
next_mtime = config_path.stat().st_mtime + 5
|
|
os.utime(config_path, (next_mtime, next_mtime))
|
|
|
|
reloaded = get_app_config()
|
|
assert reloaded.models[0].supports_thinking is True
|
|
assert reloaded is not initial
|
|
finally:
|
|
reset_app_config()
|
|
|
|
|
|
def test_get_app_config_reloads_when_config_path_changes(tmp_path, monkeypatch):
|
|
config_a = tmp_path / "config-a.yaml"
|
|
config_b = tmp_path / "config-b.yaml"
|
|
extensions_path = tmp_path / "extensions_config.json"
|
|
_write_extensions_config(extensions_path)
|
|
_write_config(config_a, model_name="model-a", supports_thinking=False)
|
|
_write_config(config_b, model_name="model-b", supports_thinking=True)
|
|
|
|
monkeypatch.setenv("DEER_FLOW_EXTENSIONS_CONFIG_PATH", str(extensions_path))
|
|
monkeypatch.setenv("DEER_FLOW_CONFIG_PATH", str(config_a))
|
|
reset_app_config()
|
|
|
|
try:
|
|
first = get_app_config()
|
|
assert first.models[0].name == "model-a"
|
|
|
|
monkeypatch.setenv("DEER_FLOW_CONFIG_PATH", str(config_b))
|
|
second = get_app_config()
|
|
assert second.models[0].name == "model-b"
|
|
assert second is not first
|
|
finally:
|
|
reset_app_config()
|