Duibonduil's picture
Upload 9 files
3e8c06e verified
import uuid
from datetime import datetime
from enum import Enum, auto
from typing import Dict, Any, Optional, ClassVar
from pydantic import Field, field_validator, model_validator, BaseModel
from aworld.output.base import Output
class ArtifactType(Enum):
"""Defines supported artifact types"""
TEXT = "TEXT"
CODE = "CODE"
MARKDOWN = "MARKDOWN"
HTML = "HTML"
SVG = "SVG"
IMAGE = "IMAGE"
JSON = "JSON"
CSV = "CSV"
TABLE = "TABLE"
CHART = "CHART"
DIAGRAM = "DIAGRAM"
MCP_CALL = "MCP_CALL"
TOOL_CALL = "TOOL_CALL"
LLM_OUTPUT = "LLM_OUTPUT"
WEB_PAGES = "WEB_PAGES"
DIR = "DIR"
CUSTOM = "CUSTOM"
class ArtifactStatus(Enum):
"""Artifact status"""
DRAFT = auto() # Draft status
COMPLETE = auto() # Completed status
EDITED = auto() # Edited status
ARCHIVED = auto() # Archived status
class ArtifactAttachment(BaseModel):
filename: str = Field(..., description="Filename")
content: str = Field(..., description="Content", exclude=True)
mime_type: str = Field(..., description="MIME type")
class Artifact(Output):
"""
Represents a specific content generation result (artifact)
Artifacts are the basic units of Artifacts technology, representing a structured content unit
Can be code, markdown, charts, and various other formats
"""
artifact_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique identifier for the artifact")
artifact_type: ArtifactType = Field(..., description="Type of the artifact")
content: Any = Field(..., description="Content of the artifact")
metadata: Dict[str, Any] = Field(default_factory=dict, description="Metadata associated with the artifact")
created_at: str = Field(default_factory=lambda: datetime.now().isoformat(), description="Creation timestamp")
updated_at: str = Field(default_factory=lambda: datetime.now().isoformat(), description="Last updated timestamp")
status: ArtifactStatus = Field(default=ArtifactStatus.COMPLETE, description="Current status of the artifact")
current_version: str = Field(default="", description="Current version of the artifact")
version_history: list = Field(default_factory=list, description="History of versions for the artifact")
create_file: bool = Field(default=False, description="Flag to indicate if a file should be created")
attachments: Optional[list[ArtifactAttachment]] = Field(default_factory=list, description="Attachments associated with the artifact")
def _record_version(self, description: str) -> None:
"""Record current state as a new version"""
version = {
"timestamp": datetime.now().isoformat(),
"description": description,
"status": self.status
}
self.version_history.append(version)
self.updated_at = version["timestamp"]
def update_content(self, content: Any, description: str = "Content update") -> None:
"""
Update artifact content and record version
Args:
content: New content
description: Update description
"""
self.content = content
self.status = ArtifactStatus.EDITED
self._record_version(description)
def update_metadata(self, metadata: Dict[str, Any]) -> None:
"""
Update artifact metadata
Args:
metadata: New metadata (will be merged with existing metadata)
"""
self.metadata.update(metadata)
self.updated_at = datetime.now().isoformat()
def mark_complete(self) -> None:
"""Mark the artifact as complete"""
self.status = ArtifactStatus.COMPLETE
self.updated_at = datetime.now().isoformat()
self._record_version("Marked as complete")
def archive(self) -> None:
"""Archive the artifact"""
self.status = ArtifactStatus.ARCHIVED
self._record_version("Artifact archived")
def get_version(self, index: int) -> Optional[Dict[str, Any]]:
"""Get version at the specified index"""
if 0 <= index < len(self.version_history):
return self.version_history[index]
return None
def revert_to_version(self, index: int) -> bool:
"""Revert to a specific version"""
version = self.get_version(index)
if version:
self.content = version["content"]
self.status = version["status"]
self._record_version(f"Reverted to version {index}")
return True
return False
def to_dict(self) -> Dict[str, Any]:
"""Convert artifact to dictionary"""
return {
"artifact_id": self.artifact_id,
"artifact_type": self.artifact_type.value,
"content": self.content,
"metadata": self.metadata,
"created_at": self.created_at,
"updated_at": self.updated_at,
"status": self.status.name,
"version_count": len(self.version_history)
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "Artifact":
"""Create an artifact instance from a dictionary"""
artifact_type = ArtifactType(data["artifact_type"])
artifact = cls(
artifact_type=artifact_type,
content=data["content"],
metadata=data["metadata"],
artifact_id=data.get("artifact_id", str(uuid.uuid4()))
)
artifact.created_at = data["created_at"]
artifact.updated_at = data["updated_at"]
artifact.status = ArtifactStatus[data["status"]]
# If version history exists, restore it as well
if "version_history" in data:
artifact.version_history = data["version_history"]
return artifact