AUXteam's picture
Upload folder using huggingface_hub
6e38ce1 verified
Raw
History Blame Contribute Delete
11.1 kB
import base64
import os
from typing import Any, List, Sequence, Dict
import json
from autogen_agentchat.messages import ChatMessage, MultiModalMessage, TextMessage
from autogen_core import Image
from loguru import logger
import shutil
from typing import Optional
def construct_task(
query: str, files: List[Dict[str, Any]] | None = None
) -> Sequence[ChatMessage]:
"""
Construct a task from a query string and list of files.
Returns a list of ChatMessages that combines all files and the query.
Args:
query (str): The text query from the user
files (List[Dict[str, Any]]): List of file objects with properties name, content, and type
Returns:
Sequence[ChatMessage]: A list of ChatMessages that combines all files and the query.
"""
if files is None:
files = []
images: List[Image] = []
text_parts: List[str] = []
messages_return: Sequence[ChatMessage] = []
attached_files: List[Dict[str, Any]] = []
# Process each file based on its type
for file in files:
try:
# Check if this is an uploaded file reference
if file.get("uploaded") and file.get("path"):
# Handle uploaded file by path reference
file_path = file.get("path", "")
text_parts.append(f"Attached file: {file.get('name', 'unknown.file')}")
attached_files.append(
{
"name": file.get("name", "unknown.file"),
"type": file.get("type", "file"),
"path": file_path,
"uploaded": True,
}
)
elif file.get("type", "").startswith("image/"):
# Handle image file using from_base64 method
image = Image.from_base64(file["content"])
images.append(image)
text_parts.append(f"Attached image: {file.get('name', 'unknown.img')}")
# name and type
attached_files.append(
{
"name": file.get("name", "unknown.img"),
"type": file.get("type", "image"),
}
)
else:
# Handle all other files as text (base64 encoded content)
try:
text_content = base64.b64decode(file["content"]).decode("utf-8")
text_parts.append(
f"Attached file: {file.get('name', 'unknown.file')}\n{text_content}"
)
attached_files.append(
{
"name": file.get("name", "unknown.file"),
"type": file.get("type", "text"),
}
)
except Exception as e:
logger.error(f"Error processing file content: {str(e)}")
text_parts.append(
f"Attached file: {file.get('name', 'unknown.file')} (failed to process content)"
)
attached_files.append(
{
"name": file.get("name", "unknown.file"),
"type": file.get("type", "text"),
}
)
except Exception as e:
logger.error(f"Error processing file {file.get('name')}: {str(e)}")
# Add the user query at the end
combined_text = "\n\n".join(text_parts)
attached_files_json = json.dumps(attached_files)
# Return a MultiModalMessage if there are images, otherwise a TextMessage
if len(text_parts) > 0:
messages_return.append(
TextMessage(
source="user", content=combined_text, metadata={"internal": "yes"}
)
)
if images:
messages_return.append(
MultiModalMessage(
source="user",
content=[query, *images],
metadata={"attached_files": attached_files_json},
)
)
else:
messages_return.append(
TextMessage(
source="user",
content=query,
metadata={"attached_files": attached_files_json},
)
)
return messages_return
def get_file_type(file_path: str) -> str:
"""
Get file type determined by the file extension. If the file extension is not
recognized, 'unknown' will be used as the file type.
Args:
file_path (str): The path to the file to be serialized.
Returns:
str: A string containing the file type.
"""
# Extended list of file extensions for code and text files
CODE_EXTENSIONS = {
".py",
".python",
".js",
".jsx",
".java",
".c",
".cpp",
".cs",
".ts",
".tsx",
".html",
".css",
".scss",
".less",
".json",
".xml",
".yaml",
".yml",
".md",
".rst",
".tex",
".sh",
".bat",
".ps1",
".php",
".rb",
".go",
".swift",
".kt",
".hs",
".scala",
".lua",
".pl",
".sql",
".config",
}
# Supported spreadsheet extensions
CSV_EXTENSIONS = {".csv", ".xlsx"}
# Supported image extensions
IMAGE_EXTENSIONS = {
".png",
".jpg",
".jpeg",
".gif",
".bmp",
".tiff",
".svg",
".webp",
}
# Supported (web) video extensions
VIDEO_EXTENSIONS = {".mp4", ".webm", ".ogg", ".mov", ".avi", ".wmv"}
# Supported PDF extension
PDF_EXTENSION = ".pdf"
# Determine the file extension
_, file_extension = os.path.splitext(file_path)
# Determine the file type based on the extension
if file_extension in CODE_EXTENSIONS:
file_type = "code"
elif file_extension in CSV_EXTENSIONS:
file_type = "csv"
elif file_extension in IMAGE_EXTENSIONS:
file_type = "image"
elif file_extension == PDF_EXTENSION:
file_type = "pdf"
elif file_extension in VIDEO_EXTENSIONS:
file_type = "video"
else:
file_type = "unknown"
return file_type
def get_modified_files(
start_timestamp: float, end_timestamp: float, source_dir: str
) -> List[Dict[str, str]]:
"""
Identify files from source_dir that were modified within a specified timestamp range.
The function excludes files with certain file extensions and names.
Args:
start_timestamp (float): The floating-point number representing the start timestamp to filter modified files.
end_timestamp (float): The floating-point number representing the end timestamp to filter modified files.
source_dir (str): The directory to search for modified files.
Returns:
List[Dict[str, str]]: A list of dictionaries with details of relative file paths that were modified.
Dictionary format: {path: "", name: "", extension: "", type: ""}
Files with extensions "__pycache__", "*.pyc", "__init__.py", and "*.cache"
are ignored.
"""
modified_files: List[Dict[str, str]] = []
ignore_extensions = {".pyc", ".cache"}
ignore_files = {"__pycache__", "__init__.py"}
# Walk through the directory tree
for root, dirs, files in os.walk(source_dir):
# Update directories and files to exclude those to be ignored
dirs[:] = [d for d in dirs if d not in ignore_files]
files[:] = [
f
for f in files
if f not in ignore_files and os.path.splitext(f)[1] not in ignore_extensions
]
for file in files:
file_path = os.path.join(root, file)
file_mtime = os.path.getmtime(file_path)
# Verify if the file was modified within the given timestamp range
if start_timestamp <= file_mtime <= end_timestamp:
file_relative_path = (
"files/user" + file_path.split("files/user", 1)[1]
if "files/user" in file_path
else ""
)
file_type = get_file_type(file_path)
file_dict = {
"path": file_relative_path,
"short_path": file_relative_path,
"name": os.path.basename(file),
# Remove the dot
"extension": os.path.splitext(file)[1].lstrip("."),
"type": file_type,
}
modified_files.append(file_dict)
# Sort the modified files by extension
modified_files.sort(key=lambda x: x["extension"])
return modified_files
def copy_files_to_run_directory(
new_files: List[Dict[str, Any]],
run_path: str,
source_dir: str = "./debug",
app_dir: Optional[str] = None,
) -> List[Dict[str, Any]]:
"""
Copy multiple files to the user's run directory.
Args:
new_files (List[Dict[str, Any]]): List of dictionaries containing file information (path, name)
run_path (str): Path segment containing user_id/run_id
source_dir (str, optional): Directory where source files are located if path is not specified. Default: `./debug`
app_dir (str, optional): Base application directory, defaults to ~/.magentic_ui if None. Default: None
Returns:
List[Dict[str, Any]]: List of file info dictionaries with updated paths
"""
# Determine app directory if not provided
if app_dir is None:
app_dir = os.path.join(os.path.expanduser("~"), ".magentic_ui")
# Create the destination directory if it doesn't exist
dest_dir = os.path.join(app_dir, "files", run_path)
os.makedirs(dest_dir, exist_ok=True)
copied_files: List[Dict[str, Any]] = []
for file_info in new_files:
try:
# Source file path
src_path = file_info.get("path", "")
if not src_path:
# If no path is specified, look in the source directory
src_path = os.path.join(source_dir, file_info.get("name", ""))
# Destination file path
dest_path = os.path.join(dest_dir, file_info.get("name", ""))
# Copy the file
if os.path.exists(src_path):
shutil.copy2(src_path, dest_path)
# Create a copy of the file info with updated path
updated_file_info = file_info.copy()
updated_file_info["path"] = dest_path
updated_file_info["short_path"] = os.path.join(
run_path, file_info.get("name", "")
)
copied_files.append(updated_file_info)
else:
print(f"Warning: Source file not found: {src_path}")
except Exception as e:
print(f"Failed to copy file {file_info.get('name')}: {e}")
return copied_files