feat(deploy): finalize MVP deployment and file transfer approach
This commit is contained in:
parent
6369721876
commit
0f79494fbe
43 changed files with 3078 additions and 645 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue