Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion argus/agents/agent_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class ActionType(str, Enum):
)

# Import from validation_models
# Validation error models; Validation schemas; Validation utilities;
# Validation error models; Validation schemas; Validation utilities;
# Custom validators; Validation decorators
from .validation_models import (
CodeAnalysisValidationSchema,
Expand Down
2 changes: 1 addition & 1 deletion argus/agents/enhanced_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"""Enhanced Agent Adapters and Migration Helpers."""

import logging
from typing import Any, cast
from typing import Any

from ..llm.config import LLMConfig
from .enhanced_specialized import (
Expand Down
6 changes: 3 additions & 3 deletions argus/agents/legacy_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
import logging
from typing import Any

from ..llm.config import LLMConfig
from ..triage_agent import TriageAgent
from ..analysis_agent import AnalysisAgent
from ..llm.config import LLMConfig
from ..remediation_agent import RemediationAgent
from .enhanced_triage_agent import EnhancedTriageAgent
from ..triage_agent import TriageAgent
from .enhanced_analysis_agent import EnhancedAnalysisAgent
from .enhanced_remediation_agent import EnhancedRemediationAgent
from .enhanced_triage_agent import EnhancedTriageAgent

logger = logging.getLogger(__name__)

Expand Down
1 change: 0 additions & 1 deletion argus/agents/response_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from uuid import uuid4

from pydantic import BaseModel, Field, field_validator
from argus.core.types.agent import AnalysisResponse, RemediationResponse

# ============================================================================
# Common Enums and Base Models
Expand Down
50 changes: 25 additions & 25 deletions argus/config/ingestion_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
pluggable log ingestion architecture.
"""

import json
import logging
from dataclasses import dataclass, field
from enum import Enum
import json
import logging
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
from typing import Any

import yaml

Expand Down Expand Up @@ -75,15 +75,15 @@ class SourceConfig:
retry_delay: float = 1.0
timeout: float = 30.0
circuit_breaker_enabled: bool = True
rate_limit_per_second: Optional[int] = None
config: Dict[str, Any] = field(default_factory=dict)
rate_limit_per_second: int | None = None
config: dict[str, Any] = field(default_factory=dict)


@dataclass
class GCPPubSubConfig(SourceConfig):
"""Configuration for GCP Pub/Sub source."""

credentials_path: Optional[str] = None
credentials_path: str | None = None
max_messages: int = 100
ack_deadline_seconds: int = 60
flow_control_max_messages: int = 1000
Expand All @@ -109,7 +109,7 @@ class GCPLoggingConfig(SourceConfig):
"""Configuration for GCP Logging source."""

log_filter: str = "severity>=ERROR"
credentials_path: Optional[str] = None
credentials_path: str | None = None
poll_interval: int = 30
max_results: int = 1000
project_id: str = ""
Expand Down Expand Up @@ -153,9 +153,9 @@ def __post_init__(self) -> None:
class AWSCloudWatchConfig(SourceConfig):
"""Configuration for AWS CloudWatch source."""

log_stream_name: Optional[str] = None
log_stream_name: str | None = None
region: str = "us-east-1"
credentials_profile: Optional[str] = None
credentials_profile: str | None = None
poll_interval: int = 30
max_events: int = 1000
log_group_name: str = ""
Expand All @@ -176,10 +176,10 @@ def __post_init__(self) -> None:
class KubernetesConfig(SourceConfig):
"""Configuration for Kubernetes source."""

namespace: Optional[str] = None
label_selector: Optional[str] = None
container_name: Optional[str] = None
kubeconfig_path: Optional[str] = None
namespace: str | None = None
label_selector: str | None = None
container_name: str | None = None
kubeconfig_path: str | None = None
poll_interval: int = 30
max_logs: int = 1000
max_pods: int = 100
Expand Down Expand Up @@ -243,11 +243,11 @@ class GlobalConfig:
class IngestionConfig:
"""Complete configuration for the log ingestion system."""

sources: List[SourceConfig] = field(default_factory=list)
sources: list[SourceConfig] = field(default_factory=list)
global_config: GlobalConfig = field(default_factory=GlobalConfig)
schema_version: str = "1.0.0"

def validate(self) -> List[str]:
def validate(self) -> list[str]:
"""Validate the configuration and return any errors."""
errors = []

Expand Down Expand Up @@ -303,14 +303,14 @@ def validate(self) -> List[str]:

return errors

def get_source_by_name(self, name: str) -> Optional[SourceConfig]:
def get_source_by_name(self, name: str) -> SourceConfig | None:
"""Get a source configuration by name."""
for source in self.sources:
if source.name == name:
return source
return None

def get_enabled_sources(self) -> List[SourceConfig]:
def get_enabled_sources(self) -> list[SourceConfig]:
"""Get all enabled sources sorted by priority."""
enabled = [source for source in self.sources if source.enabled]
return sorted(enabled, key=lambda x: x.priority)
Expand All @@ -319,13 +319,13 @@ def get_enabled_sources(self) -> List[SourceConfig]:
class IngestionConfigManager:
"""Manager for ingestion configuration loading and validation."""

def __init__(self, config_path: Optional[Union[str, Path]] = None) -> None:
def __init__(self, config_path: str | Path | None = None) -> None:
"""Initialize the config manager."""
self.config_path = Path(config_path) if config_path else None
self._config: Optional[IngestionConfig] = None
self._config: IngestionConfig | None = None

def load_config(
self, config_path: Optional[Union[str, Path]] = None
self, config_path: str | Path | None = None
) -> IngestionConfig:
"""Load configuration from file."""
if config_path:
Expand All @@ -335,7 +335,7 @@ def load_config(
raise ConfigError(f"Configuration file not found: {self.config_path}")

try:
with open(self.config_path, "r") as f:
with open(self.config_path) as f:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When opening text files, it is highly recommended to specify an explicit encoding (such as encoding="utf-8") to prevent platform-dependent encoding issues, especially when running on systems with different default locales (like Windows).

Suggested change
with open(self.config_path) as f:
with open(self.config_path, encoding="utf-8") as f:

if self.config_path.suffix.lower() in [".yaml", ".yml"]:
data = yaml.safe_load(f)
elif self.config_path.suffix.lower() == ".json":
Expand All @@ -351,7 +351,7 @@ def load_config(
except Exception as e:
raise ConfigError(f"Failed to load configuration: {e}") from e

def _parse_config(self, data: Dict[str, Any]) -> IngestionConfig:
def _parse_config(self, data: dict[str, Any]) -> IngestionConfig:
"""Parse configuration data into IngestionConfig object."""
# Parse global config
global_data = data.get("global_config", {})
Expand Down Expand Up @@ -513,14 +513,14 @@ def _parse_config(self, data: Dict[str, Any]) -> IngestionConfig:
schema_version=data.get("schema_version", "1.0.0"),
)

def validate_config(self) -> List[str]:
def validate_config(self) -> list[str]:
"""Validate the current configuration."""
if not self._config:
return ["No configuration loaded"]
return self._config.validate()

def save_config(
self, config: IngestionConfig, output_path: Union[str, Path]
self, config: IngestionConfig, output_path: str | Path
) -> None:
"""Save configuration to file."""
output_path = Path(output_path)
Expand Down Expand Up @@ -571,6 +571,6 @@ def save_config(
else:
raise ConfigError(f"Unsupported output format: {output_path.suffix}")

def get_config(self) -> Optional[IngestionConfig]:
def get_config(self) -> IngestionConfig | None:
"""Get the current configuration."""
return self._config
2 changes: 1 addition & 1 deletion argus/core/exceptions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
from .agent import AgentError as AgentSpecificError
from .base import (
AgentError,
ConfigurationError,
ArgusAgentError,
ConfigurationError,
LLMError,
MonitoringError,
ProcessingError,
Expand Down
34 changes: 17 additions & 17 deletions argus/core/interfaces/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
for all major components in the system.
"""

import time
from abc import ABC, abstractmethod
from typing import Any, Dict, Generic, List, Optional, TypeVar
import time
from typing import Any, Generic, TypeVar

from ..types import (
ConfigDict,
Expand Down Expand Up @@ -97,7 +97,7 @@ def shutdown(self) -> None:
pass

@abstractmethod
def get_health_status(self) -> Dict[str, Any]:
def get_health_status(self) -> dict[str, Any]:
"""
Get the component's health status.

Expand Down Expand Up @@ -130,7 +130,7 @@ class ConfigurableComponent(BaseComponent):
"""

def __init__(
self, component_id: str, name: str, config: Optional[ConfigDict] = None
self, component_id: str, name: str, config: ConfigDict | None = None
) -> None:
"""
Initialize the configurable component.
Expand Down Expand Up @@ -195,7 +195,7 @@ class StatefulComponent(ConfigurableComponent):
"""

def __init__(
self, component_id: str, name: str, config: Optional[ConfigDict] = None
self, component_id: str, name: str, config: ConfigDict | None = None
) -> None:
"""
Initialize the stateful component.
Expand All @@ -210,7 +210,7 @@ def __init__(
self._state_history = []

@property
def state(self) -> Dict[str, Any]:
def state(self) -> dict[str, Any]:
"""Get the current state."""
return self._state.copy()

Expand All @@ -226,7 +226,7 @@ def set_state(self, key: str, value: Any) -> None:
pass

@abstractmethod
def get_state(self, key: str, default: Optional[Any] = None) -> Any:
def get_state(self, key: str, default: Any | None = None) -> Any:
"""
Get a state value.

Expand All @@ -240,7 +240,7 @@ def get_state(self, key: str, default: Optional[Any] = None) -> Any:
pass

@abstractmethod
def clear_state(self, key: Optional[str] = None) -> None:
def clear_state(self, key: str | None = None) -> None:
"""
Clear state values.

Expand All @@ -249,7 +249,7 @@ def clear_state(self, key: Optional[str] = None) -> None:
"""
pass

def get_state_snapshot(self) -> Dict[str, Any]:
def get_state_snapshot(self) -> dict[str, Any]:
"""
Get a complete state snapshot.

Expand All @@ -274,7 +274,7 @@ class ProcessableComponent(StatefulComponent, Generic[T, R]):
"""

def __init__(
self, component_id: str, name: str, config: Optional[ConfigDict] = None
self, component_id: str, name: str, config: ConfigDict | None = None
) -> None:
"""
Initialize the processable component.
Expand All @@ -286,15 +286,15 @@ def __init__(
"""
super().__init__(component_id, name, config)
self._processing_count = 0
self._last_processed_at: Optional[Timestamp] = None
self._last_processed_at: Timestamp | None = None

@property
def processing_count(self) -> int:
"""Get the number of items processed."""
return self._processing_count

@property
def last_processed_at(self) -> Optional[Timestamp]:
def last_processed_at(self) -> Timestamp | None:
"""Get the timestamp of the last processed item."""
return self._last_processed_at

Expand Down Expand Up @@ -343,7 +343,7 @@ class MonitorableComponent(ProcessableComponent[T, R]):
"""

def __init__(
self, component_id: str, name: str, config: Optional[ConfigDict] = None
self, component_id: str, name: str, config: ConfigDict | None = None
) -> None:
"""
Initialize the monitorable component.
Expand All @@ -358,17 +358,17 @@ def __init__(
self._alerts = []

@property
def metrics(self) -> Dict[str, Any]:
def metrics(self) -> dict[str, Any]:
"""Get current metrics."""
return self._metrics.copy()

@property
def alerts(self) -> List[Dict[str, Any]]:
def alerts(self) -> list[dict[str, Any]]:
"""Get current alerts."""
return self._alerts.copy()

@abstractmethod
def collect_metrics(self) -> Dict[str, Any]:
def collect_metrics(self) -> dict[str, Any]:
"""
Collect component metrics.

Expand Down Expand Up @@ -415,7 +415,7 @@ def clear_alerts(self) -> None:
"""Clear all alerts."""
self._alerts.clear()

def get_health_status(self) -> Dict[str, Any]:
def get_health_status(self) -> dict[str, Any]:
"""
Get comprehensive health status.

Expand Down
Loading
Loading