finetuning #21
@ -65,7 +65,7 @@ def list_files() -> str:
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_file_tree(dir_path: str=ALLOWED_DIR) -> str:
|
||||
def get_file_tree(dir_path: str="") -> str:
|
||||
"""Get a tree representation of the project directory.
|
||||
|
||||
Args:
|
||||
@ -117,7 +117,7 @@ def get_file_tree(dir_path: str=ALLOWED_DIR) -> str:
|
||||
lines.append(_tree(entry, prefix + extension))
|
||||
return "\n".join(lines)
|
||||
|
||||
return _tree(Path(dir_path))
|
||||
return _tree(Path(safe_dir))
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class DebugLogger:
|
||||
"""In-memory logger for code execution events.
|
||||
|
||||
Collects timestamped INFO and ERROR entries during a single run.
|
||||
Call clear() before each new execution to start fresh.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.logs: list[dict] = []
|
||||
|
||||
def log(self, message: str) -> None:
|
||||
"""Append a general info message."""
|
||||
self.logs.append({
|
||||
"level": "INFO",
|
||||
"message": message,
|
||||
"timestamp": datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
|
||||
def log_error(self, error_message: str) -> None:
|
||||
"""Append an error message."""
|
||||
self.logs.append({
|
||||
"level": "ERROR",
|
||||
"message": error_message,
|
||||
"timestamp": datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
|
||||
def get_logs(self) -> list[dict]:
|
||||
"""Return a copy of all collected log entries."""
|
||||
return list(self.logs)
|
||||
|
||||
def clear(self) -> None:
|
||||
"""Reset the log — call before each new execution."""
|
||||
self.logs = []
|
||||
|
||||
def format_debug_output(self, output: dict) -> str:
|
||||
"""Format an ExecutionEngine result dict into a human-readable string.
|
||||
|
||||
Args:
|
||||
output: dict with keys 'stdout', 'stderr', and 'rc'.
|
||||
|
||||
Returns:
|
||||
A formatted string ready for display in the UI.
|
||||
"""
|
||||
lines = []
|
||||
|
||||
status = "SUCCESS" if output.get("rc") == 0 else "FAILED"
|
||||
lines.append(f"[{status}] Exit code: {output.get('rc')}")
|
||||
|
||||
if output.get("stdout"):
|
||||
lines.append("\n--- stdout ---")
|
||||
lines.append(output["stdout"].rstrip())
|
||||
|
||||
if output.get("stderr"):
|
||||
lines.append("\n--- stderr ---")
|
||||
lines.append(output["stderr"].rstrip())
|
||||
|
||||
if not output.get("stdout") and not output.get("stderr"):
|
||||
lines.append("No output produced.")
|
||||
|
||||
for entry in self.logs:
|
||||
lines.append(f"[{entry['timestamp']}] [{entry['level']}] {entry['message']}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger = DebugLogger()
|
||||
print(logger.get_logs())
|
||||
@ -1,5 +1,6 @@
|
||||
# Core Framework
|
||||
streamlit>=1.28.0
|
||||
streamlit_arborist>=0.1.0
|
||||
|
||||
# AI/LLM Integration
|
||||
openai>=1.0.0
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import sys
|
||||
import pytest
|
||||
from backend.agent.servers import mcp_server_file_search as server
|
||||
|
||||
@ -159,6 +160,7 @@ def test_safe_path_double_traversal(workspace):
|
||||
# 12. Symlink Escape verhindern
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@pytest.mark.skipif(sys.platform == "win32", reason="Symlinks require special privileges on Windows")
|
||||
def test_safe_path_symlink_escape(workspace):
|
||||
outside = workspace.parent / "outside"
|
||||
outside.mkdir()
|
||||
@ -264,6 +266,10 @@ def test_write_unicode_filename(workspace):
|
||||
# 20. Tiefe Verzeichnisstrukturen
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.platform == "win32",
|
||||
reason="Windows MAX_PATH limit (260 chars) prevents deep nesting",
|
||||
)
|
||||
def test_list_files_deep_nesting(workspace):
|
||||
current = workspace
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user