greydgl--pentestgpt
e238d701f2
* feat: 🎸 version 1.0 agentic workflow
Major rewrite of PentestGPT to use an agentic pipeline architecture:
Core Changes: - New event-driven architecture with EventBus for
TUI-agent decoupling - Implemented AgentController with 5-state
lifecycle (IDLE->RUNNING->PAUSED->COMPLETED->ERROR) - Added AgentBackend
interface with ClaudeCodeBackend implementation - Session management
with file-based persistence for resumable pentests - Langfuse
integration for observability and tracing Interface: - New Textual-based
TUI with real-time activity feed - Keyboard shortcuts: F1 help, Ctrl+P
pause, Ctrl+Q quit - Enhanced CLI with --target, --instruction,
--non-interactive, --debug flags Project Structure: - Moved legacy
multi-LLM version (v0.15) to legacy/ directory - New pentestgpt/core/
for agent, controller, events, session modules - New
pentestgpt/interface/ for TUI and CLI components - New
pentestgpt/benchmark/ for xbow benchmark integration - Comprehensive
test suite in tests/ with unit and integration tests DevOps: - Docker
support with Ubuntu 24.04 container - GitHub Actions CI/CD pipeline -
Makefile with dev commands (test, lint, format, typecheck) - Added
xbow-validation-benchmarks as submodule
* style: format code with Black
This commit fixes the style issues introduced in abe3be0 according to the output
from Black.
Details: https://github.com/GreyDGL/PentestGPT/pull/325
* fix: 🐛 fix test pipeline
* feat: 🎸 update format
* feat: 🎸 update
---------
Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
103 行
3.3 KiB
Python
103 行
3.3 KiB
Python
"""Configuration management for PentestGPT using Pydantic."""
|
|
|
|
from pathlib import Path
|
|
from typing import Any, Literal
|
|
|
|
from pydantic import Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class PentestGPTConfig(BaseSettings):
|
|
"""Main configuration for PentestGPT."""
|
|
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
case_sensitive=False,
|
|
extra="ignore",
|
|
)
|
|
|
|
# LLM Configuration
|
|
# Note: API key is optional - Claude Code manages its own configuration
|
|
llm_model: str = Field(
|
|
default="claude-sonnet-4-5-20250929", description="Claude model to use for the agent"
|
|
)
|
|
|
|
llm_api_key: str | None = Field(
|
|
default=None, description="Optional API key (Claude Code manages its own config)"
|
|
)
|
|
|
|
llm_api_base: str | None = Field(default=None, description="Optional custom API base URL")
|
|
|
|
# Agent Configuration
|
|
max_iterations: int = Field(default=300, description="Maximum iterations for the agent")
|
|
|
|
working_directory: Path = Field(
|
|
default_factory=lambda: Path.cwd() / "workspace",
|
|
description="Working directory for agent operations",
|
|
)
|
|
|
|
# Target Configuration
|
|
target: str = Field(
|
|
..., # Required
|
|
description="Target for penetration testing (URL, IP, domain, or path)",
|
|
)
|
|
|
|
custom_instruction: str | None = Field(
|
|
default=None, description="Optional custom instructions for the agent"
|
|
)
|
|
|
|
# Interface Configuration
|
|
interface_mode: Literal["tui", "cli"] = Field(
|
|
default="tui", description="Interface mode: TUI (interactive) or CLI (headless)"
|
|
)
|
|
|
|
verbose: bool = Field(default=True, description="Enable verbose output")
|
|
|
|
# Permission Mode
|
|
permission_mode: Literal["ask", "bypassPermissions"] = Field(
|
|
default="bypassPermissions", description="Permission mode for Claude Code SDK"
|
|
)
|
|
|
|
def __init__(self, **data: Any) -> None:
|
|
"""Initialize configuration."""
|
|
super().__init__(**data)
|
|
|
|
# Create working directory if it doesn't exist
|
|
# Ignore permission errors if directory already exists
|
|
try:
|
|
self.working_directory.mkdir(parents=True, exist_ok=True)
|
|
except (PermissionError, OSError):
|
|
# Directory already exists or we don't have permission to create it
|
|
# This is fine if the directory is already available
|
|
if not self.working_directory.exists():
|
|
raise
|
|
|
|
@property
|
|
def system_prompt_path(self) -> Path:
|
|
"""Get path to system prompt file."""
|
|
return Path(__file__).parent.parent / "prompts" / "pentesting.py"
|
|
|
|
@classmethod
|
|
def from_env(cls, **overrides: object) -> "PentestGPTConfig":
|
|
"""Create config from environment variables with optional overrides."""
|
|
return cls(**overrides)
|
|
|
|
|
|
def load_config(**overrides: object) -> PentestGPTConfig:
|
|
"""
|
|
Load configuration from environment with optional overrides.
|
|
|
|
Args:
|
|
**overrides: Keyword arguments to override config values
|
|
|
|
Returns:
|
|
PentestGPTConfig instance
|
|
|
|
Example:
|
|
>>> config = load_config(target="example.com", verbose=True)
|
|
"""
|
|
# Create config with overrides
|
|
# Note: API key is optional - Claude Code manages its own configuration
|
|
return PentestGPTConfig.from_env(**overrides)
|