feat(deploy): finalize MVP deployment and file transfer approach

This commit is contained in:
Mikhail Putilovskij 2026-05-02 23:45:52 +03:00
parent 6369721876
commit 0f79494fbe
43 changed files with 3078 additions and 645 deletions

View file

@ -2,16 +2,16 @@ from __future__ import annotations
import mimetypes
import re
from datetime import UTC, datetime
from pathlib import Path
from pathlib import Path, PurePosixPath
from core.protocol import Attachment
def _sanitize_component(value: str) -> str:
cleaned = re.sub(r"[^A-Za-z0-9._-]+", "_", value)
cleaned = cleaned.strip("._-")
return cleaned or "unknown"
def _sanitize_filename(value: str) -> str:
filename = PurePosixPath(str(value).replace("\\", "/")).name.strip()
cleaned = re.sub(r"[\x00-\x1f\x7f<>:\"/\\|?*]+", "_", filename)
cleaned = cleaned.strip(" .")
return cleaned or "attachment.bin"
def _default_filename(attachment: Attachment) -> str:
@ -28,38 +28,38 @@ def _default_filename(attachment: Attachment) -> str:
return f"{base}{extension}"
def build_workspace_attachment_path(
*,
workspace_root: Path,
matrix_user_id: str,
room_id: str,
filename: str,
timestamp: str | None = None,
) -> tuple[str, Path]:
"""Legacy path builder used when no per-agent workspace_path is configured."""
stamp = timestamp or datetime.now(UTC).strftime("%Y%m%d-%H%M%S")
safe_user = _sanitize_component(matrix_user_id.lstrip("@"))
safe_room = _sanitize_component(room_id.lstrip("!"))
safe_name = _sanitize_component(filename) or "attachment.bin"
relative_path = (
Path("surfaces") / "matrix" / safe_user / safe_room / "inbox" / f"{stamp}-{safe_name}"
)
return relative_path.as_posix(), workspace_root / relative_path
def _with_copy_index(filename: str, index: int) -> str:
path = Path(filename)
suffix = path.suffix
stem = path.stem if suffix else filename
return f"{stem} ({index}){suffix}"
def build_agent_incoming_path(
def _unique_workspace_relative_path(workspace_root: Path, filename: str) -> tuple[str, Path]:
safe_name = _sanitize_filename(filename)
candidate = workspace_root / safe_name
if not candidate.exists():
return safe_name, candidate
index = 1
while True:
indexed_name = _with_copy_index(safe_name, index)
candidate = workspace_root / indexed_name
if not candidate.exists():
return indexed_name, candidate
index += 1
def build_agent_workspace_path(
*,
workspace_root: Path,
filename: str,
timestamp: str | None = None,
) -> tuple[str, Path]:
"""Per-agent path builder: saves to {workspace_root}/incoming/{stamp}-{filename}.
"""Saves user files directly to {workspace_root}/{filename}.
The returned relative path is what gets passed to agent.send_message(attachments=[...]).
"""
stamp = timestamp or datetime.now(UTC).strftime("%Y%m%d-%H%M%S")
safe_name = _sanitize_component(filename) or "attachment.bin"
relative_path = Path("incoming") / f"{stamp}-{safe_name}"
return relative_path.as_posix(), workspace_root / relative_path
return _unique_workspace_relative_path(workspace_root, filename)
async def download_matrix_attachment(
@ -76,21 +76,11 @@ async def download_matrix_attachment(
filename = _default_filename(attachment)
if workspace_root.name and str(workspace_root) not in (".", "/workspace", "/agents"):
# Per-agent workspace configured — use simple incoming/ layout
relative_path, absolute_path = build_agent_incoming_path(
workspace_root=workspace_root,
filename=filename,
timestamp=timestamp,
)
else:
relative_path, absolute_path = build_workspace_attachment_path(
workspace_root=workspace_root,
matrix_user_id=matrix_user_id,
room_id=room_id,
filename=filename,
timestamp=timestamp,
)
del matrix_user_id, room_id, timestamp
relative_path, absolute_path = build_agent_workspace_path(
workspace_root=workspace_root,
filename=filename,
)
absolute_path.parent.mkdir(parents=True, exist_ok=True)