Repository: Significant-Gravitas/Auto-GPT
File: autogpt_platform/backend/backend/data/model.py (Python)

Code before:
    input_size: int = 0
    output_size: int = 0
    llm_call_count: int = 0
    llm_retry_count: int = 0
    input_token_count: int = 0
    output_token_count: int = 0
    extra_cost: int = 0
    extra_steps: int = 0


class GraphExecutionStats(BaseModel):
    """Execution statistics for a graph execution."""

    model_config = ConfigDict(
        extra="allow",
        arbitrary_types_allowed=True,
    )

    error: Optional[Exception | str] = None
    walltime: float = Field(
        default=0, description="Time between start and end of run (seconds)"
    )
    cputime: float = 0
    nodes_walltime: float = Field(
        default=0, description="Total node execution time (seconds)"
    )
    nodes_cputime: float = 0
    node_count: int = Field(default=0, description="Total number of node executions")
    node_error_count: int = Field(
        default=0, description="Total number of errors generated"
    )
    cost: int = Field(default=0, description="Total execution cost (cents)")


Review comment (suggestion):
```suggestion
    extra_steps: int = 0
    
    def __iadd__(self, other: "NodeExecutionStats") -> "NodeExecutionStats":
        self_values = self.model_dump()
        for key, value in other.model_dump().items():
            if key == "error" and value:
                self.error = value
                continue
            setattr(self, key, self_values[key] + value)
```

Code after:
    reason: str
    result: str | None = None
    status: str
    created_at: datetime
    updated_at: datetime


class NodeExecutionStats(BaseModel):
    """Execution statistics for a node execution."""

    model_config = ConfigDict(
        extra="allow",
        arbitrary_types_allowed=True,
    )

    error: Optional[Exception | str] = None
    walltime: float = 0
    cputime: float = 0
    input_size: int = 0
    output_size: int = 0
    llm_call_count: int = 0
    llm_retry_count: int = 0
    input_token_count: int = 0
    output_token_count: int = 0
    extra_cost: int = 0
    extra_steps: int = 0

    def __iadd__(self, other: "NodeExecutionStats") -> "NodeExecutionStats":
        """Mutate this instance by adding another NodeExecutionStats."""
        if not isinstance(other, NodeExecutionStats):
            return NotImplemented

        stats_dict = other.model_dump()
        current_stats = self.model_dump()

        for key, value in stats_dict.items():
            if key not in current_stats:
                # Field doesn't exist yet, just set it
                setattr(self, key, value)
            elif isinstance(value, dict) and isinstance(current_stats[key], dict):
                current_stats[key].update(value)
                setattr(self, key, current_stats[key])
            elif isinstance(value, (int, float)) and isinstance(
                current_stats[key], (int, float)
            ):
                setattr(self, key, current_stats[key] + value)
            elif isinstance(value, list) and isinstance(current_stats[key], list):
                current_stats[key].extend(value)
                setattr(self, key, current_stats[key])
            else:
                setattr(self, key, value)