mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-11-02 07:13:50 +00:00
* docs: rename vault_dir to workspace_dir in documentation and examples * refactor(extract): format long method call across multiple lines * refactor(extract): format system prompt parameters for better readability
84 lines
3.3 KiB
Python
84 lines
3.3 KiB
Python
"""``file_stat`` — peek at file metadata under the workspace without copying it.
|
|
|
|
Cheap inspection alternative to ``file_download``: the agent gets
|
|
size, mtime, mime type, and (for markdown files) the parsed
|
|
frontmatter — enough to decide whether to download / parse / skip
|
|
without paying the copy cost.
|
|
|
|
Returns a uniform envelope:
|
|
|
|
{exists, type, size, mtime, ctime, mime, frontmatter}
|
|
|
|
``exists=False`` short-circuits everything else to ``None``. ``type``
|
|
is ``"file"`` / ``"dir"`` (covers event workspace probes too).
|
|
``frontmatter`` is populated only for ``.md`` files and only when
|
|
parsing succeeds — schema validity is a lint concern.
|
|
|
|
``path`` accepts a file path or directory path relative to the workspace.
|
|
Joined with ``file_store.workspace_path`` and inspected on disk.
|
|
"""
|
|
|
|
import mimetypes
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
import frontmatter
|
|
|
|
from ._path import resolve_path
|
|
from ..base_step import BaseStep
|
|
from ...components import R
|
|
|
|
|
|
@R.register("stat_step")
|
|
class StatStep(BaseStep):
|
|
"""Return metadata for a file or directory under the workspace."""
|
|
|
|
async def execute(self):
|
|
assert self.context is not None
|
|
path: str = self.context.get("path", "") or ""
|
|
assert path, "path is required"
|
|
|
|
workspace_dir = Path(self.file_store.workspace_path or ".").resolve()
|
|
target, err = resolve_path(workspace_dir, path)
|
|
if err or target is None:
|
|
self.context.response.success = False
|
|
self.context.response.answer = f"Error: {err or 'invalid path'}"
|
|
self.context.response.metadata.update({"path": path, "exists": False, "error": err or "invalid path"})
|
|
self.logger.info(f"[{self.name}] path={path} error={err!r}")
|
|
return
|
|
if not target.exists():
|
|
self.context.response.success = False
|
|
self.context.response.answer = f"stat: {path} not found"
|
|
self.context.response.metadata.update({"path": path, "exists": False})
|
|
self.logger.info(f"[{self.name}] path={path} exists=False")
|
|
return
|
|
|
|
st = target.stat()
|
|
payload: dict = {
|
|
"path": path,
|
|
"absolute_path": str(target),
|
|
"exists": True,
|
|
"type": "dir" if target.is_dir() else "file",
|
|
"mtime": datetime.fromtimestamp(st.st_mtime).isoformat(),
|
|
"ctime": datetime.fromtimestamp(st.st_ctime).isoformat(),
|
|
}
|
|
if target.is_file():
|
|
payload["size"] = st.st_size
|
|
payload["mime"] = mimetypes.guess_type(target.name)[0] or "application/octet-stream"
|
|
if target.suffix == ".md":
|
|
try:
|
|
meta = dict(frontmatter.loads(target.read_text(encoding="utf-8")).metadata)
|
|
except Exception:
|
|
meta = {}
|
|
payload["frontmatter"] = meta
|
|
answer = f"stat: {path} (file, {st.st_size} bytes)"
|
|
else:
|
|
answer = f"stat: {path} (dir)"
|
|
|
|
self.context.response.success = True
|
|
self.context.response.answer = answer
|
|
self.context.response.metadata.update(payload)
|
|
self.logger.info(
|
|
f"[{self.name}] path={path} type={payload['type']} "
|
|
f"size={payload.get('size', '-')} mime={payload.get('mime', '-')}",
|
|
)
|