项目文件夹

文件
Gelei Deng e238d701f2 feat: 🎸 version 1.0 agentic workflow (#325)
* 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>
2025-12-13 01:57:24 +08:00

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)