Spaces:
Sleeping
Sleeping
File size: 3,013 Bytes
f909af8 6f6baad f909af8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | """
Data models for the ForensicShell OpenEnv environment.
ForensicShell simulates a pre-seeded "breached" Linux box. The agent investigates
via structured read-only actions (list_dir, read_file, grep, stat) and ultimately
submits a ForensicReport. A deterministic grader scores the report against hidden
ground truth per task (easy/medium/hard).
"""
from typing import List, Literal, Optional
from openenv.core.env_server.types import Action, Observation
from pydantic import BaseModel, Field
class TimelineEvent(BaseModel):
"""One step in the attacker's kill chain (used in hard task)."""
phase: Literal["login", "recon", "privesc", "persistence", "exfil"]
detail: str = Field(default="", description="Short description of the event")
class ForensicReport(BaseModel):
"""The agent's final investigation report. Submitted via action_type='submit_report'."""
compromised_user: Optional[str] = Field(
default=None, description="Username of the compromised account"
)
initial_ip: Optional[str] = Field(
default=None, description="Source IP of the initial login"
)
modified_files: List[str] = Field(
default_factory=list,
description="Absolute paths of files modified after compromise",
)
backdoor_sha256: Optional[str] = Field(
default=None,
description="SHA256 of the attacker-dropped backdoor binary (lowercase hex)",
)
timeline: List[TimelineEvent] = Field(
default_factory=list,
description="Ordered attacker kill chain (login→recon→privesc→persistence→exfil)",
)
class ForensicShellAction(Action):
"""Agent action. Use action_type to pick the verb; set only the fields that verb needs."""
action_type: Literal[
"list_dir", "read_file", "grep", "stat", "find", "submit_report"
] = Field(..., description="Which verb to execute")
path: Optional[str] = Field(
default=None, description="Target path for list_dir / read_file / grep / stat"
)
pattern: Optional[str] = Field(
default=None, description="Substring pattern for grep"
)
max_bytes: int = Field(
default=2048, description="Max bytes to return from read_file (truncated)"
)
report: Optional[ForensicReport] = Field(
default=None, description="Investigation report (only for action_type='submit_report')"
)
class ForensicShellObservation(Observation):
"""Result of the agent's last action."""
output: str = Field(default="", description="Human-readable result of the action")
task_id: str = Field(default="", description="Current task identifier")
task_description: str = Field(
default="", description="What the agent is being asked to investigate"
)
steps_remaining: int = Field(
default=0, description="How many more actions allowed this episode"
)
action_error: Optional[str] = Field(
default=None, description="Error message if the action failed; None otherwise"
)
|