vulnops / models.py
Adhitya-Vardhan
Initial commit: VulnOps OpenEnv benchmark
d63a1ba
"""Typed models for the vulnerability triage environment."""
from __future__ import annotations
from typing import Dict, List, Literal, Optional
from openenv.core.env_server.types import Action, Observation, State
from pydantic import BaseModel, Field
ActionType = Literal[
"read_report",
"inspect_evidence",
"search_nvd_database",
"fetch_commit_diff",
"message_maintainer",
"set_validity",
"set_affected_package",
"set_affected_versions",
"set_severity",
"set_exploitability",
"set_next_action",
"set_missing_information",
"request_more_info",
"submit_triage",
]
ValidityLabel = Literal["unknown", "valid", "invalid", "needs_more_info"]
SeverityLabel = Literal["unknown", "low", "medium", "high", "critical"]
ExploitabilityLabel = Literal["unknown", "low", "medium", "high"]
NextActionLabel = Literal[
"unknown",
"request_info",
"close",
"escalate",
"patch",
"publish_advisory",
]
class EvidenceItem(BaseModel):
"""Evidence the agent can reveal during triage."""
evidence_id: str = Field(..., description="Unique identifier for this evidence item")
title: str = Field(..., description="Short evidence title")
summary: str = Field(..., description="Evidence content shown to the agent")
kind: str = Field(..., description="Evidence type such as advisory or patch note")
class TriageDraft(BaseModel):
"""Agent-managed triage state."""
validity: ValidityLabel = "unknown"
affected_package: str = ""
affected_versions: str = ""
severity: SeverityLabel = "unknown"
exploitability: ExploitabilityLabel = "unknown"
next_action: NextActionLabel = "unknown"
missing_information: List[str] = Field(default_factory=list)
class VulnTriageAction(Action):
"""Structured action space for vulnerability triage."""
action_type: ActionType = Field(..., description="Which environment action to execute")
evidence_id: Optional[str] = Field(
default=None,
description="Evidence identifier used by inspect_evidence",
)
value: Optional[str] = Field(
default=None,
description="Generic value used for label-setting actions",
)
rationale: str = Field(
default="",
description="Optional short rationale for debugging and trajectory inspection",
)
class VulnTriageObservation(Observation):
"""Observation returned after every environment transition."""
task_id: str = Field(..., description="Current task identifier")
difficulty: str = Field(..., description="Difficulty band for the current task")
objective: str = Field(..., description="Concrete task objective")
report_summary: str = Field(..., description="Incoming vulnerability report summary")
visible_evidence: List[EvidenceItem] = Field(
default_factory=list,
description="Evidence items currently visible to the agent",
)
available_evidence: List[str] = Field(
default_factory=list,
description="Evidence identifiers available to inspect next",
)
draft: TriageDraft = Field(
default_factory=TriageDraft,
description="Current structured triage draft",
)
action_history: List[str] = Field(
default_factory=list,
description="Compact history of recent agent actions",
)
steps_remaining: int = Field(..., ge=0, description="Remaining steps in the episode")
score_breakdown: Dict[str, float] = Field(
default_factory=dict,
description="Current normalized grader breakdown",
)
final_score: Optional[float] = Field(
default=None,
description="Final submission score when the episode is done",
)
available_actions: List[str] = Field(
default_factory=lambda: [
"read_report",
"inspect_evidence",
"search_nvd_database",
"fetch_commit_diff",
"message_maintainer",
"set_validity",
"set_affected_package",
"set_affected_versions",
"set_severity",
"set_exploitability",
"set_next_action",
"set_missing_information",
"request_more_info",
"submit_triage",
],
description="Action names the agent can choose from",
)
class VulnTriageState(State):
"""Serializable environment state for inspection and debugging."""
task_id: str = Field(..., description="Current task identifier")
difficulty: str = Field(..., description="Difficulty band")
draft: TriageDraft = Field(default_factory=TriageDraft)
revealed_evidence_ids: List[str] = Field(default_factory=list)
action_history: List[str] = Field(default_factory=list)
steps_remaining: int = Field(..., ge=0)
submitted: bool = Field(default=False)
final_score: Optional[float] = Field(default=None)
score_breakdown: Dict[str, float] = Field(default_factory=dict)