diff --git a/gptscript/fileinfo.py b/gptscript/fileinfo.py new file mode 100644 index 0000000..5f7cd9f --- /dev/null +++ b/gptscript/fileinfo.py @@ -0,0 +1,10 @@ +from datetime import datetime + +from pydantic import BaseModel + + +class FileInfo(BaseModel): + workspaceID: str + name: str + size: int + modTime: datetime diff --git a/gptscript/gptscript.py b/gptscript/gptscript.py index 86c3a5d..39b44ef 100644 --- a/gptscript/gptscript.py +++ b/gptscript/gptscript.py @@ -9,6 +9,7 @@ from gptscript.confirm import AuthResponse from gptscript.credentials import Credential, to_credential from gptscript.datasets import DatasetMeta, Dataset, DatasetElementMeta, DatasetElement +from gptscript.fileinfo import FileInfo from gptscript.frame import RunFrame, CallFrame, PromptFrame, Program from gptscript.opts import GlobalOptions from gptscript.prompt import PromptResponse @@ -318,9 +319,9 @@ async def create_workspace(self, provider_type: str, from_workspaces: list[str] } ) - async def delete_workspace(self, workspace_id: str = ""): + async def delete_workspace(self, workspace_id: str): if workspace_id == "": - workspace_id = os.environ["GPTSCRIPT_WORKSPACE_ID"] + raise ValueError("workspace_id cannot be empty") await self._run_basic_command( "workspaces/delete", @@ -402,6 +403,20 @@ async def read_file_in_workspace(self, file_path: str, workspace_id: str = "") - } )) + async def stat_file_in_workspace(self, file_path: str, workspace_id: str = "") -> FileInfo: + if workspace_id == "": + workspace_id = os.environ["GPTSCRIPT_WORKSPACE_ID"] + + return FileInfo.model_validate_json(await self._run_basic_command( + "workspaces/stat-file", + { + "id": workspace_id, + "filePath": file_path, + "workspaceTool": self.opts.WorkspaceTool, + "env": self.opts.Env, + } + )) + def _get_command(): if os.getenv("GPTSCRIPT_BIN") is not None: diff --git a/tests/test_gptscript.py b/tests/test_gptscript.py index 9cc0f57..95236ae 100644 --- a/tests/test_gptscript.py +++ b/tests/test_gptscript.py @@ -40,7 +40,7 @@ def gptscript(): # Simple tool for testing -@pytest.fixture +@pytest.fixture(scope="function") def simple_tool(): return ToolDef( instructions="What is the capital of the united states?" @@ -48,7 +48,7 @@ def simple_tool(): # Complex tool for testing -@pytest.fixture +@pytest.fixture(scope="function") def complex_tool(): return ToolDef( jsonResponse=True, @@ -68,7 +68,7 @@ def complex_tool(): # Fixture for a list of tools -@pytest.fixture +@pytest.fixture(scope="function") def tool_list(): shebang = "#!/bin/bash" if platform.system().lower() == "windows": @@ -810,6 +810,17 @@ async def test_create_read_and_delete_file_in_workspace(gptscript): await gptscript.write_file_in_workspace("test.txt", b"test", workspace_id) contents = await gptscript.read_file_in_workspace("test.txt", workspace_id) assert contents == b"test" + + file_info = await gptscript.stat_file_in_workspace("test.txt", workspace_id) + assert file_info.name == "test.txt" + assert file_info.size == 4 + assert file_info.modTime.hour == datetime.now( + tz=file_info.modTime.tzinfo, + ).hour and file_info.modTime < datetime.now( + tz=file_info.modTime.tzinfo, + ) + + assert file_info.workspaceID == workspace_id await gptscript.delete_file_in_workspace("test.txt", workspace_id) await gptscript.delete_workspace(workspace_id) @@ -857,6 +868,16 @@ async def test_create_read_and_delete_file_in_workspaces3(gptscript): await gptscript.write_file_in_workspace("test.txt", b"test", workspace_id) contents = await gptscript.read_file_in_workspace("test.txt", workspace_id) assert contents == b"test" + + file_info = await gptscript.stat_file_in_workspace("test.txt", workspace_id) + assert file_info.name == "test.txt" + assert file_info.size == 4 + assert file_info.modTime.hour == datetime.now( + tz=file_info.modTime.tzinfo, + ).hour and file_info.modTime < datetime.now( + tz=file_info.modTime.tzinfo, + ) + await gptscript.delete_file_in_workspace("test.txt", workspace_id) await gptscript.delete_workspace(workspace_id)