Fixed internal file path translation into docker

This commit is contained in:
Fahad
2025-06-16 11:30:02 +04:00
parent d498e9854b
commit d6d7bf8cac
6 changed files with 544 additions and 10 deletions

View File

@@ -534,11 +534,17 @@ def _plan_file_inclusion_by_size(all_files: list[str], max_file_tokens: int) ->
)
else:
files_to_skip.append(file_path)
logger.debug(f"[FILES] Skipping {file_path} - file not accessible")
# More descriptive message for missing files
if not os.path.exists(translated_path):
logger.debug(
f"[FILES] Skipping {file_path} - file no longer exists (may have been moved/deleted since conversation)"
)
else:
logger.debug(f"[FILES] Skipping {file_path} - file not accessible (not a regular file)")
except Exception as e:
files_to_skip.append(file_path)
logger.debug(f"[FILES] Skipping {file_path} - error: {type(e).__name__}: {e}")
logger.debug(f"[FILES] Skipping {file_path} - error during processing: {type(e).__name__}: {e}")
logger.debug(
f"[FILES] Inclusion plan: {len(files_to_include)} include, {len(files_to_skip)} skip, {total_tokens:,} tokens"
@@ -725,7 +731,8 @@ def build_conversation_history(context: ThreadContext, model_context=None, read_
files_to_include, files_to_skip, estimated_tokens = _plan_file_inclusion_by_size(all_files, max_file_tokens)
if files_to_skip:
logger.info(f"[FILES] Skipping {len(files_to_skip)} files due to size constraints: {files_to_skip}")
logger.info(f"[FILES] Excluding {len(files_to_skip)} files from conversation history: {files_to_skip}")
logger.debug("[FILES] Files excluded for various reasons (size constraints, missing files, access issues)")
if files_to_include:
history_parts.extend(
@@ -735,7 +742,7 @@ def build_conversation_history(context: ThreadContext, model_context=None, read_
(
""
if not files_to_skip
else f"[NOTE: {len(files_to_skip)} files omitted due to size constraints]"
else f"[NOTE: {len(files_to_skip)} files omitted (size constraints, missing files, or access issues)]"
),
"Refer to these when analyzing the context and requests below:",
"",
@@ -764,16 +771,31 @@ def build_conversation_history(context: ThreadContext, model_context=None, read_
else:
logger.debug(f"File skipped (empty content): {file_path}")
except Exception as e:
logger.warning(
f"Failed to embed file in conversation history: {file_path} - {type(e).__name__}: {e}"
)
# More descriptive error handling for missing files
try:
from utils.file_utils import translate_path_for_environment
translated_path = translate_path_for_environment(file_path)
if not os.path.exists(translated_path):
logger.info(
f"File no longer accessible for conversation history: {file_path} - file was moved/deleted since conversation (marking as excluded)"
)
else:
logger.warning(
f"Failed to embed file in conversation history: {file_path} - {type(e).__name__}: {e}"
)
except Exception:
# Fallback if path translation also fails
logger.warning(
f"Failed to embed file in conversation history: {file_path} - {type(e).__name__}: {e}"
)
continue
if file_contents:
files_content = "".join(file_contents)
if files_to_skip:
files_content += (
f"\n[NOTE: {len(files_to_skip)} additional file(s) were omitted due to size constraints. "
f"\n[NOTE: {len(files_to_skip)} additional file(s) were omitted due to size constraints, missing files, or access issues. "
f"These were older files from earlier conversation turns.]\n"
)
history_parts.append(files_content)

View File

@@ -284,8 +284,40 @@ def translate_path_for_environment(path_str: str) -> str:
Returns:
Translated path appropriate for the current environment
"""
# Allow access to specific internal application configuration files
# Store as relative paths so they work in both Docker and standalone modes
# Use exact paths for security - no wildcards or prefix matching
ALLOWED_INTERNAL_PATHS = {
"conf/custom_models.json",
# Add other specific internal files here as needed
}
# Check for internal app paths - extract relative part if it's an /app/ path
relative_internal_path = None
if path_str.startswith("/app/"):
relative_internal_path = path_str[5:] # Remove "/app/" prefix
if relative_internal_path.startswith("/"):
relative_internal_path = relative_internal_path[1:] # Remove leading slash if present
# Check if this is an allowed internal file
if relative_internal_path and relative_internal_path in ALLOWED_INTERNAL_PATHS:
# Translate to appropriate path for current environment
if not WORKSPACE_ROOT or not WORKSPACE_ROOT.strip() or not CONTAINER_WORKSPACE.exists():
# Standalone mode: use relative path
return "./" + relative_internal_path
else:
# Docker mode: use absolute app path
return "/app/" + relative_internal_path
# Handle other /app/ paths in standalone mode (for non-whitelisted files)
if not WORKSPACE_ROOT or not WORKSPACE_ROOT.strip() or not CONTAINER_WORKSPACE.exists():
# Not in the configured Docker environment, no translation needed
if path_str.startswith("/app/"):
# Convert Docker internal paths to local relative paths for standalone mode
relative_path = path_str[5:] # Remove "/app/" prefix
if relative_path.startswith("/"):
relative_path = relative_path[1:] # Remove leading slash if present
return "./" + relative_path
# No other translation needed for standalone mode
return path_str
# Check if the path is already a container path (starts with /workspace)