Merge main into feature/images - resolve conflicts favoring our approach

- Kept version 4.8.0 for new features
- Preserved our _is_builtin_custom_models_config approach over main's ALLOWED_INTERNAL_PATHS
- Our targeted solution is cleaner than the general whitelist approach
This commit is contained in:
Fahad
2025-06-16 13:19:08 +04:00
5 changed files with 517 additions and 10 deletions

View File

@@ -612,11 +612,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"
@@ -803,7 +809,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(
@@ -813,7 +820,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:",
"",
@@ -842,16 +849,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

@@ -318,9 +318,14 @@ def translate_path_for_environment(path_str: str) -> str:
# Handle built-in server config file - no translation needed
if _is_builtin_custom_models_config(path_str):
return path_str
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)