fix: apply secret redaction to file tool outputs
Terminal output was already redacted via redact_sensitive_text() but read_file and search_files returned raw content. Now both tools redact secrets before returning results to the LLM. Based on PR #372 by @teyrebaz33 (closes #363) — applied manually due to branch conflicts with the current codebase.
This commit is contained in:
parent
3214c05e82
commit
7af33accf1
2 changed files with 9 additions and 0 deletions
|
|
@ -38,6 +38,7 @@ class TestReadFileHandler:
|
||||||
def test_returns_file_content(self, mock_get):
|
def test_returns_file_content(self, mock_get):
|
||||||
mock_ops = MagicMock()
|
mock_ops = MagicMock()
|
||||||
result_obj = MagicMock()
|
result_obj = MagicMock()
|
||||||
|
result_obj.content = "line1\nline2"
|
||||||
result_obj.to_dict.return_value = {"content": "line1\nline2", "total_lines": 2}
|
result_obj.to_dict.return_value = {"content": "line1\nline2", "total_lines": 2}
|
||||||
mock_ops.read_file.return_value = result_obj
|
mock_ops.read_file.return_value = result_obj
|
||||||
mock_get.return_value = mock_ops
|
mock_get.return_value = mock_ops
|
||||||
|
|
@ -52,6 +53,7 @@ class TestReadFileHandler:
|
||||||
def test_custom_offset_and_limit(self, mock_get):
|
def test_custom_offset_and_limit(self, mock_get):
|
||||||
mock_ops = MagicMock()
|
mock_ops = MagicMock()
|
||||||
result_obj = MagicMock()
|
result_obj = MagicMock()
|
||||||
|
result_obj.content = "line10"
|
||||||
result_obj.to_dict.return_value = {"content": "line10", "total_lines": 50}
|
result_obj.to_dict.return_value = {"content": "line10", "total_lines": 50}
|
||||||
mock_ops.read_file.return_value = result_obj
|
mock_ops.read_file.return_value = result_obj
|
||||||
mock_get.return_value = mock_ops
|
mock_get.return_value = mock_ops
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import os
|
||||||
import threading
|
import threading
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from tools.file_operations import ShellFileOperations
|
from tools.file_operations import ShellFileOperations
|
||||||
|
from agent.redact import redact_sensitive_text
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -128,6 +129,8 @@ def read_file_tool(path: str, offset: int = 1, limit: int = 500, task_id: str =
|
||||||
try:
|
try:
|
||||||
file_ops = _get_file_ops(task_id)
|
file_ops = _get_file_ops(task_id)
|
||||||
result = file_ops.read_file(path, offset, limit)
|
result = file_ops.read_file(path, offset, limit)
|
||||||
|
if result.content:
|
||||||
|
result.content = redact_sensitive_text(result.content)
|
||||||
return json.dumps(result.to_dict(), ensure_ascii=False)
|
return json.dumps(result.to_dict(), ensure_ascii=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return json.dumps({"error": str(e)}, ensure_ascii=False)
|
return json.dumps({"error": str(e)}, ensure_ascii=False)
|
||||||
|
|
@ -186,6 +189,10 @@ def search_tool(pattern: str, target: str = "content", path: str = ".",
|
||||||
pattern=pattern, path=path, target=target, file_glob=file_glob,
|
pattern=pattern, path=path, target=target, file_glob=file_glob,
|
||||||
limit=limit, offset=offset, output_mode=output_mode, context=context
|
limit=limit, offset=offset, output_mode=output_mode, context=context
|
||||||
)
|
)
|
||||||
|
if hasattr(result, 'matches'):
|
||||||
|
for m in result.matches:
|
||||||
|
if hasattr(m, 'content') and m.content:
|
||||||
|
m.content = redact_sensitive_text(m.content)
|
||||||
result_dict = result.to_dict()
|
result_dict = result.to_dict()
|
||||||
result_json = json.dumps(result_dict, ensure_ascii=False)
|
result_json = json.dumps(result_dict, ensure_ascii=False)
|
||||||
# Hint when results were truncated — explicit next offset is clearer
|
# Hint when results were truncated — explicit next offset is clearer
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue