mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-02 22:02:13 +08:00
fix: added configuration of python_repl (#503)
* fix: added configuration of python_repl * fix the lint and unit test errors * fix the lint and unit test errors * fix:the lint check errors
This commit is contained in:
@@ -14,10 +14,14 @@ ALLOWED_ORIGINS=http://localhost:3000
|
||||
|
||||
# Enable or disable MCP server configuration, the default is false.
|
||||
# Please enable this feature before securing your front-end and back-end in a managed environment.
|
||||
|
||||
# Otherwise, you system could be compromised.
|
||||
ENABLE_MCP_SERVER_CONFIGURATION=false
|
||||
|
||||
# Enable or disable PYTHON_REPL configuration, the default is false.
|
||||
# Please enable this feature before securing your in a managed environment.
|
||||
# Otherwise, you system could be compromised.
|
||||
ENABLE_PYTHON_REPL=false
|
||||
|
||||
# Search Engine, Supported values: tavily (recommended), duckduckgo, brave_search, arxiv
|
||||
SEARCH_API=tavily
|
||||
TAVILY_API_KEY=tvly-xxx
|
||||
|
||||
@@ -420,6 +420,9 @@ docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> If you want to deploy the deer flow into production environments, please add authentication to the website and evaluate your security check of the MCPServer and Python Repl.
|
||||
|
||||
## Examples
|
||||
|
||||
The following examples demonstrate the capabilities of DeerFlow:
|
||||
|
||||
76
README_de.md
76
README_de.md
@@ -11,7 +11,7 @@
|
||||
|
||||
**DeerFlow** (**D**eep **E**xploration and **E**fficient **R**esearch **Flow**) ist ein Community-getriebenes Framework für tiefgehende Recherche, das auf der großartigen Arbeit der Open-Source-Community aufbaut. Unser Ziel ist es, Sprachmodelle mit spezialisierten Werkzeugen für Aufgaben wie Websuche, Crawling und Python-Code-Ausführung zu kombinieren und gleichzeitig der Community, die dies möglich gemacht hat, etwas zurückzugeben.
|
||||
|
||||
Derzeit ist DeerFlow offiziell in das FaaS-Anwendungszentrum von Volcengine eingezogen. Benutzer können es über den Erfahrungslink online erleben, um seine leistungsstarken Funktionen und bequemen Operationen intuitiv zu spüren. Gleichzeitig unterstützt DeerFlow zur Erfüllung der Bereitstellungsanforderungen verschiedener Benutzer die Ein-Klick-Bereitstellung basierend auf Volcengine. Klicken Sie auf den Bereitstellungslink, um den Bereitstellungsprozess schnell abzuschließen und eine effiziente Forschungsreise zu beginnen.
|
||||
Derzeit ist DeerFlow offiziell in das [FaaS-Anwendungszentrum von Volcengine](https://console.volcengine.com/vefaas/region:vefaas+cn-beijing/market) eingezogen. Benutzer können es über den [Erfahrungslink](https://console.volcengine.com/vefaas/region:vefaas+cn-beijing/market/deerflow/?channel=github&source=deerflow) online erleben, um seine leistungsstarken Funktionen und bequemen Operationen intuitiv zu spüren. Gleichzeitig unterstützt DeerFlow zur Erfüllung der Bereitstellungsanforderungen verschiedener Benutzer die Ein-Klick-Bereitstellung basierend auf Volcengine. Klicken Sie auf den [Bereitstellungslink](https://console.volcengine.com/vefaas/region:vefaas+cn-beijing/application/create?templateId=683adf9e372daa0008aaed5c&channel=github&source=deerflow), um den Bereitstellungsprozess schnell abzuschließen und eine effiziente Forschungsreise zu beginnen.
|
||||
|
||||
Besuchen Sie [unsere offizielle Website](https://deerflow.tech/) für weitere Details.
|
||||
|
||||
@@ -43,6 +43,7 @@ In dieser Demo zeigen wir, wie man DeerFlow nutzt, um:
|
||||
- [🌟 Funktionen](#funktionen)
|
||||
- [🏗️ Architektur](#architektur)
|
||||
- [🛠️ Entwicklung](#entwicklung)
|
||||
- [🐳 Docker](#docker)
|
||||
- [🗣️ Text-zu-Sprache-Integration](#text-zu-sprache-integration)
|
||||
- [📚 Beispiele](#beispiele)
|
||||
- [❓ FAQ](#faq)
|
||||
@@ -125,6 +126,7 @@ uv run main.py
|
||||
### Web-UI
|
||||
|
||||
Dieses Projekt enthält auch eine Web-UI, die ein dynamischeres und ansprechenderes interaktives Erlebnis bietet.
|
||||
|
||||
> [!HINWEIS]
|
||||
> Sie müssen zuerst die Abhängigkeiten der Web-UI installieren.
|
||||
|
||||
@@ -143,18 +145,20 @@ Weitere Details finden Sie im Verzeichnis [`web`](./web/).
|
||||
|
||||
## Unterstützte Suchmaschinen
|
||||
|
||||
### Websuche
|
||||
|
||||
DeerFlow unterstützt mehrere Suchmaschinen, die in Ihrer `.env`-Datei über die Variable `SEARCH_API` konfiguriert werden können:
|
||||
|
||||
- **Tavily** (Standard): Eine spezialisierte Such-API für KI-Anwendungen
|
||||
- Erfordert `TAVILY_API_KEY` in Ihrer `.env`-Datei
|
||||
- Registrieren Sie sich unter: <https://app.tavily.com/home>
|
||||
- Registrieren Sie sich unter: https://app.tavily.com/home
|
||||
|
||||
- **DuckDuckGo**: Datenschutzorientierte Suchmaschine
|
||||
- Kein API-Schlüssel erforderlich
|
||||
|
||||
- **Brave Search**: Datenschutzorientierte Suchmaschine mit erweiterten Funktionen
|
||||
- Erfordert `BRAVE_SEARCH_API_KEY` in Ihrer `.env`-Datei
|
||||
- Registrieren Sie sich unter: <https://brave.com/search/api/>
|
||||
- Registrieren Sie sich unter: https://brave.com/search/api/
|
||||
|
||||
- **Arxiv**: Wissenschaftliche Papiersuche für akademische Forschung
|
||||
- Kein API-Schlüssel erforderlich
|
||||
@@ -167,6 +171,20 @@ Um Ihre bevorzugte Suchmaschine zu konfigurieren, setzen Sie die Variable `SEARC
|
||||
SEARCH_API=tavily
|
||||
```
|
||||
|
||||
### Private Wissensbasis
|
||||
|
||||
DeerFlow unterstützt private Wissensbasen wie RAGFlow und VikingDB, sodass Sie Ihre privaten Dokumente zur Beantwortung von Fragen verwenden können.
|
||||
|
||||
- **[RAGFlow](https://ragflow.io/docs/dev/)**:Open-Source-RAG-Engine
|
||||
```
|
||||
# Beispiele in .env.example
|
||||
RAG_PROVIDER=ragflow
|
||||
RAGFLOW_API_URL="http://localhost:9388"
|
||||
RAGFLOW_API_KEY="ragflow-xxx"
|
||||
RAGFLOW_RETRIEVAL_SIZE=10
|
||||
RAGFLOW_CROSS_LANGUAGES=English,Chinese,Spanish,French,German,Japanese,Korean
|
||||
```
|
||||
|
||||
## Funktionen
|
||||
|
||||
### Kernfähigkeiten
|
||||
@@ -183,6 +201,11 @@ SEARCH_API=tavily
|
||||
- Websuche über Tavily, Brave Search und mehr
|
||||
- Crawling mit Jina
|
||||
- Fortgeschrittene Inhaltsextraktion
|
||||
- Unterstützung für private Wissensbasis
|
||||
|
||||
- 📃 **RAG-Integration**
|
||||
|
||||
- Unterstützt die Erwähnung von Dateien aus [RAGFlow](https://github.com/infiniflow/ragflow) innerhalb der Eingabebox. [RAGFlow-Server starten](https://ragflow.io/docs/dev/).
|
||||
|
||||
- 🔗 **MCP Nahtlose Integration**
|
||||
- Erweiterte Fähigkeiten für privaten Domänenzugriff, Wissensgraphen, Webbrowsing und mehr
|
||||
@@ -211,6 +234,7 @@ SEARCH_API=tavily
|
||||
DeerFlow implementiert eine modulare Multi-Agenten-Systemarchitektur, die für automatisierte Forschung und Codeanalyse konzipiert ist. Das System basiert auf LangGraph und ermöglicht einen flexiblen zustandsbasierten Workflow, bei dem Komponenten über ein klar definiertes Nachrichtenübermittlungssystem kommunizieren.
|
||||
|
||||

|
||||
|
||||
> Sehen Sie es live auf [deerflow.tech](https://deerflow.tech/#multi-agent-architecture)
|
||||
|
||||
Das System verwendet einen optimierten Workflow mit den folgenden Komponenten:
|
||||
@@ -314,9 +338,9 @@ langgraph dev
|
||||
|
||||
Nach dem Start des LangGraph-Servers sehen Sie mehrere URLs im Terminal:
|
||||
|
||||
- API: <http://127.0.0.1:2024>
|
||||
- Studio UI: <https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024>
|
||||
- API-Dokumentation: <http://127.0.0.1:2024/docs>
|
||||
- API: http://127.0.0.1:2024
|
||||
- Studio UI: https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024
|
||||
- API-Dokumentation: http://127.0.0.1:2024/docs
|
||||
|
||||
Öffnen Sie den Studio UI-Link in Ihrem Browser, um auf die Debugging-Schnittstelle zuzugreifen.
|
||||
|
||||
@@ -351,13 +375,49 @@ DeerFlow unterstützt LangSmith-Tracing, um Ihnen beim Debuggen und Überwachen
|
||||
```
|
||||
|
||||
2. Starten Sie das Tracing mit LangSmith lokal, indem Sie folgenden Befehl ausführen:
|
||||
|
||||
```bash
|
||||
langgraph dev
|
||||
```
|
||||
|
||||
Dies aktiviert die Trace-Visualisierung in LangGraph Studio und sendet Ihre Traces zur Überwachung und Analyse an LangSmith.
|
||||
|
||||
## Docker
|
||||
|
||||
Sie können dieses Projekt auch mit Docker ausführen.
|
||||
|
||||
Zuerst müssen Sie die [Konfiguration](docs/configuration_guide.md) unten lesen. Stellen Sie sicher, dass die Dateien `.env` und `.conf.yaml` bereit sind.
|
||||
|
||||
Zweitens, um ein Docker-Image Ihres eigenen Webservers zu erstellen:
|
||||
|
||||
```bash
|
||||
docker build -t deer-flow-api .
|
||||
```
|
||||
|
||||
Schließlich starten Sie einen Docker-Container, der den Webserver ausführt:
|
||||
|
||||
```bash
|
||||
# Ersetzen Sie deer-flow-api-app durch Ihren bevorzugten Container-Namen
|
||||
docker run -d -t -p 8000:8000 --env-file .env --name deer-flow-api-app deer-flow-api
|
||||
|
||||
# Server stoppen
|
||||
docker stop deer-flow-api-app
|
||||
```
|
||||
|
||||
### Docker Compose (umfasst sowohl Backend als auch Frontend)
|
||||
|
||||
DeerFlow bietet ein docker-compose-Setup, um sowohl das Backend als auch das Frontend einfach zusammen auszuführen:
|
||||
|
||||
```bash
|
||||
# Docker-Image erstellen
|
||||
docker compose build
|
||||
|
||||
# Server starten
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Wenn Sie DeerFlow in Produktionsumgebungen bereitstellen möchten, fügen Sie bitte Authentifizierung zur Website hinzu und bewerten Sie Ihre Sicherheitsüberprüfung des MCPServer und Python Repl.
|
||||
|
||||
## Beispiele
|
||||
|
||||
Die folgenden Beispiele demonstrieren die Fähigkeiten von DeerFlow:
|
||||
@@ -487,6 +547,8 @@ Wir möchten unsere aufrichtige Wertschätzung den folgenden Projekten für ihre
|
||||
|
||||
- **[LangChain](https://github.com/langchain-ai/langchain)**: Ihr außergewöhnliches Framework unterstützt unsere LLM-Interaktionen und -Ketten und ermöglicht nahtlose Integration und Funktionalität.
|
||||
- **[LangGraph](https://github.com/langchain-ai/langgraph)**: Ihr innovativer Ansatz zur Multi-Agenten-Orchestrierung war maßgeblich für die Ermöglichung der ausgeklügelten Workflows von DeerFlow.
|
||||
- **[Novel](https://github.com/steven-tey/novel)**: Ihr Notion-artiger WYSIWYG-Editor unterstützt unsere Berichtbearbeitung und KI-unterstützte Umschreibung.
|
||||
- **[RAGFlow](https://github.com/infiniflow/ragflow)**: Wir haben durch die Integration mit RAGFlow die Unterstützung für Forschung auf privaten Wissensdatenbanken der Benutzer erreicht.
|
||||
|
||||
Diese Projekte veranschaulichen die transformative Kraft der Open-Source-Zusammenarbeit, und wir sind stolz darauf, auf ihren Grundlagen aufzubauen.
|
||||
|
||||
|
||||
@@ -403,6 +403,9 @@ docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Si desea implementar DeerFlow en entornos de producción, agregue autenticación al sitio web y evalúe su verificación de seguridad del MCPServer y Python Repl.
|
||||
|
||||
## Ejemplos
|
||||
|
||||
Los siguientes ejemplos demuestran las capacidades de DeerFlow:
|
||||
|
||||
@@ -399,6 +399,9 @@ docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> DeerFlow を本番環境にデプロイする場合は、ウェブサイトに認証を追加し、MCPServer と Python Repl のセキュリティチェックを評価してください。
|
||||
|
||||
## テキスト読み上げ統合
|
||||
|
||||
DeerFlow には現在、研究レポートを音声に変換できるテキスト読み上げ(TTS)機能が含まれています。この機能は火山引擎 TTS API を使用して高品質なテキストオーディオを生成します。速度、音量、ピッチなどの特性もカスタマイズ可能です。
|
||||
|
||||
@@ -388,6 +388,9 @@ docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Se você quiser implantar o DeerFlow em ambientes de produção, adicione autenticação ao site e avalie sua verificação de segurança do MCPServer e Python Repl.
|
||||
|
||||
## Exemplos
|
||||
|
||||
Os seguintes exemplos demonstram as capacidades do DeerFlow:
|
||||
|
||||
@@ -403,6 +403,9 @@ docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Если вы хотите развернуть DeerFlow в производственных средах, пожалуйста, добавьте аутентификацию к веб-сайту и оцените свою проверку безопасности MCPServer и Python Repl.
|
||||
|
||||
## Примеры
|
||||
|
||||
Следующие примеры демонстрируют возможности DeerFlow:
|
||||
|
||||
@@ -424,6 +424,9 @@ docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> 如果您想将 DeerFlow 部署到生产环境中,请为网站添加身份验证,并评估 MCPServer 和 Python Repl 的安全检查。
|
||||
|
||||
## 文本转语音集成
|
||||
|
||||
DeerFlow 现在包含一个文本转语音 (TTS) 功能,允许您将研究报告转换为语音。此功能使用火山引擎 TTS API 生成高质量的文本音频。速度、音量和音调等特性也可以自定义。
|
||||
|
||||
@@ -2,13 +2,24 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import logging
|
||||
from typing import Annotated
|
||||
import os
|
||||
from typing import Annotated, Optional
|
||||
from langchain_core.tools import tool
|
||||
from langchain_experimental.utilities import PythonREPL
|
||||
from .decorators import log_io
|
||||
|
||||
|
||||
def _is_python_repl_enabled() -> bool:
|
||||
"""Check if Python REPL tool is enabled from configuration."""
|
||||
# Check environment variable first
|
||||
env_enabled = os.getenv("ENABLE_PYTHON_REPL", "false").lower()
|
||||
if env_enabled in ("true", "1", "yes", "on"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# Initialize REPL and logger
|
||||
repl = PythonREPL()
|
||||
repl: Optional[PythonREPL] = PythonREPL() if _is_python_repl_enabled() else None
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -21,6 +32,13 @@ def python_repl_tool(
|
||||
):
|
||||
"""Use this to execute python code and do data analysis or calculation. If you want to see the output of a value,
|
||||
you should print it out with `print(...)`. This is visible to the user."""
|
||||
|
||||
# Check if the tool is enabled
|
||||
if not _is_python_repl_enabled():
|
||||
error_msg = "Python REPL tool is disabled. Please enable it in environment configuration."
|
||||
logger.warning(error_msg)
|
||||
return f"Tool disabled: {error_msg}"
|
||||
|
||||
if not isinstance(code, str):
|
||||
error_msg = f"Invalid input: code must be a string, got {type(code)}"
|
||||
logger.error(error_msg)
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from src.tools.python_repl import python_repl_tool
|
||||
|
||||
|
||||
def test_python_repl_tool_success():
|
||||
code = "print(1 + 1)"
|
||||
result = python_repl_tool(code)
|
||||
assert "Successfully executed" in result
|
||||
assert "Stdout: 2" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_syntax_error():
|
||||
code = "print(1 + )"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "SyntaxError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_runtime_error():
|
||||
code = "print(1 / 0)"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "ZeroDivisionError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_name_error():
|
||||
code = "print(undefined_variable)"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "NameError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_type_error():
|
||||
code = "'2' + 2"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "TypeError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_import_error():
|
||||
code = "from nonexistent_module import something"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "ModuleNotFoundError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_exception():
|
||||
code = "raise Exception('Test')"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "Exception" in result
|
||||
@@ -1,6 +1,7 @@
|
||||
# Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import os
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from src.tools.python_repl import python_repl_tool
|
||||
@@ -8,6 +9,7 @@ from src.tools.python_repl import python_repl_tool
|
||||
|
||||
class TestPythonReplTool:
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_successful_code_execution(self, mock_logger, mock_repl):
|
||||
@@ -26,24 +28,20 @@ class TestPythonReplTool:
|
||||
assert code in result
|
||||
assert expected_output in result
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_invalid_input_type(self, mock_logger, mock_repl):
|
||||
# Arrange
|
||||
invalid_code = 123
|
||||
|
||||
# Act & Assert - expect ValidationError from LangChain
|
||||
with pytest.raises(Exception) as exc_info:
|
||||
# Act & Assert - expect ValidationError when passing invalid input
|
||||
with pytest.raises(Exception): # Could be ValidationError or similar
|
||||
python_repl_tool(invalid_code)
|
||||
|
||||
# Verify that it's a validation error
|
||||
assert "ValidationError" in str(
|
||||
type(exc_info.value)
|
||||
) or "validation error" in str(exc_info.value)
|
||||
|
||||
# The REPL should not be called since validation fails first
|
||||
mock_repl.run.assert_not_called()
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_code_execution_with_error_in_result(self, mock_logger, mock_repl):
|
||||
@@ -62,6 +60,7 @@ class TestPythonReplTool:
|
||||
assert code in result
|
||||
assert error_result in result
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_code_execution_with_exception_in_result(self, mock_logger, mock_repl):
|
||||
@@ -80,6 +79,7 @@ class TestPythonReplTool:
|
||||
assert code in result
|
||||
assert exception_result in result
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_code_execution_raises_exception(self, mock_logger, mock_repl):
|
||||
@@ -98,6 +98,7 @@ class TestPythonReplTool:
|
||||
assert code in result
|
||||
assert repr(exception) in result
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_successful_execution_with_calculation(self, mock_logger, mock_repl):
|
||||
@@ -117,6 +118,7 @@ class TestPythonReplTool:
|
||||
assert code in result
|
||||
assert expected_output in result
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_empty_string_code(self, mock_logger, mock_repl):
|
||||
@@ -132,6 +134,7 @@ class TestPythonReplTool:
|
||||
mock_logger.info.assert_called_with("Code execution successful")
|
||||
assert "Successfully executed:" in result
|
||||
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "true"})
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_logging_calls(self, mock_logger, mock_repl):
|
||||
@@ -145,3 +148,74 @@ class TestPythonReplTool:
|
||||
# Assert
|
||||
mock_logger.info.assert_any_call("Executing Python code")
|
||||
mock_logger.info.assert_any_call("Code execution successful")
|
||||
|
||||
# New tests for configuration behavior
|
||||
@patch.dict(os.environ, {"ENABLE_PYTHON_REPL": "false"})
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_tool_disabled(self, mock_logger):
|
||||
# Arrange
|
||||
code = "print('test')"
|
||||
|
||||
# Act
|
||||
result = python_repl_tool(code)
|
||||
|
||||
# Assert
|
||||
mock_logger.warning.assert_called_with(
|
||||
"Python REPL tool is disabled. Please enable it in environment configuration."
|
||||
)
|
||||
assert "Tool disabled:" in result
|
||||
assert "Python REPL tool is disabled" in result
|
||||
|
||||
@patch.dict(os.environ, {}, clear=True)
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_tool_disabled_by_default(self, mock_logger):
|
||||
# Arrange - remove any existing ENABLE_PYTHON_REPL variable
|
||||
if "ENABLE_PYTHON_REPL" in os.environ:
|
||||
del os.environ["ENABLE_PYTHON_REPL"]
|
||||
code = "print('test')"
|
||||
|
||||
# Act
|
||||
result = python_repl_tool(code)
|
||||
|
||||
# Assert
|
||||
mock_logger.warning.assert_called_with(
|
||||
"Python REPL tool is disabled. Please enable it in environment configuration."
|
||||
)
|
||||
assert "Tool disabled:" in result
|
||||
|
||||
@pytest.mark.parametrize("env_value", ["true", "True", "TRUE", "1", "yes", "on"])
|
||||
@patch("src.tools.python_repl.repl")
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_tool_enabled_with_various_truthy_values(
|
||||
self, mock_logger, mock_repl, env_value
|
||||
):
|
||||
# Arrange
|
||||
with patch.dict(os.environ, {"ENABLE_PYTHON_REPL": env_value}):
|
||||
code = "print('enabled')"
|
||||
expected_output = "enabled\n"
|
||||
mock_repl.run.return_value = expected_output
|
||||
|
||||
# Act
|
||||
result = python_repl_tool(code)
|
||||
|
||||
# Assert
|
||||
mock_repl.run.assert_called_once_with(code)
|
||||
assert "Successfully executed:" in result
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"env_value", ["false", "False", "FALSE", "0", "no", "off", ""]
|
||||
)
|
||||
@patch("src.tools.python_repl.logger")
|
||||
def test_tool_disabled_with_various_falsy_values(self, mock_logger, env_value):
|
||||
# Arrange
|
||||
with patch.dict(os.environ, {"ENABLE_PYTHON_REPL": env_value}):
|
||||
code = "print('disabled')"
|
||||
|
||||
# Act
|
||||
result = python_repl_tool(code)
|
||||
|
||||
# Assert
|
||||
mock_logger.warning.assert_called_with(
|
||||
"Python REPL tool is disabled. Please enable it in environment configuration."
|
||||
)
|
||||
assert "Tool disabled:" in result
|
||||
|
||||
Reference in New Issue
Block a user