初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,143 @@
|
||||
"""沙箱执行请求 / 响应模型,与 Rust 端 JSON 契约对齐。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
|
||||
|
||||
class ExecRequest(BaseModel):
|
||||
"""``POST /v1/exec`` 请求体。``argv``(命令式)与 ``code``+``language``(代码片段式)二选一。"""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
argv: list[str] | None = Field(None, min_length=1)
|
||||
code: str | None = None
|
||||
language: str | None = None # code 模式语言,默认 python
|
||||
stdin: str | None = None
|
||||
timeout_ms: int | None = None
|
||||
workdir: str | None = None
|
||||
env: dict[str, str] = Field(default_factory=dict)
|
||||
max_output_bytes: int | None = None
|
||||
trace_id: str | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _enforce_argv_code_mutex(self) -> ExecRequest:
|
||||
has_argv = self.argv is not None
|
||||
has_code = self.code is not None
|
||||
if has_argv == has_code:
|
||||
raise ValueError("必须且只能指定 argv 或 code 之一")
|
||||
if has_code and self.language is None:
|
||||
self.language = "python"
|
||||
return self
|
||||
|
||||
|
||||
class ExecResponse(BaseModel):
|
||||
"""``POST /v1/exec`` 响应体。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
ok: bool
|
||||
exit_code: int | None = None
|
||||
stdout: str = ""
|
||||
stderr: str = ""
|
||||
duration_ms: int = 0
|
||||
timeout: bool = False
|
||||
cancelled: bool = False
|
||||
truncated: bool = False
|
||||
trace_id: str = ""
|
||||
isolation_mode: str = "process" # 实际生效的隔离模式(process/container)
|
||||
|
||||
|
||||
class CancelResponse(BaseModel):
|
||||
"""``POST /v1/cancel`` 响应体。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
cancelled: bool
|
||||
trace_id: str
|
||||
|
||||
|
||||
# ---- 文件 IO(不经 shell,二进制安全;与 Rust fileio.rs 契约对齐) ----
|
||||
|
||||
|
||||
class FileReadRequest(BaseModel):
|
||||
"""``POST /v1/file/read`` 请求。``path`` 为 base 内相对路径。"""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
path: str
|
||||
offset: int | None = None
|
||||
limit: int | None = None
|
||||
|
||||
|
||||
class FileReadResponse(BaseModel):
|
||||
"""``POST /v1/file/read`` 响应。``content_b64`` 为 base64url-no-pad(二进制安全)。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
content_b64: str
|
||||
size: int
|
||||
offset: int
|
||||
returned: int
|
||||
truncated: bool
|
||||
|
||||
|
||||
class FileWriteRequest(BaseModel):
|
||||
"""``POST /v1/file/write`` 请求。``content_b64`` 为 base64url-no-pad。"""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
path: str
|
||||
content_b64: str
|
||||
|
||||
|
||||
class FileWriteResponse(BaseModel):
|
||||
"""``POST /v1/file/write`` 响应。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
bytes_written: int
|
||||
|
||||
|
||||
class FileListRequest(BaseModel):
|
||||
"""``POST /v1/file/list`` 请求。``path`` 默认 base 根(``.``)。"""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
path: str = "."
|
||||
|
||||
|
||||
class DirEntry(BaseModel):
|
||||
"""目录条目。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
name: str
|
||||
kind: str # "file" | "dir" | "other"
|
||||
size: int
|
||||
|
||||
|
||||
class FileListResponse(BaseModel):
|
||||
"""``POST /v1/file/list`` 响应(条目按名字排序)。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
entries: list[DirEntry]
|
||||
|
||||
|
||||
class FileStatRequest(BaseModel):
|
||||
"""``POST /v1/file/stat`` 请求。"""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
path: str
|
||||
|
||||
|
||||
class FileStatResponse(BaseModel):
|
||||
"""``POST /v1/file/stat`` 响应。"""
|
||||
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
|
||||
kind: str
|
||||
size: int
|
||||
modified_unix: int
|
||||
Reference in new issue
Block a user